| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /////////////////////////////////////////////////////////////////////////////
- // Name: src/cocoa/dialog.mm
- // Purpose: wxDialog class
- // Author: David Elliott
- // Modified by:
- // Created: 2002/12/15
- // Copyright: 2002 David Elliott
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- #include "wx/wxprec.h"
- #include "wx/dialog.h"
- #ifndef WX_PRECOMP
- #include "wx/log.h"
- #include "wx/app.h"
- #include "wx/settings.h"
- #endif //WX_PRECOMP
- #include "wx/modalhook.h"
- #include "wx/cocoa/autorelease.h"
- #include "wx/cocoa/string.h"
- #import <AppKit/NSPanel.h>
- #import <AppKit/NSApplication.h>
- #import <AppKit/NSEvent.h>
- #import <Foundation/NSRunLoop.h>
- // Lists to keep track of windows, so we can disable/enable them
- // for modal dialogs
- static wxWindowList wxModalDialogs;
- IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
- WX_IMPLEMENT_COCOA_OWNER(wxDialog,NSPanel,NSWindow,NSWindow)
- void wxDialog::Init()
- {
- m_isModal = false;
- SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
- }
- bool wxDialog::Create(wxWindow *parent, wxWindowID winid,
- const wxString& title,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& name)
- {
- wxAutoNSAutoreleasePool pool;
- wxTopLevelWindows.Append(this);
- if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
- return false;
- if (parent)
- parent->AddChild(this);
- unsigned int cocoaStyle = NSWindowStyleForWxStyle(style);
- NSRect cocoaRect = MakeInitialNSWindowContentRect(pos,size,cocoaStyle);
- m_cocoaNSWindow = NULL;
- SetNSPanel([[NSPanel alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
- // NOTE: SetNSWindow has retained the Cocoa object for this object.
- // Because we do not release on close, the following release matches the
- // above alloc and thus the retain count will be 1.
- [m_cocoaNSWindow release];
- wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxDialog m_cocoaNSWindow retainCount=%d"),[m_cocoaNSWindow retainCount]);
- [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
- [m_cocoaNSWindow setHidesOnDeactivate:NO];
- return true;
- }
- wxDialog::~wxDialog()
- {
- DisassociateNSPanel(GetNSPanel());
- }
- void wxDialog::CocoaDelegate_windowWillClose(void)
- {
- m_closed = true;
- /* Actually, this isn't true anymore */
- wxLogTrace(wxTRACE_COCOA,wxT("Woah: Dialogs are not generally closed"));
- }
- void wxDialog::SetModal(bool flag)
- {
- wxFAIL_MSG( wxT("wxDialog:SetModal obsolete now") );
- }
- bool wxDialog::Show(bool show)
- {
- if(m_isShown == show)
- return false;
- if(show)
- {
- wxAutoNSAutoreleasePool pool;
- if (CanDoLayoutAdaptation())
- DoLayoutAdaptation();
- InitDialog();
- if(IsModal())
- { // ShowModal() will show the dialog
- m_isShown = true;
- return true;
- }
- }
- else
- {
- if(IsModal())
- { // this doesn't hide the dialog, base class Show(false) does.
- wxLogTrace(wxTRACE_COCOA,wxT("abortModal"));
- [wxTheApp->GetNSApplication() abortModal];
- wxModalDialogs.DeleteObject(this);
- m_isModal = false;
- }
- }
- return wxTopLevelWindow::Show(show);
- }
- // Shows the dialog and begins a modal event loop. When the event loop
- // is stopped (via EndModal()) it returns the exit code.
- int wxDialog::ShowModal()
- {
- WX_HOOK_MODAL_DIALOG();
- wxCHECK_MSG(!IsModal(),GetReturnCode(),wxT("wxDialog::ShowModal called within its own modal loop"));
- // Show(true) will set m_isShown = true
- m_isShown = false;
- m_isModal = true;
- wxModalDialogs.Append(this);
- wxLogTrace(wxTRACE_COCOA,wxT("runModal"));
- NSApplication *theNSApp = wxTheApp->GetNSApplication();
- // If the app hasn't started, flush the event queue
- // If we don't do this, the Dock doesn't get the message that
- // the app has started so will refuse to activate it.
- if(![theNSApp isRunning])
- {
- // We should only do a few iterations so one pool should be okay
- wxAutoNSAutoreleasePool pool;
- while(NSEvent *event = [theNSApp
- nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantPast]
- inMode:NSDefaultRunLoopMode
- dequeue: YES])
- {
- [theNSApp sendEvent: event];
- }
- }
- Show(true);
- do {
- wxAutoNSAutoreleasePool pool;
- [wxTheApp->GetNSApplication() runModalForWindow:m_cocoaNSWindow];
- } while(0);
- wxLogTrace(wxTRACE_COCOA,wxT("runModal END"));
- return GetReturnCode();
- }
- void wxDialog::EndModal(int retCode)
- {
- wxASSERT_MSG(IsModal(), wxT("EndModal() should only be used within ShowModal()"));
- SetReturnCode(retCode);
- Show(false);
- }
|