]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/dialog.cpp
wxStaticBitmap::GetIcon() added
[wxWidgets.git] / src / motif / dialog.cpp
index d67152d0fcb8ea5d02273d06f5c3a3429d8c49fa..41d930d7f16c8b5842d5373201c8a6f7b3435180 100644 (file)
@@ -42,7 +42,6 @@
 #include "wx/motif/private.h"
 
 static void wxCloseDialogCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs);
-static void wxDialogBoxRepaintProc(Widget w, XtPointer c_data, XEvent *event, char *);
 static void wxDialogBoxEventHandler (Widget    wid,
                                      XtPointer client_data,
                                      XEvent*   event,
@@ -231,7 +230,7 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
         SetSize(pos.x, pos.y, size.x, size.y);
     }
     XtAddEventHandler(dialogShell,ExposureMask,FALSE,
-        wxDialogBoxRepaintProc, (XtPointer) this);
+        wxUniversalRepaintProc, (XtPointer) this);
     
     XtAddEventHandler(dialogShell,
         ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask,
@@ -259,6 +258,10 @@ void wxDialog::SetModal(bool flag)
 
 wxDialog::~wxDialog()
 {
+    if (m_mainWidget)
+      XtRemoveEventHandler((Widget) m_mainWidget, ExposureMask, FALSE,
+          wxUniversalRepaintProc, (XtPointer) this);
+    
     m_modalShowing = FALSE;
     if (!wxUSE_INVISIBLE_RESIZE && m_mainWidget)
     {
@@ -285,26 +288,16 @@ wxDialog::~wxDialog()
     // but I think this should work, if we destroy the children first.
     // Note that this might need to be done for wxFrame also.
     DestroyChildren();
-    
-    // This causes a crash in e.g. the resource sample when closing
-    // the example dialog. TODO: Probably not necessary (?)
-#if 0
-    // Now process all events, because otherwise
-    // this might remain on the screen.
-    Display* display;
-    if (m_mainWidget)
-        display = XtDisplay((Widget) m_mainWidget);
-    else
-        display = (Display*) wxGetDisplay();
-    
-    XSync(display, FALSE);
-    XEvent event;
-    while (XtAppPending((XtAppContext) wxTheApp->GetAppContext())) {
-        XFlush(display);
-        XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event);
-        XtDispatchEvent(&event);
+
+    // The idea about doing it here is that if you have to remove the
+    // XtDestroyWidget from ~wxWindow, at least top-level windows
+    // will still be deleted (and destroy children implicitly).
+    if (GetMainWidget())
+    {
+      DetachWidget(GetMainWidget()); // Removes event handlers
+      XtDestroyWidget((Widget) GetMainWidget());
+      SetMainWidget((WXWidget) NULL);
     }
-#endif
 }
 
 // By default, pressing escape cancels the dialog
@@ -342,19 +335,18 @@ XtVaGetValues((Widget) m_mainWidget, XmNiconic, &iconic, NULL);
     return FALSE;
 }
 
-void wxDialog::SetSize(int x, int y, int width, int height, int sizeFlags)
+void wxDialog::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
     XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_ANY, NULL);
-    wxWindow::SetSize(x, y, width, height, sizeFlags);
+    wxWindow::DoSetSize(x, y, width, height, sizeFlags);
     XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_NONE, NULL);
 }
 
-void wxDialog::SetClientSize(int width, int height)
+void wxDialog::DoSetClientSize(int width, int height)
 {
-    SetSize(-1, -1, width, height);
+    wxWindow::SetSize(-1, -1, width, height);
 }
 
-
 void wxDialog::SetTitle(const wxString& title)
 {
     m_dialogTitle = title;
@@ -564,37 +556,34 @@ void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
     }
 }
 
-bool wxDialog::OnClose()
+void wxDialog::OnCloseWindow(wxCloseEvent& event)
 {
-    // Behaviour changed in 2.0: we'll send a Cancel message by default,
+    // We'll send a Cancel message by default,
     // which may close the dialog.
-    // Check for looping if the Cancel event handler calls Close()
-    
+    // Check for looping if the Cancel event handler calls Close().
+
+    // Note that if a cancel button and handler aren't present in the dialog,
+    // nothing will happen when you close the dialog via the window manager, or
+    // via Close().
+    // We wouldn't want to destroy the dialog by default, since the dialog may have been
+    // created on the stack.
+    // However, this does mean that calling dialog->Close() won't delete the dialog
+    // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
+    // sure to destroy the dialog.
+    // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
+
     static wxList closing;
     
     if ( closing.Member(this) )
-        return FALSE;
+        return;
     
     closing.Append(this);
     
     wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
     cancelEvent.SetEventObject( this );
-    GetEventHandler()->ProcessEvent(cancelEvent);
-    
-    closing.DeleteObject(this);
-    
-    return FALSE;
-}
+    GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
 
-void wxDialog::OnCloseWindow(wxCloseEvent& event)
-{
-    // Compatibility
-    if ( GetEventHandler()->OnClose() || !event.CanVeto())
-    {
-        this->Destroy();
-    }
-    else
-        event.Veto(TRUE);
+    closing.DeleteObject(this);
 }
 
 // Destroy the window (delayed, if a managed window)
@@ -628,47 +617,7 @@ static void wxCloseDialogCallback( Widget WXUNUSED(widget), XtPointer client_dat
     dialog->GetEventHandler()->ProcessEvent(closeEvent);
 }
 
-// TODO: Preferably, we should have a universal repaint proc.
-// Meanwhile, use a special one for dialogs.
-static void wxDialogBoxRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *)
-{
-    Window window;
-    Display *display;
-    
-    wxWindow* win = (wxWindow *)wxWidgetHashTable->Get((long)w);
-    if (!win)
-        return;
-    
-    switch(event -> type)
-    {
-    case Expose :
-        {
-            window = (Window) win -> GetXWindow();
-            display = (Display *) win -> GetXDisplay();
-            
-            wxRect* rect = new wxRect(event->xexpose.x, event->xexpose.y,
-                event->xexpose.width, event->xexpose.height);
-            win->m_updateRects.Append((wxObject*) rect);
-            
-            if (event -> xexpose.count == 0)
-            {
-                wxPaintEvent event(win->GetId());
-                event.SetEventObject(win);
-                win->GetEventHandler()->ProcessEvent(event);
-                
-                win->ClearUpdateRects();
-            }
-            break;
-        }
-    default :
-        {
-            cout << "\n\nNew Event ! is = " << event -> type << "\n";
-            break;
-        }
-    }
-}
-
-static void wxDialogBoxEventHandler (Widget    wid,
+void wxDialogBoxEventHandler (Widget    wid,
                                      XtPointer WXUNUSED(client_data),
                                      XEvent*   event,
                                      Boolean *continueToDispatch)
@@ -702,8 +651,16 @@ static void wxDialogBoxEventHandler (Widget    wid,
                 }
                 else
                 {
-                    keyEvent.SetEventType(wxEVT_CHAR);
-                    dialog->GetEventHandler()->ProcessEvent(keyEvent);
+                    // For simplicity, OnKeyDown is the same as OnChar
+                    // TODO: filter modifier key presses from OnChar
+                    keyEvent.SetEventType(wxEVT_KEY_DOWN);
+
+                    // Only process OnChar if OnKeyDown didn't swallow it
+                    if (!dialog->GetEventHandler()->ProcessEvent (keyEvent))
+                    {
+                        keyEvent.SetEventType(wxEVT_CHAR);
+                        dialog->GetEventHandler()->ProcessEvent(keyEvent);
+                   }
                 }
             }
         }