#include "wx/menuitem.h"
#include "wx/log.h"
-#if USE_DRAG_AND_DROP
+#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#endif
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,
+ XmScaleCallbackStruct *cbs);
+void wxPanelItemEventHandler (Widget wid,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean *continueToDispatch);
#define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
#define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
m_caretWidth = 0; m_caretHeight = 0;
m_caretEnabled = FALSE;
m_caretShown = FALSE;
- m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW) ; ;
+ // m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW) ; ;
+ m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
m_foregroundColour = *wxBLACK;
- m_defaultForegroundColour = *wxBLACK ;
- m_defaultBackgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
-#if USE_DRAG_AND_DROP
+#if wxUSE_DRAG_AND_DROP
m_pDropTarget = NULL;
#endif
m_drawingArea = (WXWidget) 0;
m_hScroll = FALSE;
m_vScroll = FALSE;
- m_hScrollingEnabled = FALSE;
- m_vScrollingEnabled = FALSE;
m_backingPixmap = (WXPixmap) 0;
m_pixmapWidth = 0;
m_pixmapHeight = 0;
m_pixmapOffsetY = 0;
m_lastTS = 0;
m_lastButton = 0;
+ m_canAddEventHandler = FALSE;
+ m_scrollPosX = 0;
+ m_scrollPosY = 0;
+ m_paintRegion = (WXRegion) 0;
}
// Destructor
wxWindow::~wxWindow()
{
- //// Motif-specific
+ //// Motif-specific
- // If m_drawingArea, we're a fully-fledged window with drawing area, scrollbars etc. (what wxCanvas used to be)
- if (m_drawingArea)
- {
- // Destroy children before destroying self
- DestroyChildren();
+ if (m_paintRegion)
+ XDestroyRegion ((Region) m_paintRegion);
+ m_paintRegion = (WXRegion) 0;
- if (m_backingPixmap)
- XFreePixmap (XtDisplay ((Widget) GetMainWidget()), (Pixmap) m_backingPixmap);
+ if (GetMainWidget())
+ DetachWidget(GetMainWidget()); // Removes event handlers
- Widget w = (Widget) m_drawingArea;
- wxDeleteWindowFromTable(w);
+ // If m_drawingArea, we're a fully-fledged window with drawing area, scrollbars etc. (what wxCanvas used to be)
+ if (m_drawingArea)
+ {
+ // Destroy children before destroying self
+ DestroyChildren();
- if (w)
- XtDestroyWidget(w);
- m_mainWidget = (WXWidget) 0;
+ if (m_backingPixmap)
+ XFreePixmap (XtDisplay ((Widget) GetMainWidget()), (Pixmap) m_backingPixmap);
- // Only if we're _really_ a canvas (not a dialog box/panel)
- if (m_scrolledWindow)
- {
- wxDeleteWindowFromTable((Widget) m_scrolledWindow);
- }
+ Widget w = (Widget) m_drawingArea;
+ wxDeleteWindowFromTable(w);
- if (m_hScrollBar)
- {
- XtUnmanageChild ((Widget) m_hScrollBar);
- XtDestroyWidget ((Widget) m_hScrollBar);
- }
- if (m_vScrollBar)
- {
- XtUnmanageChild ((Widget) m_vScrollBar);
- XtDestroyWidget ((Widget) m_vScrollBar);
- }
- if (m_scrolledWindow)
- {
- XtUnmanageChild ((Widget) m_scrolledWindow);
- XtDestroyWidget ((Widget) m_scrolledWindow);
- }
+ if (w)
+ XtDestroyWidget(w);
+ m_mainWidget = (WXWidget) 0;
- if (m_borderWidget)
- {
- XtDestroyWidget ((Widget) m_borderWidget);
- m_borderWidget = (WXWidget) 0;
- }
- }
+ // Only if we're _really_ a canvas (not a dialog box/panel)
+ if (m_scrolledWindow)
+ {
+ wxDeleteWindowFromTable((Widget) m_scrolledWindow);
+ }
+ if (m_hScrollBar)
+ {
+ XtUnmanageChild ((Widget) m_hScrollBar);
+ XtDestroyWidget ((Widget) m_hScrollBar);
+ }
+ if (m_vScrollBar)
+ {
+ XtUnmanageChild ((Widget) m_vScrollBar);
+ XtDestroyWidget ((Widget) m_vScrollBar);
+ }
+ if (m_scrolledWindow)
+ {
+ XtUnmanageChild ((Widget) m_scrolledWindow);
+ XtDestroyWidget ((Widget) m_scrolledWindow);
+ }
- //// Generic stuff
+ if (m_borderWidget)
+ {
+ XtDestroyWidget ((Widget) m_borderWidget);
+ m_borderWidget = (WXWidget) 0;
+ }
+ }
+
+ //// Generic stuff
// Have to delete constraints/sizer FIRST otherwise
// sizers may try to look at deleted windows as they
// delete themselves.
-#if USE_CONSTRAINTS
+#if wxUSE_CONSTRAINTS
DeleteRelatedConstraints();
if (m_constraints)
{
m_sizerParent = NULL;
m_autoLayout = FALSE;
m_windowValidator = NULL;
-#if USE_DRAG_AND_DROP
+#if wxUSE_DRAG_AND_DROP
m_pDropTarget = NULL;
#endif
m_caretWidth = 0; m_caretHeight = 0;
m_windowParent = NULL;
// Motif-specific
+ m_canAddEventHandler = FALSE;
m_mainWidget = (WXWidget) 0;
m_button1Pressed = FALSE;
m_button2Pressed = FALSE;
m_drawingArea = (WXWidget) 0;
m_hScroll = FALSE;
m_vScroll = FALSE;
- m_hScrollingEnabled = FALSE;
- m_vScrollingEnabled = FALSE;
m_backingPixmap = (WXPixmap) 0;
m_pixmapWidth = 0;
m_pixmapHeight = 0;
m_pixmapOffsetX = 0;
m_pixmapOffsetY = 0;
+ m_scrollPosX = 0;
+ m_scrollPosY = 0;
+ m_paintRegion = (WXRegion) 0;
if (!parent)
return FALSE;
else
m_windowId = id;
- m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW) ; ;
+ // m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW) ; ;
+ m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
m_foregroundColour = *wxBLACK;
- m_defaultForegroundColour = *wxBLACK ;
- m_defaultBackgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
m_windowStyle = style;
XtAddEventHandler ((Widget) m_drawingArea, PointerMotionHintMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask,
False, (XtEventHandler) wxCanvasEnterLeave, (XtPointer) this);
- return TRUE;
+ // Add scrollbars if required
+ if (m_windowStyle & wxHSCROLL)
+ {
+ Widget hScrollBar = XtVaCreateManagedWidget ("hsb",
+ xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
+ XmNorientation, XmHORIZONTAL,
+ NULL);
+ // XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+ XtAddCallback (hScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
+
+ XtVaSetValues (hScrollBar,
+ XmNincrement, 1,
+ XmNvalue, 0,
+ NULL);
+
+ m_hScrollBar = (WXWidget) hScrollBar;
+ m_hScroll = TRUE;
+ }
+ if (m_windowStyle & wxVSCROLL)
+ {
+ Widget vScrollBar = XtVaCreateManagedWidget ("vsb",
+ xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
+ XmNorientation, XmVERTICAL,
+ NULL);
+ // XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+ XtAddCallback (vScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
+
+ XtVaSetValues (vScrollBar,
+ XmNincrement, 1,
+ XmNvalue, 0,
+ NULL);
+
+ m_vScrollBar = (WXWidget) vScrollBar;
+ m_vScroll = TRUE;
+ }
+
+ if (m_hScrollBar || m_vScrollBar)
+ XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
+
+ if (m_hScrollBar)
+ XtRealizeWidget ((Widget) m_hScrollBar);
+ if (m_vScrollBar)
+ XtRealizeWidget ((Widget) m_vScrollBar);
+
+ // Without this, the cursor may not be restored properly
+ // (e.g. in splitter sample).
+ SetCursor(*wxSTANDARD_CURSOR);
+ SetSize(pos.x, pos.y, size.x, size.y);
+
+ return TRUE;
}
void wxWindow::SetFocus()
return NULL;
}
-#if USE_DRAG_AND_DROP
+#if wxUSE_DRAG_AND_DROP
void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
{
return;
}
- Widget widget = (Widget) GetMainWidget();
+ Widget widget = (Widget) GetTopWidget();
Dimension xx, yy;
XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
*x = xx; *y = yy;
void wxWindow::GetPosition(int *x, int *y) const
{
- if (m_drawingArea)
- {
- CanvasGetPosition(x, y);
- return;
- }
- Widget widget = (Widget) GetMainWidget();
- Position xx, yy;
- XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
- *x = xx; *y = yy;
+ if (m_drawingArea)
+ {
+ CanvasGetPosition(x, y);
+ return;
+ }
+ Widget widget = (Widget) GetTopWidget();
+ Position xx, yy;
+ XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
+
+ // We may be faking the client origin.
+ // So a window that's really at (0, 30) may appear
+ // (to wxWin apps) to be at (0, 0).
+ if (GetParent())
+ {
+ wxPoint pt(GetParent()->GetClientAreaOrigin());
+ xx -= pt.x;
+ yy -= pt.y;
+ }
+
+ *x = xx; *y = yy;
}
void wxWindow::ScreenToClient(int *x, int *y) const
{
- // TODO
+ Widget widget = (Widget) GetClientWidget();
+ Display *display = XtDisplay((Widget) GetMainWidget());
+ Window rootWindow = RootWindowOfScreen(XtScreen(widget));
+ Window thisWindow = XtWindow(widget);
+
+ Window childWindow;
+ int xx = *x;
+ int yy = *y;
+ XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
}
void wxWindow::ClientToScreen(int *x, int *y) const
{
- Widget widget = (Widget) GetMainWidget();
+ Widget widget = (Widget) GetClientWidget();
Display *display = XtDisplay(widget);
Window rootWindow = RootWindowOfScreen(XtScreen(widget));
- Window thisWindow;
- if (this->IsKindOf(CLASSINFO(wxFrame)))
- {
- wxFrame *fr = (wxFrame *)this;
- // TODO
- // thisWindow = XtWindow(fr->m_clientArea);
- }
- else
- thisWindow = XtWindow((Widget)widget);
+ Window thisWindow = XtWindow(widget);
Window childWindow;
int xx = *x;
m_windowCursor = cursor;
if (m_windowCursor.Ok())
{
- /* TODO when wxCursor implemented
WXDisplay *dpy = GetXDisplay();
- Cursor x_cursor = cursor.GetXCursor(dpy);
+ WXCursor x_cursor = ((wxCursor&)cursor).GetXCursor(dpy);
Widget w = (Widget) GetMainWidget();
Window win = XtWindow(w);
- XDefineCursor((Display*) dpy, win, x_cursor);
- */
+ XDefineCursor((Display*) dpy, win, (Cursor) x_cursor);
}
}
// Get size *available for subwindows* i.e. excluding menu bar etc.
void wxWindow::GetClientSize(int *x, int *y) const
{
- Widget widget = (Widget) GetMainWidget();
+ Widget widget = (Widget) GetClientWidget();
Dimension xx, yy;
XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
*x = xx; *y = yy;
CanvasSetSize(x, y, width, height, sizeFlags);
return;
}
- Widget widget = (Widget) GetMainWidget();
+ Widget widget = (Widget) GetTopWidget();
+ if (!widget)
+ return;
+
+ bool managed = XtIsManaged( widget );
+ if (managed)
+ XtUnmanageChild(widget);
+
+ int xx = x; int yy = y;
+ AdjustForParentClientOrigin(xx, yy, sizeFlags);
if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
- XtVaSetValues(widget, XmNx, x, NULL);
+ XtVaSetValues(widget, XmNx, xx, NULL);
if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
- XtVaSetValues(widget, XmNy, y, NULL);
+ XtVaSetValues(widget, XmNy, yy, NULL);
if (width > -1)
XtVaSetValues(widget, XmNwidth, width, NULL);
if (height > -1)
XtVaSetValues(widget, XmNheight, height, NULL);
+ if (managed)
+ XtManageChild(widget);
+
wxSizeEvent sizeEvent(wxSize(width, height), GetId());
sizeEvent.SetEventObject(this);
return;
}
- Widget widget = (Widget) GetMainWidget();
+ Widget widget = (Widget) GetTopWidget();
if (width > -1)
XtVaSetValues(widget, XmNwidth, width, NULL);
}
else
{
- XtMapWidget((Widget) GetMainWidget());
+ XtMapWidget((Widget) GetTopWidget());
}
}
else
}
else
{
- XtUnmapWidget((Widget) GetMainWidget());
+ XtUnmapWidget((Widget) GetTopWidget());
}
}
int wxWindow::GetCharHeight() const
{
- // TODO
+ if (!m_windowFont.Ok())
return 0;
+
+ WXFontStructPtr pFontStruct = m_windowFont.GetFontStruct(1.0, GetXDisplay());
+
+ int direction, ascent, descent;
+ XCharStruct overall;
+ XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
+ &descent, &overall);
+// return (overall.ascent + overall.descent);
+ return (ascent + descent);
}
int wxWindow::GetCharWidth() const
{
- // TODO
+ if (!m_windowFont.Ok())
return 0;
+
+ WXFontStructPtr pFontStruct = m_windowFont.GetFontStruct(1.0, GetXDisplay());
+
+ int direction, ascent, descent;
+ XCharStruct overall;
+ XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
+ &descent, &overall);
+ return overall.width;
+}
+
+/* Helper function for 16-bit fonts */
+static int str16len(const char *s)
+{
+ int count = 0;
+
+ while (s[0] && s[1]) {
+ count++;
+ s += 2;
+ }
+
+ return count;
}
void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
- int *descent, int *externalLeading, const wxFont *theFont, bool) const
+ int *descent, int *externalLeading, const wxFont *theFont, bool use16) const
{
wxFont *fontToUse = (wxFont *)theFont;
if (!fontToUse)
fontToUse = (wxFont *) & m_windowFont;
- // TODO
+ if (!fontToUse->Ok())
+ return;
+
+ WXFontStructPtr pFontStruct = theFont->GetFontStruct(1.0, GetXDisplay());
+
+ int direction, ascent, descent2;
+ XCharStruct overall;
+ int slen;
+
+ if (use16) slen = str16len(string); else slen = strlen(string);
+
+ if (use16)
+ XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction,
+ &ascent, &descent2, &overall);
+ else
+ XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) string, slen, &direction,
+ &ascent, &descent2, &overall);
+
+ *x = (overall.width);
+ *y = (ascent + descent2);
+ if (descent)
+ *descent = descent2;
+ if (externalLeading)
+ *externalLeading = 0;
}
void wxWindow::Refresh(bool eraseBack, const wxRectangle *rect)
if (eraseBack)
{
wxClientDC dc(this);
+ wxBrush backgroundBrush(GetBackgroundColour(), wxSOLID);
+ dc.SetBackground(backgroundBrush);
dc.Clear();
}
return;
wxFrame *frame = (wxFrame *)this;
+ Widget widget = (Widget) frame->GetShellWidget();
- /* Uncomment when wxFrame implemented
if (minW > -1)
- XtVaSetValues((Widget) frame->m_frameShell, XmNminWidth, minW, NULL);
+ XtVaSetValues(widget, XmNminWidth, minW, NULL);
if (minH > -1)
- XtVaSetValues((Widget) frame->m_frameShell, XmNminHeight, minH, NULL);
+ XtVaSetValues(widget, XmNminHeight, minH, NULL);
if (maxW > -1)
- XtVaSetValues((Widget) frame->m_frameShell, XmNmaxWidth, maxW, NULL);
+ XtVaSetValues(widget, XmNmaxWidth, maxW, NULL);
if (maxH > -1)
- XtVaSetValues((Widget) frame->m_frameShell, XmNmaxHeight, maxH, NULL);
+ XtVaSetValues(widget, XmNmaxHeight, maxH, NULL);
if (incW > -1)
- XtVaSetValues((Widget) frame->m_frameShell, XmNwidthInc, incW, NULL);
+ XtVaSetValues(widget, XmNwidthInc, incW, NULL);
if (incH > -1)
- XtVaSetValues((Widget) frame->m_frameShell, XmNheightInc, incH, NULL);
- */
+ XtVaSetValues(widget, XmNheightInc, incH, NULL);
}
void wxWindow::Centre(int direction)
int wxWindow::GetScrollPos(int orient) const
{
- // TODO
- return 0;
+ if (orient == wxHORIZONTAL)
+ return m_scrollPosX;
+ else
+ return m_scrollPosY;
+/*
+ Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar);
+ if (scrollBar)
+ {
+ int pos;
+ XtVaGetValues(scrollBar,
+ XmNvalue, &pos, NULL);
+ return pos;
+ }
+ else
+ return 0;
+*/
}
// This now returns the whole range, not just the number
// of positions that we can scroll.
int wxWindow::GetScrollRange(int orient) const
{
- // TODO
- return 0;
+ Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar);
+ if (scrollBar)
+ {
+ int range;
+ XtVaGetValues(scrollBar,
+ XmNmaximum, &range, NULL);
+ return range;
+ }
+ else
+ return 0;
}
int wxWindow::GetScrollThumb(int orient) const
{
- // TODO
- return 0;
+ Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar);
+ if (scrollBar)
+ {
+ int thumb;
+ XtVaGetValues(scrollBar,
+ XmNsliderSize, &thumb, NULL);
+ return thumb;
+ }
+ else
+ return 0;
}
-void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
+void wxWindow::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
{
- // TODO
- return;
+ Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar);
+ if (scrollBar)
+ {
+ XtVaSetValues (scrollBar,
+ XmNvalue, pos,
+ NULL);
+ }
+ if (orient == wxHORIZONTAL)
+ m_scrollPosX = pos;
+ else
+ m_scrollPosY = pos;
+
}
// New function that will replace some of the above.
void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
- int range, bool refresh)
+ int range, bool WXUNUSED(refresh))
{
- // TODO
+ Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar );
+ if (!scrollBar)
+ return;
+
+ if (range == 0)
+ range = 1;
+ if (thumbVisible == 0)
+ thumbVisible = 1;
+
+ XtVaSetValues(scrollBar,
+ XmNvalue, pos,
+ XmNminimum, 0,
+ XmNmaximum, range,
+ XmNsliderSize, thumbVisible,
+ NULL);
+
+ if (orient == wxHORIZONTAL)
+ m_scrollPosX = pos;
+ else
+ m_scrollPosY = pos;
}
// Does a physical scroll
void wxWindow::ScrollWindow(int dx, int dy, const wxRectangle *rect)
{
- // TODO
- return;
+// cerr << "Scrolling. delta = " << dx << ", " << dy << endl;
+ int x, y, w, h;
+ if (rect)
+ {
+ // Use specified rectangle
+ x = rect->x; y = rect->y; w = rect->width; h = rect->height;
+ }
+ else
+ {
+ // Use whole client area
+ x = 0; y = 0;
+ GetClientSize(& w, & h);
+ }
+
+ int x1 = (dx >= 0) ? x : x - dx ;
+ int y1 = (dy >= 0) ? y : y - dy;
+ int w1 = w - abs(dx);
+ int h1 = h - abs(dy);
+ int x2 = (dx >= 0) ? x + dx : x;
+ int y2 = (dy >= 0) ? y + dy : y;
+
+ wxClientDC dc(this);
+
+ dc.SetLogicalFunction (wxCOPY);
+
+ Widget widget = (Widget) GetMainWidget();
+ Window window = XtWindow(widget);
+ Display* display = XtDisplay(widget);
+
+ XCopyArea(display, window,
+ window, (GC) dc.GetGC(),
+ x1, y1,
+ w1, h1,
+ x2, y2);
+
+ dc.SetAutoSetting(TRUE);
+ wxBrush brush(GetBackgroundColour(), wxSOLID);
+ dc.SetBrush(brush); // ??
+
+ // We'll add rectangles to the list of update rectangles
+ // according to which bits we've exposed.
+ wxList updateRects;
+
+ if (dx > 0)
+ {
+ wxRect *rect = new wxRect;
+ rect->x = x;
+ rect->y = y;
+ rect->width = dx;
+ rect->height = h;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ else if (dx < 0)
+ {
+ wxRect *rect = new wxRect;
+
+ rect->x = x + w + dx;
+ rect->y = y;
+ rect->width = -dx;
+ rect->height = h;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width,
+ rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ if (dy > 0)
+ {
+ wxRect *rect = new wxRect;
+
+ rect->x = x;
+ rect->y = y;
+ rect->width = w;
+ rect->height = dy;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ else if (dy < 0)
+ {
+ wxRect *rect = new wxRect;
+
+ rect->x = x;
+ rect->y = y + h + dy;
+ rect->width = w;
+ rect->height = -dy;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ dc.SetBrush(wxNullBrush);
+
+ // Now send expose events
+
+ wxNode* node = updateRects.First();
+ while (node)
+ {
+ wxRect* rect = (wxRect*) node->Data();
+ XExposeEvent event;
+
+ event.type = Expose;
+ event.display = display;
+ event.send_event = True;
+ event.window = window;
+
+ event.x = rect->x;
+ event.y = rect->y;
+ event.width = rect->width;
+ event.height = rect->height;
+
+ event.count = 0;
+
+ XSendEvent(display, window, False, ExposureMask, (XEvent *)&event);
+
+ node = node->Next();
+
+ }
}
void wxWindow::SetFont(const wxFont& font)
{
m_windowFont = font;
- if (!m_windowFont.Ok())
- return;
- // TODO
+ // 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())
+ {
+ int width, height, width1, height1;
+ GetSize(& width, & height);
+
+ XtVaSetValues (w,
+ XmNfontList, (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay(w)),
+ NULL);
+
+ GetSize(& width1, & height1);
+ if (width != width1 || height != height1)
+ {
+ SetSize(-1, -1, width, height);
+ }
+ }
+ */
}
void wxWindow::OnChar(wxKeyEvent& event)
bool wxWindow::IsEnabled() const
{
- // TODO
+ // TODO. Is this right?
+ // return XtGetSensitive((Widget) GetMainWidget());
return FALSE;
}
}
}
+// If nothing defined for this, try the parent.
+// E.g. we may be a button loaded from a resource, with no callback function
+// defined.
+void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
+{
+ if (GetEventHandler()->ProcessEvent(event) )
+ return;
+ if (m_windowParent)
+ m_windowParent->GetEventHandler()->OnCommand(win, event);
+}
+
void wxWindow::SetConstraints(wxLayoutConstraints *c)
{
if (m_constraints)
void wxWindow::Clear()
{
- wxClientDC dc(this);
+ wxClientDC dc(this);
wxBrush brush(GetBackgroundColour(), wxSOLID);
dc.SetBackground(brush);
dc.Clear();
// Raise the window to the top of the Z order
void wxWindow::Raise()
{
- Window window = XtWindow((Widget) GetMainWidget());
- XRaiseWindow(XtDisplay((Widget) GetMainWidget()), window);
+ Window window = XtWindow((Widget) GetTopWidget());
+ XRaiseWindow(XtDisplay((Widget) GetTopWidget()), window);
}
// Lower the window to the bottom of the Z order
void wxWindow::Lower()
{
- Window window = XtWindow((Widget) GetMainWidget());
- XLowerWindow(XtDisplay((Widget) GetMainWidget()), window);
+ Window window = XtWindow((Widget) GetTopWidget());
+ XLowerWindow(XtDisplay((Widget) GetTopWidget()), window);
}
bool wxWindow::AcceptsFocus() const
void wxDeleteWindowFromTable(Widget w)
{
-#if DEBUG
-// printf("Deleting widget %ld\n", w);
-#endif
-// wxWindow *win = (wxWindow *)wxWidgetHashTable->Get ((long) w);
-
wxWidgetHashTable->Delete((long)w);
}
if (m_drawingArea != (WXWidget) 0)
return m_drawingArea;
else
- return m_mainWidget;
+ return GetMainWidget();
+}
+
+WXWidget wxWindow::GetTopWidget() const
+{
+ return GetMainWidget();
}
void wxCanvasRepaintProc (Widget drawingArea, XtPointer clientData,
wxevent.SetId(canvas->GetId());
wxevent.SetEventObject(canvas);
+ wxevent.m_x = local_event.xbutton.x;
+ wxevent.m_y = local_event.xbutton.y;
canvas->GetEventHandler()->ProcessEvent (wxevent);
/*
if (eventType == wxEVT_ENTER_WINDOW ||
XtUnmanageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
+ int xx = x; int yy = y;
+ AdjustForParentClientOrigin(xx, yy, sizeFlags);
+
if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
{
XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
- XmNx, x, NULL);
+ XmNx, xx, NULL);
}
if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
{
XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
- XmNy, y, NULL);
+ XmNy, yy, NULL);
}
if (w > -1)
void wxWindow::CanvasGetPosition (int *x, int *y) const
{
- Position xx, yy;
- XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL);
- *x = xx;
- *y = yy;
+ Position xx, yy;
+ XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL);
+
+ // We may be faking the client origin.
+ // So a window that's really at (0, 30) may appear
+ // (to wxWin apps) to be at (0, 0).
+ if (GetParent())
+ {
+ wxPoint pt(GetParent()->GetClientAreaOrigin());
+ xx -= pt.x;
+ yy -= pt.y;
+ }
+
+ *x = xx;
+ *y = yy;
+}
+
+// Add to hash table, add event handler
+bool wxWindow::AttachWidget (wxWindow* parent, WXWidget mainWidget,
+ WXWidget formWidget, int x, int y, int width, int height)
+{
+ wxAddWindowToTable((Widget) mainWidget, this);
+ if (CanAddEventHandler())
+ {
+ XtAddEventHandler((Widget) mainWidget,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
+ False,
+ wxPanelItemEventHandler,
+ (XtPointer) this);
+ }
+
+ if (!formWidget)
+ {
+ XtTranslations ptr;
+ XtOverrideTranslations ((Widget) mainWidget,
+ ptr = XtParseTranslationTable ("<Configure>: resize()"));
+ XtFree ((char *) ptr);
+ }
+
+ // Some widgets have a parent form widget, e.g. wxRadioBox
+ if (formWidget)
+ {
+ if (!wxAddWindowToTable((Widget) formWidget, this))
+ return FALSE;
+
+ XtTranslations ptr;
+ XtOverrideTranslations ((Widget) formWidget,
+ ptr = XtParseTranslationTable ("<Configure>: resize()"));
+ XtFree ((char *) ptr);
+ }
+
+ if (x == -1)
+ x = 0;
+ if (y == -1)
+ y = 0;
+ SetSize (x, y, width, height);
+
+ return TRUE;
+}
+
+// Remove event handler, remove from hash table
+bool wxWindow::DetachWidget(WXWidget widget)
+{
+ if (CanAddEventHandler())
+ {
+ XtRemoveEventHandler((Widget) widget,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
+ False,
+ wxPanelItemEventHandler,
+ (XtPointer)this);
+ }
+
+ wxDeleteWindowFromTable((Widget) widget);
+ return TRUE;
+}
+
+void wxPanelItemEventHandler (Widget wid,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean *continueToDispatch)
+{
+ // Widget can be a label or the actual widget.
+
+ wxWindow *window = (wxWindow *)wxWidgetHashTable->Get((long)wid);
+ if (window)
+ {
+ wxMouseEvent wxevent(0);
+ if (wxTranslateMouseEvent(wxevent, window, wid, event))
+ {
+ window->GetEventHandler()->ProcessEvent(wxevent);
+ }
+ }
+ // TODO: probably the key to allowing default behaviour
+ // to happen.
+ // Say we set a m_doDefault flag to FALSE at the start of this
+ // function. Then in e.g. wxWindow::OnMouseEvent we can
+ // call Default() which sets this flag to TRUE, indicating
+ // that default processing can happen. Thus, behaviour can appear
+ // to be overridden just by adding an event handler and not calling
+ // wxWindow::OnWhatever.
+ // ALSO, maybe we can use this instead of the current way of handling
+ // drawing area events, to simplify things.
+ *continueToDispatch = True;
+}
+
+void wxScrollBarCallback(Widget scrollbar, XtPointer clientData,
+ XmScaleCallbackStruct *cbs)
+{
+ Widget scrolledWindow = XtParent (scrollbar);
+ wxWindow *win = (wxWindow *) wxWidgetHashTable->Get ((long) scrolledWindow);
+ int orientation = (int) clientData;
+
+ wxEventType eventType = wxEVT_NULL;
+ switch (cbs->reason)
+ {
+ case XmCR_INCREMENT:
+ {
+ eventType = wxEVT_SCROLL_LINEDOWN;
+ break;
+ }
+ case XmCR_DECREMENT:
+ {
+ eventType = wxEVT_SCROLL_LINEUP;
+ break;
+ }
+ case XmCR_DRAG:
+ {
+ eventType = wxEVT_SCROLL_THUMBTRACK;
+ break;
+ }
+ case XmCR_VALUE_CHANGED:
+ {
+ // TODO: Should this be intercepted too, or will it cause
+ // duplicate events?
+ eventType = wxEVT_SCROLL_THUMBTRACK;
+ break;
+ }
+ case XmCR_PAGE_INCREMENT:
+ {
+ eventType = wxEVT_SCROLL_PAGEDOWN;
+ break;
+ }
+ case XmCR_PAGE_DECREMENT:
+ {
+ eventType = wxEVT_SCROLL_PAGEUP;
+ break;
+ }
+ case XmCR_TO_TOP:
+ {
+ eventType = wxEVT_SCROLL_TOP;
+ break;
+ }
+ case XmCR_TO_BOTTOM:
+ {
+ eventType = wxEVT_SCROLL_BOTTOM;
+ break;
+ }
+ default:
+ {
+ // Should never get here
+ wxFAIL_MSG("Unknown scroll event.");
+ break;
+ }
+ }
+
+ wxScrollEvent event(eventType, win->GetId());
+ event.SetEventObject(win);
+ event.SetPosition(cbs->value);
+ event.SetOrientation( (orientation == XmHORIZONTAL) ? wxHORIZONTAL : wxVERTICAL );
+
+ win->GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent)
+{
+ switch (xevent->xany.type)
+ {
+ case EnterNotify:
+ case LeaveNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ {
+ wxEventType eventType = wxEVT_NULL;
+
+ if (xevent->xany.type == LeaveNotify)
+ {
+ win->m_button1Pressed = FALSE;
+ win->m_button2Pressed = FALSE;
+ win->m_button3Pressed = FALSE;
+ return FALSE;
+ }
+ else if (xevent->xany.type == MotionNotify)
+ {
+ eventType = wxEVT_MOTION;
+ }
+ else if (xevent->xany.type == ButtonPress)
+ {
+ if (xevent->xbutton.button == Button1)
+ {
+ eventType = wxEVT_LEFT_DOWN;
+ win->m_button1Pressed = TRUE;
+ }
+ else if (xevent->xbutton.button == Button2)
+ {
+ eventType = wxEVT_MIDDLE_DOWN;
+ win->m_button2Pressed = TRUE;
+ }
+ else if (xevent->xbutton.button == Button3)
+ {
+ eventType = wxEVT_RIGHT_DOWN;
+ win->m_button3Pressed = TRUE;
+ }
+ }
+ else if (xevent->xany.type == ButtonRelease)
+ {
+ if (xevent->xbutton.button == Button1)
+ {
+ eventType = wxEVT_LEFT_UP;
+ win->m_button1Pressed = FALSE;
+ }
+ else if (xevent->xbutton.button == Button2)
+ {
+ eventType = wxEVT_MIDDLE_UP;
+ win->m_button2Pressed = FALSE;
+ }
+ else if (xevent->xbutton.button == Button3)
+ {
+ eventType = wxEVT_RIGHT_UP;
+ win->m_button3Pressed = FALSE;
+ }
+ else return FALSE;
+ }
+ else return FALSE;
+
+ wxevent.m_eventHandle = (char *)xevent;
+ wxevent.SetEventType(eventType);
+
+ Position x1, y1;
+ XtVaGetValues(widget, XmNx, &x1, XmNy, &y1, NULL);
+
+ int x2, y2;
+ win->GetPosition(&x2, &y2);
+
+ // The button x/y must be translated to wxWindows
+ // window space - the widget might be a label or button,
+ // within a form.
+ int dx = 0;
+ int dy = 0;
+ if (widget != (Widget)win->GetMainWidget())
+ {
+ dx = x1;
+ dy = y1;
+ }
+
+ wxevent.m_x = xevent->xbutton.x + dx;
+ wxevent.m_y = xevent->xbutton.y + dy;
+
+ wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
+ || (event_left_is_down (xevent)
+ && (eventType != wxEVT_LEFT_UP)));
+ wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
+ || (event_middle_is_down (xevent)
+ && (eventType != wxEVT_MIDDLE_UP)));
+ wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
+ || (event_right_is_down (xevent)
+ && (eventType != wxEVT_RIGHT_UP)));
+
+ wxevent.m_shiftDown = xevent->xbutton.state & ShiftMask;
+ wxevent.m_controlDown = xevent->xbutton.state & ControlMask;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent)
+{
+ switch (xevent->xany.type)
+ {
+ case KeyPress:
+ {
+ char buf[20];
+
+ KeySym keySym;
+// XComposeStatus compose;
+// (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, &compose);
+ (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL);
+ int id = wxCharCodeXToWX (keySym);
+
+ if (xevent->xkey.state & ShiftMask)
+ wxevent.m_shiftDown = TRUE;
+ if (xevent->xkey.state & ControlMask)
+ wxevent.m_controlDown = TRUE;
+ if (xevent->xkey.state & Mod3Mask)
+ wxevent.m_altDown = TRUE;
+ if (xevent->xkey.state & Mod1Mask)
+ wxevent.m_metaDown = TRUE;
+ wxevent.SetEventObject(win);
+ wxevent.m_keyCode = id;
+ wxevent.SetTimestamp(xevent->xkey.time);
+
+ wxevent.m_x = xevent->xbutton.x;
+ wxevent.m_y = xevent->xbutton.y;
+
+ if (id > -1)
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ }
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+// TODO From wxWin 1.68. What does it do exactly?
+#define YAllocColor XAllocColor
+
+XColor itemColors[5];
+int wxComputeColors (Display *display, wxColour * back, wxColour * fore)
+{
+ int result;
+ static XmColorProc colorProc;
+
+ result = wxNO_COLORS;
+
+ if (back)
+ {
+ itemColors[0].red = (((long) back->Red ()) << 8);
+ itemColors[0].green = (((long) back->Green ()) << 8);
+ itemColors[0].blue = (((long) back->Blue ()) << 8);
+ itemColors[0].flags = DoRed | DoGreen | DoBlue;
+ if (colorProc == (XmColorProc) NULL)
+ {
+ // Get a ptr to the actual function
+ colorProc = XmSetColorCalculation ((XmColorProc) NULL);
+ // And set it back to motif.
+ XmSetColorCalculation (colorProc);
+ }
+ (*colorProc) (&itemColors[wxBACK_INDEX],
+ &itemColors[wxFORE_INDEX],
+ &itemColors[wxSELE_INDEX],
+ &itemColors[wxTOPS_INDEX],
+ &itemColors[wxBOTS_INDEX]);
+ result = wxBACK_COLORS;
+ }
+ if (fore)
+ {
+ itemColors[wxFORE_INDEX].red = (((long) fore->Red ()) << 8);
+ itemColors[wxFORE_INDEX].green = (((long) fore->Green ()) << 8);
+ itemColors[wxFORE_INDEX].blue = (((long) fore->Blue ()) << 8);
+ itemColors[wxFORE_INDEX].flags = DoRed | DoGreen | DoBlue;
+ if (result == wxNO_COLORS)
+ result = wxFORE_COLORS;
+ }
+
+ Display *dpy = display;
+ Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
+
+ if (back)
+ {
+ /* 5 Colours to allocate */
+ for (int i = 0; i < 5; i++)
+ if (!YAllocColor (dpy, cmap, &itemColors[i]))
+ result = wxNO_COLORS;
+ }
+ else if (fore)
+ {
+ /* Only 1 colour to allocate */
+ if (!YAllocColor (dpy, cmap, &itemColors[wxFORE_INDEX]))
+ result = wxNO_COLORS;
+ }
+
+ return (result);
+
+}
+
+void wxWindow::ChangeColour(WXWidget widget)
+{
+ // TODO
+#if 0
+ int change;
+
+ // TODO: how to determine whether we can change this item's colours?
+ // We used to have wxUSER_COLOURS. Now perhaps we assume we always
+ // can change it.
+ // if (!(parent->GetWindowStyleFlag() & wxUSER_COLOURS))
+ // return;
+
+ change = wxComputeColors (XtDisplay((Widget)widget), panel->GetBackgroundColour(),
+ panel->GetLabelColour());
+ if (change == wxBACK_COLORS)
+ XtVaSetValues ((Widget) widget,
+ XmNbackground, itemColors[wxBACK_INDEX].pixel,
+ XmNtopShadowColor, itemColors[wxTOPS_INDEX].pixel,
+ XmNbottomShadowColor, itemColors[wxBOTS_INDEX].pixel,
+ XmNforeground, itemColors[wxFORE_INDEX].pixel,
+ NULL);
+ else if (change == wxFORE_COLORS)
+ XtVaSetValues (formWidget,
+ XmNforeground, itemColors[wxFORE_INDEX].pixel,
+ NULL);
+
+ change = wxComputeColors (XtDisplay((Widget)formWidget), GetBackgroundColour(), GetLabelColour());
+ if (change == wxBACK_COLORS)
+ XtVaSetValues (labelWidget,
+ XmNbackground, itemColors[wxBACK_INDEX].pixel,
+ XmNtopShadowColor, itemColors[wxTOPS_INDEX].pixel,
+ XmNbottomShadowColor, itemColors[wxBOTS_INDEX].pixel,
+ XmNarmColor, itemColors[wxSELE_INDEX].pixel,
+ XmNforeground, itemColors[wxFORE_INDEX].pixel,
+ NULL);
+ else if (change == wxFORE_COLORS)
+ XtVaSetValues (labelWidget,
+ XmNforeground, itemColors[wxFORE_INDEX].pixel,
+ NULL);
+#endif
+}
+
+void wxWindow::ChangeFont(WXWidget widget)
+{
+ /*
+ if (widget && GetFont() && GetFont()->Ok())
+ {
+ XmFontList fontList = (XmFontList) GetFont()->GetFontList(1.0, GetXDisplay());
+ if (fontList)
+ XtVaSetValues ((Widget) widget,
+ XmNfontList, fontList,
+ NULL);
+ }
+ */
}