X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0d57be459406c2830f6abc9d99ae99166c6d133b..8aa04e8bf1638ed4d9355e560c8d718c8be4667a:/src/motif/window.cpp diff --git a/src/motif/window.cpp b/src/motif/window.cpp index e0d7b1fec2..dc47a226d6 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -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, @@ -108,6 +108,8 @@ wxWindow::wxWindow() #if wxUSE_DRAG_AND_DROP m_pDropTarget = NULL; #endif + m_clientObject = (wxClientData*) NULL; + m_clientData = NULL; /// Motif-specific m_mainWidget = (WXWidget) 0; @@ -133,7 +135,6 @@ wxWindow::wxWindow() m_canAddEventHandler = FALSE; m_scrollPosX = 0; m_scrollPosY = 0; - m_paintRegion = (WXRegion) 0; } // Destructor @@ -141,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 @@ -239,8 +236,10 @@ wxWindow::~wxWindow() // dangling pointers. wxPendingDelete.DeleteObject(this); - if ( m_windowValidator ) - delete m_windowValidator; + if ( m_windowValidator ) delete m_windowValidator; + if (m_clientObject) delete m_clientObject; + + ClearUpdateRects(); } // Destroy the window (delayed, if a managed window) @@ -282,6 +281,8 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, m_maxSizeY = -1; m_defaultItem = NULL; m_windowParent = NULL; + m_clientObject = (wxClientData*) NULL; + m_clientData = NULL; // Motif-specific m_canAddEventHandler = FALSE; @@ -305,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; @@ -740,6 +740,8 @@ bool wxWindow::Show(bool show) { if (m_borderWidget || m_scrolledWindow) { + if (m_drawingArea) + XtMapWidget((Widget) m_drawingArea); XtMapWidget(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); } else @@ -751,6 +753,8 @@ bool wxWindow::Show(bool show) { if (m_borderWidget || m_scrolledWindow) { + if (m_drawingArea) + XtUnmapWidget((Widget) m_drawingArea); XtUnmapWidget(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); } else @@ -1387,7 +1391,18 @@ void wxWindow::RemoveChild(wxWindow *child) void wxWindow::DestroyChildren() { - if (GetChildren()) { + if (GetChildren()) + { + wxNode *node = GetChildren()->First(); + while (node) + { + wxNode* next = node->Next(); + wxWindow* child = (wxWindow*) node->Data(); + delete child; + node = next; + } + GetChildren()->Clear(); +#if 0 wxNode *node; while ((node = GetChildren()->First()) != (wxNode *)NULL) { wxWindow *child; @@ -1397,6 +1412,7 @@ void wxWindow::DestroyChildren() delete node; } } /* while */ +#endif } } @@ -1913,6 +1929,27 @@ void wxWindow::SetValidator(const wxValidator& validator) m_windowValidator->SetWindow(this) ; } +void wxWindow::SetClientObject( wxClientData *data ) +{ + if (m_clientObject) delete m_clientObject; + m_clientObject = data; +} + +wxClientData *wxWindow::GetClientObject() +{ + return m_clientObject; +} + +void wxWindow::SetClientData( void *data ) +{ + m_clientData = data; +} + +void *wxWindow::GetClientData() +{ + return m_clientData; +} + // Find a window by id or name wxWindow *wxWindow::FindWindow(long id) { @@ -1975,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 @@ -2032,9 +2069,7 @@ void wxWidgetResizeProc(Widget w, XConfigureEvent *event, String args[], int *nu bool wxAddWindowToTable(Widget w, wxWindow *win) { wxWindow *oldItem = NULL; -#if DEBUG // printf("Adding widget %ld, name = %s\n", w, win->GetClassInfo()->GetClassName()); -#endif if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w))) { char buf[300]; @@ -2096,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) @@ -2734,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); @@ -3024,8 +3025,6 @@ void wxWindow::ChangeForegroundColour() // Change a widget's foreground and background colours. -// TODO: make this 2 functions, ChangeForegroundColour and ChangeBackgroundColour. - void wxWindow::DoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour) { // When should we specify the foreground, if it's calculated @@ -3072,12 +3071,11 @@ void wxWindow::SetForegroundColour(const wxColour& col) ChangeForegroundColour(); } -void wxWindow::ChangeFont() +void wxWindow::ChangeFont(bool keepOriginalSize) { // Note that this causes the widget to be resized back // to its original size! We therefore have to set the size // back again. TODO: a better way in Motif? - /* Widget w = (Widget) GetLabelWidget(); // Usually the main widget if (w && m_windowFont.Ok()) { @@ -3089,12 +3087,11 @@ void wxWindow::ChangeFont() NULL); GetSize(& width1, & height1); - if (width != width1 || height != height1) + if (keepOriginalSize && (width != width1 || height != height1)) { SetSize(-1, -1, width, height); } } - */ } void wxWindow::SetFont(const wxFont& font) @@ -3103,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; +}