]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/window.cpp
Accelerators implemented for wxMotif; some wxComboBox stupidities cured
[wxWidgets.git] / src / motif / window.cpp
index 9fc441729c430a27160c2d71744321c949851a75..dc47a226d6a8d78db4a1020e03e8cd4188417782 100644 (file)
@@ -52,7 +52,7 @@ void wxCanvasRepaintProc (Widget, XtPointer, XmDrawingAreaCallbackStruct * cbs);
 void wxCanvasInputEvent (Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs);
 void wxCanvasMotionEvent (Widget, XButtonEvent * event);
 void wxCanvasEnterLeave (Widget drawingArea, XtPointer clientData, XCrossingEvent * event);
-void wxScrollBarCallback(Widget widget, XtPointer clientData,
+static void wxScrollBarCallback(Widget widget, XtPointer clientData,
                         XmScaleCallbackStruct *cbs);
 void wxPanelItemEventHandler (Widget    wid,
                               XtPointer client_data,
@@ -135,7 +135,6 @@ wxWindow::wxWindow()
     m_canAddEventHandler = FALSE;
     m_scrollPosX = 0;
     m_scrollPosY = 0;
-    m_paintRegion = (WXRegion) 0;
 }
 
 // Destructor
@@ -143,10 +142,6 @@ wxWindow::~wxWindow()
 {
     //// Motif-specific
 
-    if (m_paintRegion)
-        XDestroyRegion ((Region) m_paintRegion);
-    m_paintRegion = (WXRegion) 0;
-
     if (GetMainWidget())
         DetachWidget(GetMainWidget()); // Removes event handlers
 
@@ -243,6 +238,8 @@ wxWindow::~wxWindow()
 
     if ( m_windowValidator ) delete m_windowValidator;
     if (m_clientObject) delete m_clientObject;
+
+    ClearUpdateRects();
 }
 
 // Destroy the window (delayed, if a managed window)
@@ -309,7 +306,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
     m_pixmapOffsetY = 0;
     m_scrollPosX = 0;
     m_scrollPosY = 0;
-    m_paintRegion = (WXRegion) 0;
 
     if (!parent)
         return FALSE;
@@ -2016,9 +2012,9 @@ bool wxWindow::AcceptsFocus() const
 }
 
 // Update region access
-wxRegion wxWindow::GetUpdateRegion() const
+wxRegion& wxWindow::GetUpdateRegion() const
 {
-    return m_updateRegion;
+    return (wxRegion&) m_updateRegion;
 }
 
 bool wxWindow::IsExposed(int x, int y, int w, int h) const
@@ -2135,75 +2131,41 @@ void wxCanvasRepaintProc (Widget drawingArea, XtPointer clientData,
  XmDrawingAreaCallbackStruct * cbs)
 {
     if (!wxWidgetHashTable->Get ((long) (Widget) drawingArea))
-       return;
+           return;
 
     XEvent * event = cbs->event;
-    wxWindow * canvas = (wxWindow *) clientData;
-    Display * display = (Display *) canvas->GetXDisplay();
-    //    GC gc = (GC) canvas->GetDC()->gc;
+    wxWindow * win = (wxWindow *) clientData;
+    Display * display = (Display *) win->GetXDisplay();
 
     switch (event->type)
     {
-      case Expose:
-      {
-       /* TODO
-        wxCanvasDC* canvasDC = canvas->GetDC();
-        if (canvasDC)
-       {
-          if (canvasDC->onpaint_reg)
-            XDestroyRegion(canvasDC->onpaint_reg);
-          canvasDC->onpaint_reg = XCreateRegion();
-          
-       }
-       */
-
-       int n = canvas->m_updateRects.Number();
-        XRectangle* xrects = new XRectangle[n];
-        int i;
-       for (i = 0; i < canvas->m_updateRects.Number(); i++)
-       {
-         wxRect* rect = (wxRect*) canvas->m_updateRects.Nth(i)->Data();
-         xrects[i].x = rect->x;
-          xrects[i].y = rect->y;
-          xrects[i].width = rect->width;
-          xrects[i].height = rect->height;
-         /* TODO (?) Actually ignore it I think.
-          if (canvasDC)
-            XUnionRectWithRegion(&(xrects[i]), canvasDC->onpaint_reg,
-              canvasDC->onpaint_reg);
-      */
-       }
-       /* TODO must clip the area being repainted. So we need a gc.
-         * Alternatively, wxPaintDC must do the clipping
-         * when it's created.
-        XSetClipRectangles(display, gc, 0, 0, xrects, n, Unsorted);
-       */
-
-        canvas->DoPaint() ; // xrects, n);
-        delete[] xrects;
+        case Expose:
+        {
+            wxRect* rect = new wxRect(event->xexpose.x, event->xexpose.y,
+                                       event->xexpose.width, event->xexpose.height);
+           /*
+            cout << "Expose proc. wxRect: " << rect->x << ", " << rect->y << ", ";
+            cout << rect->width << ", " << rect->height << "\n\n";
+           */
 
-        canvas->m_updateRects.Clear();
+            win->m_updateRects.Append((wxObject*) rect);
 
-       /*
-        if (canvasDC)
-       {
-          XDestroyRegion(canvasDC->onpaint_reg);
-          canvasDC->onpaint_reg = NULL;
-       }
-
-       XGCValues gc_val;
-       gc_val.clip_mask = None;
-       XChangeGC(display, gc, GCClipMask, &gc_val);
-       */
+            if (event -> xexpose.count == 0)
+            {
+                wxPaintEvent event(win->GetId());
+                event.SetEventObject(win);
+                win->GetEventHandler()->ProcessEvent(event);
 
-       break;
-    }
-    default:
-    {
-       cout << "\n\nNew Event ! is = " << event -> type << "\n";
-       break;
+                win->ClearUpdateRects();
+            }
+            break;
+        }
+        default:
+        {
+               cout << "\n\nNew Event ! is = " << event -> type << "\n";
+               break;
+        }
     }
-  }
 }
 
 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
