#include "wx/settings.h"
#include "wx/msgdlg.h"
#include "wx/frame.h"
+#include "wx/scrolwin.h"
#include "wx/menuitem.h"
#include "wx/log.h"
wxWindow::wxWindow()
{
// Generic
+ m_isWindow = TRUE; // An optimization
m_windowId = 0;
m_windowStyle = 0;
m_windowParent = NULL;
m_clientData = NULL;
/// Motif-specific
+ m_needsRefresh = TRUE;
m_mainWidget = (WXWidget) 0;
m_button1Pressed = FALSE;
m_button2Pressed = FALSE;
// Destroy the window
if (GetMainWidget())
{
- wxDeleteWindowFromTable((Widget) GetMainWidget());
+ // If this line (XtDestroyWidget) causes a crash, you may comment it out.
+ // Child widgets will get destroyed automatically when a frame
+ // or dialog is destroyed, but before that you may get some memory
+ // leaks and potential layout problems if you delete and then add
+ // child windows.
XtDestroyWidget((Widget) GetMainWidget());
SetMainWidget((WXWidget) NULL);
}
const wxString& name)
{
// Generic
+ m_isWindow = TRUE; // An optimization
m_windowId = 0;
m_windowStyle = 0;
m_windowParent = NULL;
m_clientData = NULL;
// Motif-specific
+ m_needsRefresh = TRUE;
m_canAddEventHandler = FALSE;
m_mainWidget = (WXWidget) 0;
m_button1Pressed = FALSE;
*x = xx; *y = yy;
}
-void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
+void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
// A bit of optimization to help sort out the flickers.
int oldX, oldY, oldW, oldH;
*/
}
-void wxWindow::SetClientSize(int width, int height)
+void wxWindow::DoSetClientSize(int width, int height)
{
if (m_drawingArea)
{
void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
{
+ m_needsRefresh = TRUE;
Display *display = XtDisplay((Widget) GetMainWidget());
Window thisWindow = XtWindow((Widget) GetMainWidget());
delete rect;
node = node->Next();
}
-
+
+ XmUpdateDisplay((Widget) GetMainWidget());
}
void wxWindow::OnChar(wxKeyEvent& event)
{
+ event.Skip();
/* ??
if ( event.KeyCode() == WXK_TAB ) {
// propagate the TABs to the parent - it's up to it to decide what
void wxWindow::OnKeyDown(wxKeyEvent& event)
{
- Default();
+ event.Skip();
}
void wxWindow::OnKeyUp(wxKeyEvent& event)
{
- Default();
+ event.Skip();
}
void wxWindow::OnPaint(wxPaintEvent& event)
// Get the window with the focus
wxWindow *wxWindow::FindFocus()
{
- // TODO
- return NULL;
+ // TODO Problems:
+ // (1) Can there be multiple focussed widgets in an application?
+ // In which case we need to find the top-level window that's
+ // currently active.
+ // (2) The widget with the focus may not be in the widget table
+ // depending on which widgets I put in the table
+
+ wxNode *node = wxTopLevelWindows.First();
+ while (node)
+ {
+ wxWindow *win = (wxWindow *)node->Data();
+
+ Widget w = XmGetFocusWidget ((Widget) win->GetTopWidget()) ;
+
+ if (w != (Widget) NULL)
+ {
+ wxWindow* focusWin = wxGetWindowFromTable(w);
+ if (focusWin)
+ return focusWin;
+ }
+
+ node = node->Next();
+ }
+ return (wxWindow*) NULL;
}
void wxWindow::AddChild(wxWindow *child)
{
wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
event.SetEventObject(this);
+#if WXWIN_COMPATIBILITY
event.SetForce(force);
+#endif
+ event.SetCanVeto(!force);
return GetEventHandler()->ProcessEvent(event);
}
{
if ( m_windowValidator )
delete m_windowValidator;
- m_windowValidator = validator.Clone();
+ m_windowValidator = (wxValidator*) validator.Clone();
if ( m_windowValidator )
m_windowValidator->SetWindow(this) ;
// Get the underlying X window and display
WXWindow wxWindow::GetXWindow() const
{
- return (WXWindow) XtWindow((Widget) GetMainWidget());
+ if (GetMainWidget())
+ return (WXWindow) XtWindow((Widget) GetMainWidget());
+ else
+ return (WXWindow) 0;
}
WXDisplay *wxWindow::GetXDisplay() const
{
- return (WXDisplay*) XtDisplay((Widget) GetMainWidget());
+ if (GetMainWidget())
+ return (WXDisplay*) XtDisplay((Widget) GetMainWidget());
+ else
+ return (WXDisplay*) NULL;
}
WXWidget wxWindow::GetMainWidget() const
if (event -> xexpose.count == 0)
{
+ /*
wxPaintEvent event(win->GetId());
event.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(event);
+ */
+ win->DoPaint();
win->ClearUpdateRects();
}
break;
wxEventType eventType = wxEVT_CHAR;
- // TODO: Is this the correct criterion for wxEVT_KEY_DOWN down versus wxEVT_CHAR?
- if (id > WXK_START) // Non-ASCII values
- eventType = wxEVT_KEY_DOWN;
-
wxKeyEvent event (eventType);
if (local_event.xkey.state & ShiftMask)
event.SetEventType(wxEVT_CHAR_HOOK);
if (parent->GetEventHandler()->ProcessEvent(event))
return;
- event.SetEventType(wxEVT_CHAR);
}
-
- canvas->GetEventHandler()->ProcessEvent (event);
+
+ // For simplicity, OnKeyDown is the same as OnChar
+ // TODO: filter modifier key presses from OnChar
+ event.SetEventType(wxEVT_KEY_DOWN);
+
+ // Only process OnChar if OnKeyDown didn't swallow it
+ if (!canvas->GetEventHandler()->ProcessEvent (event))
+ {
+ event.SetEventType(wxEVT_CHAR);
+ canvas->GetEventHandler()->ProcessEvent (event);
+ }
}
break;
}
void wxWindow::DoPaint()
{
//TODO : make a temporary gc so we can do the XCopyArea below
- if (0) // m_backingPixmap)
+ if (m_backingPixmap && !m_needsRefresh)
{
- /*
- Widget drawingArea = (Widget) m_drawingArea;
- // int orig = GetDC()->GetLogicalFunction();
- // GetDC()->SetLogicalFunction (wxCOPY);
-
- // TODO: it may not be necessary to store m_pixmapOffsetX/Y; we
- // should be able to calculate them.
- XCopyArea (XtDisplay (drawingArea), m_backingPixmap, XtWindow (drawingArea), GetDC ()->gc,
- m_pixmapOffsetX, m_pixmapOffsetY,
- m_pixmapWidth, m_pixmapHeight,
- 0, 0);
-
- // GetDC()->SetLogicalFunction (orig);
- */
+ wxPaintDC dc(this);
+
+ GC tempGC = (GC) dc.GetBackingGC();
+
+ Widget widget = (Widget) GetMainWidget();
+
+ int scrollPosX = 0;
+ int scrollPosY = 0;
+
+ // We have to test whether it's a wxScrolledWindow (hack!)
+ // because otherwise we don't know how many pixels have been
+ // scrolled. We might solve this in the future by defining
+ // virtual wxWindow functions to get the scroll position in pixels.
+ // Or, each kind of scrolled window has to implement backing
+ // stores itself, using generic wxWindows code.
+ if (this->IsKindOf(CLASSINFO(wxScrolledWindow)))
+ {
+ wxScrolledWindow* scrolledWindow = (wxScrolledWindow*) this;
+ int x, y;
+ scrolledWindow->CalcScrolledPosition(0, 0, & x, & y);
+
+ scrollPosX = - x;
+ scrollPosY = - y;
+ }
+
+ // TODO: This could be optimized further by only copying the
+ // areas in the current update region.
+
+ // Only blit the part visible in the client area. The backing pixmap
+ // always starts at 0, 0 but we may be looking at only a portion of it.
+ wxSize clientArea = GetClientSize();
+ int toBlitX = m_pixmapWidth - scrollPosX;
+ int toBlitY = m_pixmapHeight - scrollPosY;
+
+ // Copy whichever is samller, the amount of pixmap we have to copy,
+ // or the size of the client area.
+ toBlitX = wxMin(toBlitX, clientArea.x);
+ toBlitY = wxMin(toBlitY, clientArea.y);
+
+ // Make sure we're not negative
+ toBlitX = wxMax(0, toBlitX);
+ toBlitY = wxMax(0, toBlitY);
+
+ XCopyArea (XtDisplay (widget), (Pixmap) m_backingPixmap, XtWindow (widget), tempGC,
+ scrollPosX, scrollPosY, // Start at the scroll position
+ toBlitX, toBlitY, // How much of the pixmap to copy
+ 0, 0); // Destination
}
else
{
+ // Set an erase event first
+ wxEraseEvent eraseEvent(GetId());
+ eraseEvent.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(eraseEvent);
+
wxPaintEvent event(GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
+
+ m_needsRefresh = FALSE;
}
}
ChangeFont();
}
+void wxWindow::SetToolTip(const wxString& tooltip)
+{
+ // TODO
+}
+
void wxWindow::ClearUpdateRects()
{
wxNode* node = m_updateRects.First();
return (m_count == 0);
}
+// For repainting arbitrary windows
+void wxUniversalRepaintProc(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)
+ {
+ win->DoPaint();
+
+ win->ClearUpdateRects();
+ }
+ break;
+ }
+ default :
+ {
+ cout << "\n\nNew Event ! is = " << event -> type << "\n";
+ break;
+ }
+ }
+}
+