PageRenderTime 48ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/ExtLibs/wxWidgets/src/osx/carbon/fontdlgosx.mm

https://bitbucket.org/lennonchan/cafu
Objective C++ | 559 lines | 354 code | 115 blank | 90 comment | 23 complexity | c71657c5cc7b057c2c6de0c47ed3d153 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: src/osx/carbon/fontdlgosx.mm
  3. // Purpose: wxFontDialog class.
  4. // Author: Ryan Norton
  5. // Modified by:
  6. // Created: 2004-10-03
  7. // RCS-ID: $Id$
  8. // Copyright: (c) Ryan Norton
  9. // Licence: wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11. #include "wx/wxprec.h"
  12. // ===========================================================================
  13. // declarations
  14. // ===========================================================================
  15. // ---------------------------------------------------------------------------
  16. // headers
  17. // ---------------------------------------------------------------------------
  18. #include "wx/fontdlg.h"
  19. #ifndef WX_PRECOMP
  20. #include "wx/intl.h"
  21. #include "wx/log.h"
  22. #include "wx/cmndata.h"
  23. #endif
  24. #include "wx/fontutil.h"
  25. // ============================================================================
  26. // implementation
  27. // ============================================================================
  28. #include "wx/cocoa/autorelease.h"
  29. #include "wx/cocoa/string.h"
  30. #if wxOSX_USE_EXPERIMENTAL_FONTDIALOG
  31. #import <Foundation/Foundation.h>
  32. #import <AppKit/AppKit.h>
  33. #include "wx/osx/private.h"
  34. @interface wxMacFontPanelAccView : NSView
  35. {
  36. BOOL m_okPressed ;
  37. BOOL m_shouldClose ;
  38. NSButton* m_cancelButton ;
  39. NSButton* m_okButton ;
  40. }
  41. - (IBAction)cancelPressed:(id)sender;
  42. - (IBAction)okPressed:(id)sender;
  43. - (void)resetFlags;
  44. - (BOOL)closedWithOk;
  45. - (BOOL)shouldCloseCarbon;
  46. - (NSButton*)okButton;
  47. @end
  48. @implementation wxMacFontPanelAccView : NSView
  49. - (id)initWithFrame:(NSRect)rectBox
  50. {
  51. [super initWithFrame:rectBox];
  52. wxCFStringRef cfOkString( wxT("OK"), wxLocale::GetSystemEncoding() );
  53. wxCFStringRef cfCancelString( wxT("Cancel"), wxLocale::GetSystemEncoding() );
  54. NSRect rectCancel = NSMakeRect( (CGFloat) 10.0 , (CGFloat)10.0 , (CGFloat)82 , (CGFloat)24 );
  55. NSRect rectOK = NSMakeRect( (CGFloat)100.0 , (CGFloat)10.0 , (CGFloat)82 , (CGFloat)24 );
  56. NSButton* cancelButton = [[NSButton alloc] initWithFrame:rectCancel];
  57. [cancelButton setTitle:(NSString*)wxCFRetain((CFStringRef)cfCancelString)];
  58. [cancelButton setBezelStyle:NSRoundedBezelStyle];
  59. [cancelButton setButtonType:NSMomentaryPushInButton];
  60. [cancelButton setAction:@selector(cancelPressed:)];
  61. [cancelButton setTarget:self];
  62. m_cancelButton = cancelButton ;
  63. NSButton* okButton = [[NSButton alloc] initWithFrame:rectOK];
  64. [okButton setTitle:(NSString*)wxCFRetain((CFStringRef)cfOkString)];
  65. [okButton setBezelStyle:NSRoundedBezelStyle];
  66. [okButton setButtonType:NSMomentaryPushInButton];
  67. [okButton setAction:@selector(okPressed:)];
  68. [okButton setTarget:self];
  69. // doesn't help either, the button is not highlighted after a color dialog has been used
  70. // [okButton setKeyEquivalent:@"\r"];
  71. m_okButton = okButton ;
  72. [self addSubview:cancelButton];
  73. [self addSubview:okButton];
  74. [self resetFlags];
  75. return self;
  76. }
  77. - (void)resetFlags
  78. {
  79. m_okPressed = NO ;
  80. m_shouldClose = NO ;
  81. }
  82. - (IBAction)cancelPressed:(id)sender
  83. {
  84. wxUnusedVar(sender);
  85. m_shouldClose = YES ;
  86. [NSApp stopModal];
  87. }
  88. - (IBAction)okPressed:(id)sender
  89. {
  90. wxUnusedVar(sender);
  91. m_okPressed = YES ;
  92. m_shouldClose = YES ;
  93. [NSApp stopModal];
  94. }
  95. -(BOOL)closedWithOk
  96. {
  97. return m_okPressed ;
  98. }
  99. -(BOOL)shouldCloseCarbon
  100. {
  101. return m_shouldClose ;
  102. }
  103. -(NSButton*)okButton
  104. {
  105. return m_okButton ;
  106. }
  107. @end
  108. extern "C" int RunMixedFontDialog(wxFontDialog* dialog) ;
  109. int RunMixedFontDialog(wxFontDialog* dialog)
  110. {
  111. #if wxOSX_USE_COCOA
  112. wxFontData& fontdata= ((wxFontDialog*)dialog)->GetFontData() ;
  113. #else
  114. wxUnusedVar(dialog);
  115. #endif
  116. int retval = wxID_CANCEL ;
  117. wxAutoNSAutoreleasePool pool;
  118. // setting up the ok/cancel buttons
  119. NSFontPanel* fontPanel = [NSFontPanel sharedFontPanel] ;
  120. // adjust modality for carbon environment
  121. #if wxOSX_USE_CARBON
  122. WindowRef carbonWindowRef = (WindowRef)[fontPanel windowRef] ;
  123. SetWindowModality(carbonWindowRef, kWindowModalityAppModal , 0) ;
  124. SetWindowGroup(carbonWindowRef , GetWindowGroupOfClass(kMovableModalWindowClass));
  125. #endif
  126. [fontPanel setFloatingPanel:NO] ;
  127. [[fontPanel standardWindowButton:NSWindowCloseButton] setEnabled:NO] ;
  128. wxMacFontPanelAccView* accessoryView = (wxMacFontPanelAccView*) [fontPanel accessoryView] ;
  129. if ( accessoryView == nil)
  130. {
  131. NSRect rectBox = NSMakeRect( 0 , 0 , 192 , 40 );
  132. accessoryView = [[wxMacFontPanelAccView alloc] initWithFrame:rectBox];
  133. [fontPanel setAccessoryView:accessoryView];
  134. [accessoryView release];
  135. [fontPanel setDefaultButtonCell:[[accessoryView okButton] cell]] ;
  136. }
  137. [accessoryView resetFlags];
  138. #if wxOSX_USE_COCOA
  139. wxFont font = *wxNORMAL_FONT ;
  140. if ( fontdata.m_initialFont.IsOk() )
  141. {
  142. font = fontdata.m_initialFont ;
  143. }
  144. [[NSFontPanel sharedFontPanel] setPanelFont: font.OSXGetNSFont() isMultiple:NO];
  145. if(fontdata.m_fontColour.IsOk())
  146. [[NSColorPanel sharedColorPanel] setColor:
  147. [NSColor colorWithCalibratedRed:fontdata.m_fontColour.Red() / 255.0
  148. green:fontdata.m_fontColour.Green() / 255.0
  149. blue:fontdata.m_fontColour.Blue() / 255.0
  150. alpha:1.0]
  151. ];
  152. else
  153. [[NSColorPanel sharedColorPanel] setColor:[NSColor blackColor]];
  154. #endif
  155. [NSApp runModalForWindow:fontPanel];
  156. // if we don't reenable it, FPShowHideFontPanel does not work
  157. [[fontPanel standardWindowButton:NSWindowCloseButton] setEnabled:YES] ;
  158. #if wxOSX_USE_CARBON
  159. if( FPIsFontPanelVisible())
  160. FPShowHideFontPanel() ;
  161. #else
  162. [fontPanel close];
  163. #endif
  164. if ( [accessoryView closedWithOk])
  165. {
  166. #if wxOSX_USE_COCOA
  167. NSFont* theFont = [fontPanel panelConvertFont:[NSFont userFontOfSize:0]];
  168. fontdata.m_chosenFont = wxFont( theFont );
  169. //Get the shared color panel along with the chosen color and set the chosen color
  170. NSColor* theColor = [[[NSColorPanel sharedColorPanel] color] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
  171. fontdata.m_fontColour.Set((unsigned char) ([theColor redComponent] * 255.0),
  172. (unsigned char) ([theColor greenComponent] * 255.0),
  173. (unsigned char) ([theColor blueComponent] * 255.0));
  174. #endif
  175. retval = wxID_OK ;
  176. }
  177. [fontPanel setAccessoryView:nil];
  178. return retval ;
  179. }
  180. #else
  181. #if USE_NATIVE_FONT_DIALOG_FOR_MACOSX
  182. IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
  183. // Cocoa headers
  184. #import <AppKit/NSFont.h>
  185. #import <AppKit/NSFontManager.h>
  186. #import <AppKit/NSFontPanel.h>
  187. #import <AppKit/NSColor.h>
  188. #import <AppKit/NSColorPanel.h>
  189. // ---------------------------------------------------------------------------
  190. // wxWCDelegate - Window Closed delegate
  191. // ---------------------------------------------------------------------------
  192. @interface wxWCDelegate : NSObject
  193. {
  194. bool m_bIsClosed;
  195. }
  196. // Delegate methods
  197. - (id)init;
  198. - (BOOL)windowShouldClose:(id)sender;
  199. - (BOOL)isClosed;
  200. @end // interface wxNSFontPanelDelegate : NSObject
  201. @implementation wxWCDelegate : NSObject
  202. - (id)init
  203. {
  204. [super init];
  205. m_bIsClosed = false;
  206. return self;
  207. }
  208. - (BOOL)windowShouldClose:(id)sender
  209. {
  210. m_bIsClosed = true;
  211. [NSApp abortModal];
  212. [NSApp stopModal];
  213. return YES;
  214. }
  215. - (BOOL)isClosed
  216. {
  217. return m_bIsClosed;
  218. }
  219. @end // wxNSFontPanelDelegate
  220. // ---------------------------------------------------------------------------
  221. // wxWCODelegate - Window Closed or Open delegate
  222. // ---------------------------------------------------------------------------
  223. @interface wxWCODelegate : NSObject
  224. {
  225. bool m_bIsClosed;
  226. bool m_bIsOpen;
  227. }
  228. // Delegate methods
  229. - (id)init;
  230. - (BOOL)windowShouldClose:(id)sender;
  231. - (void)windowDidUpdate:(NSNotification *)aNotification;
  232. - (BOOL)isClosed;
  233. - (BOOL)isOpen;
  234. @end // interface wxNSFontPanelDelegate : NSObject
  235. @implementation wxWCODelegate : NSObject
  236. - (id)init
  237. {
  238. [super init];
  239. m_bIsClosed = false;
  240. m_bIsOpen = false;
  241. return self;
  242. }
  243. - (BOOL)windowShouldClose:(id)sender
  244. {
  245. m_bIsClosed = true;
  246. m_bIsOpen = false;
  247. [NSApp abortModal];
  248. [NSApp stopModal];
  249. return YES;
  250. }
  251. - (void)windowDidUpdate:(NSNotification *)aNotification
  252. {
  253. if (m_bIsOpen == NO)
  254. {
  255. m_bIsClosed = false;
  256. m_bIsOpen = true;
  257. [NSApp abortModal];
  258. [NSApp stopModal];
  259. }
  260. }
  261. - (BOOL)isClosed
  262. {
  263. return m_bIsClosed;
  264. }
  265. - (BOOL)isOpen
  266. {
  267. return m_bIsOpen;
  268. }
  269. @end // wxNSFontPanelDelegate
  270. // ---------------------------------------------------------------------------
  271. // wxFontDialog
  272. // ---------------------------------------------------------------------------
  273. wxFontDialog::wxFontDialog()
  274. {
  275. }
  276. wxFontDialog::wxFontDialog(wxWindow *parent, const wxFontData& data)
  277. {
  278. Create(parent, data);
  279. }
  280. wxFontDialog::~wxFontDialog()
  281. {
  282. }
  283. bool wxFontDialog::Create(wxWindow *parent, const wxFontData& data)
  284. {
  285. m_fontData = data;
  286. //autorelease pool - req'd for carbon
  287. NSAutoreleasePool *thePool;
  288. thePool = [[NSAutoreleasePool alloc] init];
  289. //Get the initial wx font
  290. wxFont& thewxfont = m_fontData.m_initialFont;
  291. //if the font is valid set the default (selected) font of the
  292. //NSFontDialog to that font
  293. if (thewxfont.IsOk())
  294. {
  295. NSFontTraitMask theMask = 0;
  296. if(thewxfont.GetStyle() == wxFONTSTYLE_ITALIC)
  297. theMask |= NSItalicFontMask;
  298. if(thewxfont.IsFixedWidth())
  299. theMask |= NSFixedPitchFontMask;
  300. NSFont* theDefaultFont =
  301. [[NSFontManager sharedFontManager] fontWithFamily:
  302. wxNSStringWithWxString(thewxfont.GetFaceName())
  303. traits:theMask
  304. weight:thewxfont.GetWeight() == wxBOLD ? 9 :
  305. thewxfont.GetWeight() == wxLIGHT ? 0 : 5
  306. size: (float)(thewxfont.GetPointSize())
  307. ];
  308. wxASSERT_MSG(theDefaultFont, wxT("Invalid default font for wxCocoaFontDialog!"));
  309. //Apple docs say to call NSFontManager::setSelectedFont
  310. //However, 10.3 doesn't seem to create the font panel
  311. //is this is done, so create it ourselves
  312. [[NSFontPanel sharedFontPanel] setPanelFont:theDefaultFont isMultiple:NO];
  313. }
  314. if(m_fontData.m_fontColour.IsOk())
  315. [[NSColorPanel sharedColorPanel] setColor:
  316. [NSColor colorWithCalibratedRed:m_fontData.m_fontColour.Red() / 255.0
  317. green:m_fontData.m_fontColour.Green() / 255.0
  318. blue:m_fontData.m_fontColour.Blue() / 255.0
  319. alpha:1.0]
  320. ];
  321. else
  322. [[NSColorPanel sharedColorPanel] setColor:[NSColor blackColor]];
  323. //We're done - free up the pool
  324. [thePool release];
  325. return true;
  326. }
  327. int wxFontDialog::ShowModal()
  328. {
  329. //Start the pool. Required for carbon interaction
  330. //(For those curious, the only thing that happens
  331. //if you don't do this is a bunch of error
  332. //messages about leaks on the console,
  333. //with no windows shown or anything).
  334. NSAutoreleasePool *thePool;
  335. thePool = [[NSAutoreleasePool alloc] init];
  336. //Get the shared color and font panel
  337. NSFontPanel* theFontPanel = [NSFontPanel sharedFontPanel];
  338. NSColorPanel* theColorPanel = [NSColorPanel sharedColorPanel];
  339. //Create and assign the delegates (cocoa event handlers) so
  340. //we can tell if a window has closed/open or not
  341. wxWCDelegate* theFPDelegate = [[wxWCDelegate alloc] init];
  342. [theFontPanel setDelegate:theFPDelegate];
  343. wxWCODelegate* theCPDelegate = [[wxWCODelegate alloc] init];
  344. [theColorPanel setDelegate:theCPDelegate];
  345. //
  346. // Begin the modal loop for the font and color panels
  347. //
  348. // The idea is that we first make the font panel modal,
  349. // but if the color panel is opened, unless we stop the
  350. // modal loop the color panel opens behind the font panel
  351. // with no input acceptable to it - which makes it useless.
  352. //
  353. // So we set up delegates for both the color and font panels,
  354. // and the if the font panel opens the color panel, we
  355. // stop the modal loop, and start a separate modal loop for
  356. // the color panel until the color panel closes, switching
  357. // back to the font panel modal loop once it does close.
  358. //
  359. wxDialog::OSXBeginModalDialog();
  360. do
  361. {
  362. //
  363. // Start the font panel modal loop
  364. //
  365. NSModalSession session = [NSApp beginModalSessionForWindow:theFontPanel];
  366. for (;;)
  367. {
  368. [NSApp runModalSession:session];
  369. //If the font panel is closed or the font panel
  370. //opened the color panel, break
  371. if ([theFPDelegate isClosed] || [theCPDelegate isOpen])
  372. break;
  373. }
  374. [NSApp endModalSession:session];
  375. //is the color panel open?
  376. if ([theCPDelegate isOpen])
  377. {
  378. //
  379. // Start the color panel modal loop
  380. //
  381. NSModalSession session = [NSApp beginModalSessionForWindow:theColorPanel];
  382. for (;;)
  383. {
  384. [NSApp runModalSession:session];
  385. //If the color panel is closed, return the font panel modal loop
  386. if ([theCPDelegate isClosed])
  387. break;
  388. }
  389. [NSApp endModalSession:session];
  390. }
  391. //If the font panel is still alive (I.E. we broke
  392. //out of its modal loop because the color panel was
  393. //opened) return the font panel modal loop
  394. }while([theFPDelegate isClosed] == NO);
  395. wxDialog::OSXEndModalDialog();
  396. //free up the memory for the delegates - we don't need them anymore
  397. [theFPDelegate release];
  398. [theCPDelegate release];
  399. //Get the font the user selected
  400. NSFont* theFont = [theFontPanel panelConvertFont:[NSFont userFontOfSize:0]];
  401. //Get more information about the user's chosen font
  402. NSFontTraitMask theTraits = [[NSFontManager sharedFontManager] traitsOfFont:theFont];
  403. int theFontWeight = [[NSFontManager sharedFontManager] weightOfFont:theFont];
  404. int theFontSize = (int) [theFont pointSize];
  405. //Set the wx font to the appropriate data
  406. if(theTraits & NSFixedPitchFontMask)
  407. m_fontData.m_chosenFont.SetFamily(wxTELETYPE);
  408. m_fontData.m_chosenFont.SetFaceName(wxStringWithNSString([theFont familyName]));
  409. m_fontData.m_chosenFont.SetPointSize(theFontSize);
  410. m_fontData.m_chosenFont.SetStyle(theTraits & NSItalicFontMask ? wxFONTSTYLE_ITALIC : 0);
  411. m_fontData.m_chosenFont.SetWeight(theFontWeight < 5 ? wxLIGHT :
  412. theFontWeight >= 9 ? wxBOLD : wxNORMAL);
  413. //Get the shared color panel along with the chosen color and set the chosen color
  414. NSColor* theColor = [[theColorPanel color] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
  415. m_fontData.m_fontColour.Set((unsigned char) ([theColor redComponent] * 255.0),
  416. (unsigned char) ([theColor greenComponent] * 255.0),
  417. (unsigned char) ([theColor blueComponent] * 255.0));
  418. //Friendly debug stuff
  419. #ifdef FONTDLGDEBUG
  420. wxPrintf(wxT("---Font Panel---\n--NS--\nSize:%f\nWeight:%i\nTraits:%i\n--WX--\nFaceName:%s\nPointSize:%i\nStyle:%i\nWeight:%i\nColor:%i,%i,%i\n---END Font Panel---\n"),
  421. (float) theFontSize,
  422. theFontWeight,
  423. theTraits,
  424. m_fontData.m_chosenFont.GetFaceName().c_str(),
  425. m_fontData.m_chosenFont.GetPointSize(),
  426. m_fontData.m_chosenFont.GetStyle(),
  427. m_fontData.m_chosenFont.GetWeight(),
  428. m_fontData.m_fontColour.Red(),
  429. m_fontData.m_fontColour.Green(),
  430. m_fontData.m_fontColour.Blue() );
  431. #endif
  432. //Release the pool, we're done :)
  433. [thePool release];
  434. //Return ID_OK - there are no "apply" buttons or the like
  435. //on either the font or color panel
  436. return wxID_OK;
  437. }
  438. //old api stuff (REMOVE ME)
  439. bool wxFontDialog::IsShown() const
  440. {
  441. return false;
  442. }
  443. #endif // 10.2+
  444. #endif