1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFontDialog class.
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 #include "wx/cmndata.h"
21 #include "wx/fontdlg.h"
22 #include "wx/fontutil.h"
25 // ============================================================================
27 // ============================================================================
30 #if USE_NATIVE_FONT_DIALOG_FOR_MACOSX
32 #if !USE_SHARED_LIBRARY
33 IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
37 #include "wx/cocoa/autorelease.h"
38 #include "wx/cocoa/string.h"
40 #import <AppKit/NSFont.h>
41 #import <AppKit/NSFontManager.h>
42 #import <AppKit/NSFontPanel.h>
43 #import <AppKit/NSColor.h>
44 #import <AppKit/NSColorPanel.h>
46 // ---------------------------------------------------------------------------
47 // wxWCDelegate - Window Closed delegate
48 // ---------------------------------------------------------------------------
50 @interface wxWCDelegate : NSObject
57 - (BOOL)windowShouldClose:(id)sender;
59 @end // interface wxNSFontPanelDelegate : NSObject
61 @implementation wxWCDelegate : NSObject
71 - (BOOL)windowShouldClose:(id)sender
85 @end // wxNSFontPanelDelegate
87 // ---------------------------------------------------------------------------
88 // wxWCODelegate - Window Closed or Open delegate
89 // ---------------------------------------------------------------------------
91 @interface wxWCODelegate : NSObject
99 - (BOOL)windowShouldClose:(id)sender;
100 - (void)windowDidUpdate:(NSNotification *)aNotification;
103 @end // interface wxNSFontPanelDelegate : NSObject
105 @implementation wxWCODelegate : NSObject
116 - (BOOL)windowShouldClose:(id)sender
126 - (void)windowDidUpdate:(NSNotification *)aNotification
148 @end // wxNSFontPanelDelegate
150 // ---------------------------------------------------------------------------
152 // ---------------------------------------------------------------------------
154 wxFontDialog::wxFontDialog()
158 wxFontDialog::wxFontDialog(wxWindow *parent, const wxFontData& data)
160 Create(parent, data);
163 wxFontDialog::~wxFontDialog()
167 bool wxFontDialog::Create(wxWindow *parent, const wxFontData& data)
172 // This is the key call - this initializes
173 // events and window stuff for cocoa for carbon
176 // This is also the only call here that is
177 // 10.2+ specific (the rest is OSX only),
178 // which, ironically, the carbon font
181 bool bOK = NSApplicationLoad();
183 //autorelease pool - req'd for carbon
184 NSAutoreleasePool *thePool;
185 thePool = [[NSAutoreleasePool alloc] init];
187 //Get the initial wx font
188 wxFont& thewxfont = m_fontData.m_initialFont;
190 //if the font is valid set the default (selected) font of the
191 //NSFontDialog to that font
194 NSFontTraitMask theMask = 0;
196 if(thewxfont.GetStyle() == wxFONTSTYLE_ITALIC)
197 theMask |= NSItalicFontMask;
199 if(thewxfont.IsFixedWidth())
200 theMask |= NSFixedPitchFontMask;
202 NSFont* theDefaultFont =
203 [[NSFontManager sharedFontManager] fontWithFamily:
204 wxNSStringWithWxString(thewxfont.GetFaceName())
206 weight:thewxfont.GetWeight() == wxBOLD ? 9 :
207 thewxfont.GetWeight() == wxLIGHT ? 0 : 5
208 size: (float)(thewxfont.GetPointSize())
211 wxASSERT_MSG(theDefaultFont, wxT("Invalid default font for wxCocoaFontDialog!"));
213 //set the initial font of the NSFontPanel
214 //(the font manager calls the appropriate NSFontPanel method)
215 [[NSFontManager sharedFontManager] setSelectedFont:theDefaultFont isMultiple:NO];
219 if(m_fontData.m_fontColour.Ok())
220 [[NSColorPanel sharedColorPanel] setColor:
221 [NSColor colorWithCalibratedRed:m_fontData.m_fontColour.Red() / 255.0
222 green:m_fontData.m_fontColour.Green() / 255.0
223 blue:m_fontData.m_fontColour.Blue() / 255.0
227 [[NSColorPanel sharedColorPanel] setColor:[NSColor blackColor]];
229 //We're done - free up the pool
235 int wxFontDialog::ShowModal()
237 //Start the pool. Required for carbon interaction
238 //(For those curious, the only thing that happens
239 //if you don't do this is a bunch of error
240 //messages about leaks on the console,
241 //with no windows shown or anything).
242 NSAutoreleasePool *thePool;
243 thePool = [[NSAutoreleasePool alloc] init];
245 //Get the shared color and font panel
246 NSFontPanel* theFontPanel = [NSFontPanel sharedFontPanel];
247 NSColorPanel* theColorPanel = [NSColorPanel sharedColorPanel];
249 //Create and assign the delegates (cocoa event handlers) so
250 //we can tell if a window has closed/open or not
251 wxWCDelegate* theFPDelegate = [[wxWCDelegate alloc] init];
252 [theFontPanel setDelegate:theFPDelegate];
254 wxWCODelegate* theCPDelegate = [[wxWCODelegate alloc] init];
255 [theColorPanel setDelegate:theCPDelegate];
258 // Begin the modal loop for the font and color panels
260 // The idea is that we first make the font panel modal,
261 // but if the color panel is opened, unless we stop the
262 // modal loop the color panel opens behind the font panel
263 // with no input acceptable to it - which makes it useless.
265 // So we set up delegates for both the color and font panels,
266 // and the if the font panel opens the color panel, we
267 // stop the modal loop, and start a seperate modal loop for
268 // the color panel until the color panel closes, switching
269 // back to the font panel modal loop once it does close.
274 // Start the font panel modal loop
276 NSModalSession session = [NSApp beginModalSessionForWindow:theFontPanel];
279 [NSApp runModalSession:session];
281 //If the font panel is closed or the font panel
282 //opened the color panel, break
283 if ([theFPDelegate isClosed] || [theCPDelegate isOpen])
286 [NSApp endModalSession:session];
288 //is the color panel open?
289 if ([theCPDelegate isOpen])
292 // Start the color panel modal loop
294 NSModalSession session = [NSApp beginModalSessionForWindow:theColorPanel];
297 [NSApp runModalSession:session];
299 //If the color panel is closed, return the font panel modal loop
300 if ([theCPDelegate isClosed])
303 [NSApp endModalSession:session];
305 //If the font panel is still alive (I.E. we broke
306 //out of its modal loop because the color panel was
307 //opened) return the font panel modal loop
308 }while([theFPDelegate isClosed] == NO);
310 //free up the memory for the delegates - we don't need them anymore
311 [theFPDelegate release];
312 [theCPDelegate release];
314 //Get the font the user selected
315 NSFont* theFont = [theFontPanel panelConvertFont:[NSFont userFontOfSize:0]];
317 //Get more information about the user's chosen font
318 NSFontTraitMask theTraits = [[NSFontManager sharedFontManager] traitsOfFont:theFont];
319 int theFontWeight = [[NSFontManager sharedFontManager] weightOfFont:theFont];
320 int theFontSize = (int) [theFont pointSize];
322 //Set the wx font to the appropriate data
323 if(theTraits & NSFixedPitchFontMask)
324 m_fontData.m_chosenFont.SetFamily(wxTELETYPE);
326 m_fontData.m_chosenFont.SetFaceName(wxStringWithNSString([theFont familyName]));
327 m_fontData.m_chosenFont.SetPointSize(theFontSize);
328 m_fontData.m_chosenFont.SetStyle(theTraits & NSItalicFontMask ? wxFONTSTYLE_ITALIC : 0);
329 m_fontData.m_chosenFont.SetWeight(theFontWeight < 5 ? wxLIGHT :
330 theFontWeight >= 9 ? wxBOLD : wxNORMAL);
332 //Get the shared color panel along with the chosen color and set the chosen color
333 NSColor* theColor = [[theColorPanel color] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
335 m_fontData.m_fontColour.Set((unsigned char) ([theColor redComponent] * 255.0),
336 (unsigned char) ([theColor greenComponent] * 255.0),
337 (unsigned char) ([theColor blueComponent] * 255.0));
339 //Friendly debug stuff
341 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"),
347 m_fontData.m_chosenFont.GetFaceName().c_str(),
348 m_fontData.m_chosenFont.GetPointSize(),
349 m_fontData.m_chosenFont.GetStyle(),
350 m_fontData.m_chosenFont.GetWeight(),
351 m_fontData.m_fontColour.Red(),
352 m_fontData.m_fontColour.Green(),
353 m_fontData.m_fontColour.Blue() );
356 //Release the pool, we're done :)
359 //Return ID_OK - there are no "apply" buttons or the like
360 //on either the font or color panel
364 //old api stuff (REMOVE ME)
365 bool wxFontDialog::IsShown() const