@@ -2773,7 +2735,7 @@ void wxPanelItemEventHandler (Widget    wid,
   *continueToDispatch = True;
 }
 
-void wxScrollBarCallback(Widget scrollbar, XtPointer clientData,
+static void wxScrollBarCallback(Widget scrollbar, XtPointer clientData,
                         XmScaleCallbackStruct *cbs)
 {
     Widget scrolledWindow = XtParent (scrollbar);
@@ -3138,4 +3100,83 @@ void wxWindow::SetFont(const wxFont& font)
     ChangeFont();
 }
 
+void wxWindow::ClearUpdateRects()
+{
+    wxNode* node = m_updateRects.First();
+    while (node)
+    {
+        wxRect* rect = (wxRect*) node->Data();
+        delete rect;
+        node = node->Next();
+    }
+    m_updateRects.Clear();
+}
+
+bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
+{
+    if (!m_acceleratorTable.Ok())
+        return FALSE;
+
+    int count = m_acceleratorTable.GetCount();
+    wxAcceleratorEntry* entries = m_acceleratorTable.GetEntries();
+    int i;
+    for (i = 0; i < count; i++)
+    {
+        wxAcceleratorEntry* entry = & (entries[i]);
+        if (entry->MatchesEvent(event))
+        {
+            // Bingo, we have a match. Now find a control
+            // that matches the entry command id.
+
+            // Need to go up to the top of the window hierarchy,
+            // since it might be e.g. a menu item
+            wxWindow* parent = this;
+            while (parent && !parent->IsKindOf(CLASSINFO(wxFrame)) && !parent->IsKindOf(CLASSINFO(wxDialog)))
+                parent = parent->GetParent();
+
+            if (!parent)
+                return FALSE;
+
+            if (parent->IsKindOf(CLASSINFO(wxFrame)))
+            {
+                // Try for a menu command
+                wxFrame* frame = (wxFrame*) parent;
+                if (frame->GetMenuBar())
+                {
+                    wxMenuItem* item = frame->GetMenuBar()->FindItemForId(entry->GetCommand());
+                    if (item)
+                    {
+                        wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, entry->GetCommand());
+                        commandEvent.SetEventObject(frame);
+
+                        // If ProcessEvent returns TRUE (it was handled), then
+                        // the calling code will skip the event handling.
+                        return frame->GetEventHandler()->ProcessEvent(commandEvent);
+                    }
+                }
+            }
+
+            // Find a child matching the command id
+            wxWindow* child = parent->FindWindow(entry->GetCommand());
+
+            // No such child
+            if (!child)
+                return FALSE;
+
+            // Now we process those kinds of windows that we can.
+            // For now, only buttons.
+            if (child->IsKindOf(CLASSINFO(wxButton)))
+            {
+                wxCommandEvent commandEvent (wxEVT_COMMAND_BUTTON_CLICKED, child->GetId());
+                commandEvent.SetEventObject(child);
+                return child->GetEventHandler()->ProcessEvent(commandEvent);
+            }
+
+            return FALSE;
+        } // matches event
+    }// for
+
+    // We didn't match the key event against an accelerator.
+    return FALSE;
+}