From: Julian Smart Date: Thu, 12 Nov 1998 22:47:51 +0000 (+0000) Subject: Accelerators implemented for wxMotif; some wxComboBox stupidities cured X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/8aa04e8bf1638ed4d9355e560c8d718c8be4667a Accelerators implemented for wxMotif; some wxComboBox stupidities cured git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@995 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/motif/changes.txt b/docs/motif/changes.txt index 561b69716e..4ada41c3b9 100644 --- a/docs/motif/changes.txt +++ b/docs/motif/changes.txt @@ -11,3 +11,26 @@ Julian: - First go at wxApp, wxWindow, wxDialog, wxPen, wxBrush, wxFont, wxColour, wxButton, wxCheckBox, wxTextCtrl, wxStaticText, wxMenu, wxMenuItem, wxMenuBar + +12/11/98 +-------- + +It's a long time since I updated this file. Previously done: + +- wxFrame, wxDialog done. +- wxScrolledWindow done (but backing pixmap not used at present). +- wxBitmap done though could be tidied it up at some point. +- Most basic controls are there, if not rigorously tested. +- Some MDI support (menus appear on child frames at present). +- wxNotebook almost done. +- wxToolBar done (horizontal only, which would be easy to extend + to vertical toolbars). + +More recently: + +- Colour and font changing done (question mark over what happens + to scrollbars). +- Accelerators done (for menu items and buttons). Also event loop + tidied up in wxApp so that events are filtered through ProcessXEvent. +- wxWindow::GetUpdateRegion should now work. + diff --git a/docs/motif/todo.txt b/docs/motif/todo.txt index 0aaab0544d..e717d2aa19 100644 --- a/docs/motif/todo.txt +++ b/docs/motif/todo.txt @@ -1,7 +1,7 @@ wxMotif TODO ------------ -Updated: 9/11/98 +Updated: 12/11/98 -------------------------------o------------------------- @@ -21,10 +21,10 @@ High Priority so maybe have wxSystemSettings value for scrollbar colour, and/or ability to set scrollbar colour independently. -- Make wxDialog OnPaint work. - -- Optimize wxWindow OnPaint, clipping the damaged - region. +- Optimize wxWindow OnPaint to avoid flicker, collapsing Expose events + as per flicker fix in 1.68. It will be tricky to avoid + interfering with non-wxScrolledWindow widgets except by + explicitly testing for wxScrolledWindow. - Implementation of OnEraseBackground. How? Call OnEraseBackground just before OnPaint? Will duplicate Xlib's own erase of the background. @@ -35,6 +35,8 @@ High Priority painting a tiled bitmap, then a slight flicker might be seen unless X can be persuaded not to repaint the window background by default. +- Finish wxNotebook. + - wxSpinButton - Tidy dialogs such as the colour and font selectors. @@ -49,7 +51,7 @@ High Priority - wxThread (hopefully, similar to wxGTK) -- wxAcceleratorTable. +- wxGrid: scrollbars don't hide; problem with cell selection. - Miscellaneous events. @@ -93,10 +95,6 @@ Low Priority - add the driver code to src/motif/helphtml.cpp (a frame, toolbar, history list). - Note that a quicker route to a help system may be to use the - code in the contrib dir of XmHTML to control a Netscape session -- - but Netscape can be a colour resource hog. - - Optimize screen refresh for non-native widgets, e.g. wxWindow created with Create(), using technique in flicker patch for 1.68 (see JACS for latest patch). diff --git a/include/wx/generic/helpext.h b/include/wx/generic/helpext.h index 4b3c52c0b4..0ee2fa51b4 100644 --- a/include/wx/generic/helpext.h +++ b/include/wx/generic/helpext.h @@ -14,6 +14,8 @@ # pragma interface "wxexthlp.h" #endif +#include "wx/helpbase.h" + /// Name for map file. #define WXEXTHELP_MAPFILE "wxhelp.map" /// Path separator. diff --git a/include/wx/motif/accel.h b/include/wx/motif/accel.h index 3e8da6784a..cd08c75f1d 100644 --- a/include/wx/motif/accel.h +++ b/include/wx/motif/accel.h @@ -18,6 +18,7 @@ #include "wx/object.h" #include "wx/string.h" +#include "wx/event.h" class WXDLLEXPORT wxAcceleratorTable; @@ -31,11 +32,15 @@ class WXDLLEXPORT wxAcceleratorTable; #define wxACCEL_SHIFT 0x04 // Hold no key down -#define wxACCEL_NONE 0x00 +#define wxACCEL_NORMAL 0x00 class WXDLLEXPORT wxAcceleratorEntry { public: + wxAcceleratorEntry(const wxAcceleratorEntry& entry) + { + m_flags = entry.m_flags; m_keyCode = entry.m_keyCode; m_command = entry.m_command; + } wxAcceleratorEntry(int flags = 0, int keyCode = 0, int cmd = 0) { m_flags = flags; m_keyCode = keyCode; m_command = cmd; @@ -48,6 +53,15 @@ public: inline int GetKeyCode() const { return m_keyCode; } inline int GetCommand() const { return m_command; } + void operator = (const wxAcceleratorEntry& entry) + { + m_flags = entry.m_flags; m_keyCode = entry.m_keyCode; m_command = entry.m_command; + } + + // Implementation use only + bool MatchesEvent(const wxKeyEvent& event) const; + +public: int m_flags; int m_keyCode; // ASCII or virtual keycode int m_command; // Command id to generate @@ -72,6 +86,10 @@ public: inline bool operator != (const wxAcceleratorTable& accel) { return m_refData != accel.m_refData; } bool Ok() const; + +// Implementation only + int GetCount() const; + wxAcceleratorEntry* GetEntries() const; }; WXDLLEXPORT_DATA(extern wxAcceleratorTable) wxNullAcceleratorTable; diff --git a/include/wx/motif/app.h b/include/wx/motif/app.h index c36e03233d..5cbe5267fa 100644 --- a/include/wx/motif/app.h +++ b/include/wx/motif/app.h @@ -107,6 +107,14 @@ class WXDLLEXPORT wxApp: public wxEvtHandler // Creates a log object virtual wxLog* CreateLogTarget(); +// Motif implementation. + + // Processes an X event. + virtual void ProcessXEvent(WXEvent* event); + + // Returns TRUE if an accelerator has been processed + virtual bool CheckForAccelerator(WXEvent* event); + public: // Will always be set to the appropriate, main-style values. int argc; diff --git a/include/wx/motif/combobox.h b/include/wx/motif/combobox.h index 0948077c71..d0ccd9e884 100644 --- a/include/wx/motif/combobox.h +++ b/include/wx/motif/combobox.h @@ -28,6 +28,7 @@ class WXDLLEXPORT wxComboBox: public wxChoice public: inline wxComboBox() {} + ~wxComboBox(); inline wxComboBox(wxWindow *parent, wxWindowID id, const wxString& value = wxEmptyString, @@ -50,8 +51,20 @@ class WXDLLEXPORT wxComboBox: public wxChoice const wxValidator& validator = wxDefaultValidator, const wxString& name = wxComboBoxNameStr); - // List functions: see wxChoice - + virtual void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); + + // List functions + virtual void Append(const wxString& item); + virtual void Delete(int n); + virtual void Clear(); + virtual int GetSelection() const ; + virtual void SetSelection(int n); + virtual int FindString(const wxString& s) const; + virtual wxString GetString(int n) const ; + virtual wxString GetStringSelection() const ; + virtual bool SetStringSelection(const wxString& sel); + virtual inline int Number() const { return m_noStrings; } + // Text field functions virtual wxString GetValue() const ; virtual void SetValue(const wxString& value); @@ -66,10 +79,6 @@ class WXDLLEXPORT wxComboBox: public wxChoice virtual long GetLastPosition() const ; virtual void Replace(long from, long to, const wxString& value); virtual void Remove(long from, long to); - virtual void SetSelection(int n) - { - wxChoice::SetSelection(n); - } virtual void SetSelection(long from, long to); virtual void SetEditable(bool editable); @@ -77,6 +86,8 @@ class WXDLLEXPORT wxComboBox: public wxChoice virtual void ChangeFont(bool keepOriginalSize = TRUE); virtual void ChangeBackgroundColour(); virtual void ChangeForegroundColour(); + WXWidget GetTopWidget() const { return m_mainWidget; } + WXWidget GetMainWidget() const { return m_mainWidget; } }; #endif diff --git a/include/wx/motif/scrolbar.h b/include/wx/motif/scrolbar.h index 63bc35f17d..e7881e617d 100644 --- a/include/wx/motif/scrolbar.h +++ b/include/wx/motif/scrolbar.h @@ -66,7 +66,7 @@ protected: int m_viewSize; int m_objectSize; -DECLARE_EVENT_TABLE() +// DECLARE_EVENT_TABLE() }; #endif diff --git a/include/wx/motif/window.h b/include/wx/motif/window.h index 6f72b72742..06f9f56d99 100644 --- a/include/wx/motif/window.h +++ b/include/wx/motif/window.h @@ -539,6 +539,20 @@ public: // Generates a paint event virtual void DoPaint(); + // How to implement accelerators. If we find a key event, + // translate to wxWindows wxKeyEvent form. Find a widget for the window. + // Now find a wxWindow for the widget. If there isn't one, go up the widget hierarchy + // trying to find one. Once one is found, call ProcessAccelerator for the + // window. If it returns TRUE (processed the event), skip the X event, + // otherwise carry on up the wxWindows window hierarchy calling ProcessAccelerator. + // If all return FALSE, process the X event as normal. + // Eventually we can implement OnCharHook the same way, but concentrate on accelerators + // for now. + // ProcessAccelerator must look at the current accelerator table, and try to find + // what menu id or window (beneath it) has this ID. Then construct an appropriate command + // event and send it. + virtual bool ProcessAccelerator(wxKeyEvent& event); + //////////////////////////////////////////////////////////////////////// //// PROTECTED DATA protected: diff --git a/include/wx/stubs/accel.h b/include/wx/stubs/accel.h index 10e43ef5e8..ec39737483 100644 --- a/include/wx/stubs/accel.h +++ b/include/wx/stubs/accel.h @@ -31,7 +31,7 @@ class WXDLLEXPORT wxAcceleratorTable; #define wxACCEL_SHIFT 0x04 // Hold no key down -#define wxACCEL_NONE 0x00 +#define wxACCEL_NORMAL 0x00 class WXDLLEXPORT wxAcceleratorEntry { diff --git a/include/wx/stubs/combobox.h b/include/wx/stubs/combobox.h index 86895e561c..07054af74e 100644 --- a/include/wx/stubs/combobox.h +++ b/include/wx/stubs/combobox.h @@ -50,7 +50,17 @@ class WXDLLEXPORT wxComboBox: public wxChoice const wxValidator& validator = wxDefaultValidator, const wxString& name = wxComboBoxNameStr); - // List functions: see wxChoice + // List functions + virtual void Append(const wxString& item); + virtual void Delete(int n); + virtual void Clear(); + virtual int GetSelection() const ; + virtual void SetSelection(int n); + virtual int FindString(const wxString& s) const; + virtual wxString GetString(int n) const ; + virtual wxString GetStringSelection() const ; + virtual bool SetStringSelection(const wxString& sel); + virtual inline int Number() const { return m_noStrings; } // Text field functions virtual wxString GetValue() const ; @@ -66,10 +76,6 @@ class WXDLLEXPORT wxComboBox: public wxChoice virtual long GetLastPosition() const ; virtual void Replace(long from, long to, const wxString& value); virtual void Remove(long from, long to); - virtual void SetSelection(int n) - { - wxChoice::SetSelection(n); - } virtual void SetSelection(long from, long to); virtual void SetEditable(bool editable); }; diff --git a/src/generic/gridg.cpp b/src/generic/gridg.cpp index 4b639f1e51..24554d3133 100644 --- a/src/generic/gridg.cpp +++ b/src/generic/gridg.cpp @@ -45,10 +45,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid, wxPanel) BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel) - EVT_SIZE(wxGenericGrid::OnSize) - EVT_PAINT(wxGenericGrid::OnPaint) - EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground) - EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent) + EVT_SIZE(wxGenericGrid::OnSize) + EVT_PAINT(wxGenericGrid::OnPaint) + EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground) + EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent) EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText) EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll) EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll) @@ -898,15 +898,6 @@ void wxGenericGrid::AdjustScrollbars(void) int cw, ch; GetClientSize(&cw, &ch); - // To calculate the number of steps for each scrollbar, - // we need to see how much will fit onto the canvas - // at the present size. So: - // 1) Find the *last* row r1 such that when it's at the top of the - // window, all the remaining rows are visible. - // 2) There should therefore be r1 - 1 steps in the scrollbar. - // Similarly with columns. - - // IGNORE THE ABOVE, it's crap. // We find the view size by seeing how many rows/cols fit on // the current view. // BUT... this means that the scrollbar should be adjusted every time @@ -933,10 +924,6 @@ void wxGenericGrid::AdjustScrollbars(void) { noHorizSteps = 0; int widthCount = 0; -/* - if (GetLabelSize(wxVERTICAL) > 0) - noHorizSteps ++; -*/ int i; int nx = 0; @@ -960,10 +947,6 @@ void wxGenericGrid::AdjustScrollbars(void) { noVertSteps = 0; int heightCount = 0; -/* - if (GetLabelSize(wxHORIZONTAL) > 0) - noVertSteps ++; -*/ int i; int ny = 0; @@ -989,20 +972,20 @@ void wxGenericGrid::AdjustScrollbars(void) } else { - if ( m_hScrollBar ) - m_hScrollBar->Show(TRUE); + if ( m_hScrollBar ) + m_hScrollBar->Show(TRUE); } if (m_totalGridHeight + horizScrollBarHeight <= ch) { - if ( m_vScrollBar ) - m_vScrollBar->Show(FALSE); - SetScrollPosY(0); + if ( m_vScrollBar ) + m_vScrollBar->Show(FALSE); + SetScrollPosY(0); } else { - if ( m_vScrollBar ) - m_vScrollBar->Show(TRUE); + if ( m_vScrollBar ) + m_vScrollBar->Show(TRUE); } UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed @@ -1017,12 +1000,7 @@ void wxGenericGrid::AdjustScrollbars(void) if (m_hScrollBar) { int nCols = GetCols(); -/* - m_hScrollBar->SetPageSize(wxMax(noHorizSteps, 1)); - m_hScrollBar->SetViewLength(wxMax(noHorizSteps, 1)); - m_hScrollBar->SetObjectLength(nCols); -*/ - m_hScrollBar->SetScrollbar(m_hScrollBar->GetPosition(), wxMax(noHorizSteps, 1), nCols, wxMax(noHorizSteps, 1)); + m_hScrollBar->SetScrollbar(m_hScrollBar->GetPosition(), wxMax(noHorizSteps, 1), (noHorizSteps == 0) ? 1 : nCols, wxMax(noHorizSteps, 1)); m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth); @@ -1031,13 +1009,8 @@ void wxGenericGrid::AdjustScrollbars(void) if (m_vScrollBar) { int nRows = GetRows(); -/* - m_vScrollBar->SetPageSize(wxMax(noVertSteps, 1)); - m_vScrollBar->SetViewLength(wxMax(noVertSteps, 1)); - m_vScrollBar->SetObjectLength(nRows); -*/ - m_vScrollBar->SetScrollbar(m_vScrollBar->GetPosition(), wxMax(noVertSteps, 1), nRows, wxMax(noVertSteps, 1)); + m_vScrollBar->SetScrollbar(m_vScrollBar->GetPosition(), wxMax(noVertSteps, 1), (noVertSteps == 0) ? 1 : nRows, wxMax(noVertSteps, 1)); m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet, m_scrollWidth, ch - m_topOfSheet - horizScrollBarHeight); } @@ -2444,6 +2417,7 @@ void wxGenericGrid::OnGridScroll(wxScrollEvent& ev) } win->UpdateDimensions(); + win->SetCurrentRect(win->GetCursorRow(), win->GetCursorColumn()); // Because rows and columns can be arbitrary sizes, diff --git a/src/motif/accel.cpp b/src/motif/accel.cpp index 463102260b..ca8624f3e7 100644 --- a/src/motif/accel.cpp +++ b/src/motif/accel.cpp @@ -16,6 +16,8 @@ #include "wx/setup.h" #include "wx/accel.h" #include "wx/string.h" +#include "wx/utils.h" +#include #if !USE_SHARED_LIBRARIES IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject) @@ -28,66 +30,89 @@ public: wxAcceleratorRefData(); ~wxAcceleratorRefData(); -/* TODO: implementation - inline HACCEL GetHACCEL() const { return m_hAccel; } -protected: - HACCEL m_hAccel; -*/ +public: + int m_count; + wxAcceleratorEntry* m_entries; }; #define M_ACCELDATA ((wxAcceleratorRefData *)m_refData) wxAcceleratorRefData::wxAcceleratorRefData() { - // TODO -/* - HACCEL m_hAccel; -*/ + m_count = 0; + m_entries = (wxAcceleratorEntry*) NULL; } wxAcceleratorRefData::~wxAcceleratorRefData() { -/* - if (m_hAccel) - { - DestroyAcceleratorTable((HACCEL) m_hAccel); - } - m_hAccel = 0 ; -*/ + delete[] m_entries; + m_entries = (wxAcceleratorEntry*) NULL; + m_count = 0; } wxAcceleratorTable::wxAcceleratorTable() { - m_refData = NULL; + m_refData = (wxAcceleratorRefData*) NULL; } wxAcceleratorTable::~wxAcceleratorTable() { + // Data deleted in ~wxObject } // Load from .rc resource wxAcceleratorTable::wxAcceleratorTable(const wxString& resource) { m_refData = new wxAcceleratorRefData; - -/* TODO: load acelerator from resource, if appropriate for your platform - M_ACCELDATA->m_hAccel = hAccel; - M_ACCELDATA->m_ok = (hAccel != 0); -*/ } // Create from an array wxAcceleratorTable::wxAcceleratorTable(int n, wxAcceleratorEntry entries[]) { - m_refData = new wxAcceleratorRefData; + wxAcceleratorRefData* data = new wxAcceleratorRefData; + m_refData = data; + + data->m_count = n; + data->m_entries = new wxAcceleratorEntry[n]; + int i; + for (i = 0; i < n; i++) + data->m_entries[i] = entries[i]; -/* TODO: create table from entries - */ } bool wxAcceleratorTable::Ok() const { - // TODO - return FALSE; + return (m_refData != (wxAcceleratorRefData*) NULL); +} + +int wxAcceleratorTable::GetCount() const +{ + return M_ACCELDATA->m_count; +} + +wxAcceleratorEntry* wxAcceleratorTable::GetEntries() const +{ + return M_ACCELDATA->m_entries; +} + +// Implementation use only +bool wxAcceleratorEntry::MatchesEvent(const wxKeyEvent& event) const +{ + bool eventAltDown = event.AltDown(); + bool eventCtrlDown = event.ControlDown(); + bool eventShiftDown = event.ShiftDown(); + int eventKeyCode = event.KeyCode(); + + bool accAltDown = ((GetFlags() & wxACCEL_ALT) == wxACCEL_ALT); + bool accCtrlDown = ((GetFlags() & wxACCEL_CTRL) == wxACCEL_CTRL); + bool accShiftDown = ((GetFlags() & wxACCEL_SHIFT) == wxACCEL_SHIFT); + int accKeyCode = GetKeyCode(); + int accKeyCode2 = GetKeyCode(); + if (isascii(accKeyCode2)) + accKeyCode2 = wxToLower(accKeyCode2); + + return ((eventAltDown == accAltDown) && (eventCtrlDown == accCtrlDown) && + (eventShiftDown == accShiftDown) && + ((eventKeyCode == accKeyCode || eventKeyCode == accKeyCode2))) ; } diff --git a/src/motif/app.cpp b/src/motif/app.cpp index bd0acfb2d8..8c006f4e9a 100644 --- a/src/motif/app.cpp +++ b/src/motif/app.cpp @@ -281,34 +281,53 @@ int wxApp::MainLoop() while (m_keepGoing) { XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &event); - if(event.type == PropertyNotify) - { - HandlePropertyChange((WXEvent*) &event); - } else - { - // Terry Gitnick - 1/21/98 - /* if resize event, don't resize until the last resize event for this - window is recieved. Prevents flicker as windows are resized. */ - if (event.type == ResizeRequest) - { - Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget()); - Window win = event.xany.window; - XEvent report; + + ProcessXEvent((WXEvent*) & event); + ProcessIdle(); + } + + return 0; +} + +// Processes an X event. +void wxApp::ProcessXEvent(WXEvent* _event) +{ + XEvent* event = (XEvent*) _event; + + if (CheckForAccelerator(_event)) + { + // Do nothing! We intercepted and processed the event as an accelerator. + return; + } + else if (event->type == PropertyNotify) + { + HandlePropertyChange(_event); + return; + } + else if (event->type == ResizeRequest) + { + /* Terry Gitnick - 1/21/98 + * If resize event, don't resize until the last resize event for this + * window is recieved. Prevents flicker as windows are resized. + */ + + Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget()); + Window win = event->xany.window; + XEvent report; - // to avoid flicker - report = event; - while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report)); - } + // to avoid flicker + report = * event; + while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report)); + // TODO: when implementing refresh optimization, we can use // XtAddExposureToRegion to expand the window's paint region. - XtDispatchEvent(&event); - - ProcessIdle(); - } + XtDispatchEvent(event); + } + else + { + XtDispatchEvent(event); } - - return 0; } // Returns TRUE if more time is needed. @@ -330,13 +349,20 @@ void wxApp::ExitMainLoop() bool wxApp::Pending() { XFlush(XtDisplay( (Widget) wxTheApp->GetTopLevelWidget() )); - return (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) != 0) ; + + // Fix by Doug from STI, to prevent a stall if non-X event + // is found. + return ((XtAppPending( (XtAppContext) GetAppContext() ) & XtIMXEvent) != 0) ; } // Dispatch a message. void wxApp::Dispatch() { - XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll); +// XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll); + + XEvent event; + XtAppNextEvent((XtAppContext) GetAppContext(), &event); + ProcessXEvent((WXEvent*) & event); } // This should be redefined in a derived class for @@ -496,6 +522,41 @@ WXColormap wxApp::GetMainColormap(WXDisplay* display) return (WXColormap) c; } +// Returns TRUE if an accelerator has been processed +bool wxApp::CheckForAccelerator(WXEvent* event) +{ + XEvent* xEvent = (XEvent*) event; + if (xEvent->xany.type == KeyPress) + { + // Find a wxWindow for this window + // TODO: should get display for the window, not the current display + Widget widget = XtWindowToWidget((Display*) wxGetDisplay(), xEvent->xany.window); + wxWindow* win = NULL; + + // Find the first wxWindow that corresponds to this event window + while (widget && !(win = wxGetWindowFromTable(widget))) + widget = XtParent(widget); + + if (!widget || !win) + return FALSE; + + wxKeyEvent keyEvent(wxEVT_CHAR); + wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent); + + // Now we have a wxKeyEvent and we have a wxWindow. + // Go up the hierarchy until we find a matching accelerator, + // or we get to the top. + while (win) + { + if (win->ProcessAccelerator(keyEvent)) + return TRUE; + win = win->GetParent(); + } + return FALSE; + } + return FALSE; +} + void wxExit() { int retValue = 0; diff --git a/src/motif/choice.cpp b/src/motif/choice.cpp index a70bef64bf..566dc1ea49 100644 --- a/src/motif/choice.cpp +++ b/src/motif/choice.cpp @@ -145,14 +145,17 @@ wxChoice::~wxChoice() if (m_widgetList) delete[] m_widgetList; - DetachWidget(GetMainWidget()); // Removes event handlers + if (GetMainWidget()) + { + DetachWidget(GetMainWidget()); // Removes event handlers - XtDestroyWidget((Widget) m_formWidget); - m_formWidget = (WXWidget) 0; + XtDestroyWidget((Widget) m_formWidget); + m_formWidget = (WXWidget) 0; - // Presumably the other widgets have been deleted now, via the form - m_mainWidget = (WXWidget) 0; - m_buttonWidget = (WXWidget) 0; + // Presumably the other widgets have been deleted now, via the form + m_mainWidget = (WXWidget) 0; + m_buttonWidget = (WXWidget) 0; + } } void wxChoice::Append(const wxString& item) diff --git a/src/motif/combobox.cpp b/src/motif/combobox.cpp index 8361a2b102..4537779eb6 100644 --- a/src/motif/combobox.cpp +++ b/src/motif/combobox.cpp @@ -94,6 +94,19 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, return TRUE; } +wxComboBox::~wxComboBox() +{ + DetachWidget((Widget) m_mainWidget); // Removes event handlers + XtDestroyWidget((Widget) m_mainWidget); + m_mainWidget = (WXWidget) 0; +} + +void wxComboBox::SetSize(int x, int y, int width, int height, int sizeFlags) +{ + // Necessary so it doesn't call wxChoice::SetSize + wxWindow::SetSize(x, y, width, height, sizeFlags); +} + wxString wxComboBox::GetValue() const { char *s = XmComboBoxGetString ((Widget) m_mainWidget); @@ -115,6 +128,97 @@ void wxComboBox::SetValue(const wxString& value) m_inSetValue = FALSE; } +void wxComboBox::Append(const wxString& item) +{ + XmString str = XmStringCreateLtoR((char*) (const char*) item, XmSTRING_DEFAULT_CHARSET); + XmComboBoxAddItem((Widget) m_mainWidget, str, 0); + m_stringList.Add(item); + XmStringFree(str); + m_noStrings ++; +} + +void wxComboBox::Delete(int n) +{ + XmComboBoxDeletePos((Widget) m_mainWidget, n-1); + wxNode *node = m_stringList.Nth(n); + if (node) + { + delete[] (char *)node->Data(); + delete node; + } + m_noStrings--; +} + +void wxComboBox::Clear() +{ + XmComboBoxDeleteAllItems((Widget) m_mainWidget); + m_stringList.Clear(); +} + +void wxComboBox::SetSelection (int n) +{ + XmComboBoxSelectPos((Widget) m_mainWidget, n+1, False); +} + +int wxComboBox::GetSelection (void) const +{ + int sel = XmComboBoxGetSelectedPos((Widget) m_mainWidget); + if (sel == 0) + return -1; + else + return sel - 1; +} + +wxString wxComboBox::GetString(int n) const +{ + wxNode *node = m_stringList.Nth (n); + if (node) + return wxString((char *) node->Data ()); + else + return wxEmptyString; +} + +wxString wxComboBox::GetStringSelection() const +{ + int sel = GetSelection(); + if (sel == -1) + return wxEmptyString; + else + return GetString(sel); +} + +bool wxComboBox::SetStringSelection(const wxString& sel) +{ + int n = FindString(sel); + if (n == -1) + return FALSE; + else + { + SetSelection(n); + return TRUE; + } +} + +int wxComboBox::FindString(const wxString& s) const +{ + int *pos_list = NULL; + int count = 0; + XmString text = XmStringCreateSimple ((char*) (const char*) s); + bool found = (XmComboBoxGetMatchPos((Widget) m_mainWidget, + text, &pos_list, &count) != 0); + + XmStringFree(text); + + if (found && count > 0) + { + int pos = pos_list[0] - 1; + free(pos_list); + return pos; + } + + return -1; +} + // Clipboard operations void wxComboBox::Copy() { diff --git a/src/motif/dialog.cpp b/src/motif/dialog.cpp index 4afc7bf1c0..b76fe887a8 100644 --- a/src/motif/dialog.cpp +++ b/src/motif/dialog.cpp @@ -480,7 +480,10 @@ int wxDialog::ShowModal() // Loop until we signal that the dialog should be closed while ((wxModalShowingStack.Number() > 0) && (bool)wxModalShowingStack.First()->Data()) { - XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll); +// XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll); + + XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event); + wxTheApp->ProcessXEvent((WXEvent*) &event); } // Remove modal dialog flag from stack @@ -494,7 +497,8 @@ int wxDialog::ShowModal() { XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())); XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event); - XtDispatchEvent(&event); + + wxTheApp->ProcessXEvent((WXEvent*) &event); } // TODO: is it safe to call this, if the dialog may have been deleted diff --git a/src/motif/mdi/lib/XsMotifWindow.C b/src/motif/mdi/lib/XsMotifWindow.C index a3b895fc1a..7f9e45a4a0 100644 --- a/src/motif/mdi/lib/XsMotifWindow.C +++ b/src/motif/mdi/lib/XsMotifWindow.C @@ -375,6 +375,9 @@ void _XsMotifCorner::_expose (XEvent*) { Dimension w, h; + if (_topShadowGC == 0) // JACS + return; + // Get the size of the corner XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL); @@ -612,6 +615,8 @@ const char *_XsMotifSide::className ( ) const void _XsMotifSide::_expose (XEvent *event) { + if (_topShadowGC == 0) // JACS + return; // Clear out the window first @@ -847,6 +852,9 @@ const char *_XsMotifButton::className ( ) const void _XsMotifButton::_expose (XEvent *event) { + if (_topShadowGC == 0) // JACS + return; + Dimension w, h; // Get the size of the button @@ -1152,6 +1160,8 @@ void _XsMotifTitle::_redraw ( ) void _XsMotifTitle::_expose (XEvent *event) { + if (_topShadowGC == 0) // JACS + return; // Clear out the window first @@ -1646,6 +1656,9 @@ void _XsMotifIcon::_input (XEvent *event) void _XsMotifIcon::_expose (XEvent *) { + if (_topShadowGC == 0) // JACS + return; + Dimension iconHeight; Dimension iconWidth; diff --git a/src/motif/scrolbar.cpp b/src/motif/scrolbar.cpp index 0f19d1e20f..52ef32cc55 100644 --- a/src/motif/scrolbar.cpp +++ b/src/motif/scrolbar.cpp @@ -22,7 +22,7 @@ #include -void wxScrollBarCallback(Widget widget, XtPointer clientData, +static void wxScrollBarCallback(Widget widget, XtPointer clientData, XmScaleCallbackStruct *cbs); #if !USE_SHARED_LIBRARY @@ -167,7 +167,7 @@ void wxScrollBar::ChangeForegroundColour() // TODO } -void wxScrollBarCallback(Widget widget, XtPointer clientData, +static void wxScrollBarCallback(Widget widget, XtPointer clientData, XmScaleCallbackStruct *cbs) { wxScrollBar *scrollBar = (wxScrollBar *)clientData; diff --git a/src/motif/textctrl.cpp b/src/motif/textctrl.cpp index 3d7c94d2e4..b28bdf9ef5 100644 --- a/src/motif/textctrl.cpp +++ b/src/motif/textctrl.cpp @@ -181,7 +181,9 @@ wxString wxTextCtrl::GetValue() const void wxTextCtrl::SetValue(const wxString& value) { - wxASSERT_MSG( (!value.IsNull()), "Must not pass a null string to wxTextCtrl::SetValue." ) ; + // This assert is wrong -- means that you can't set an empty + // string (IsNull == IsEmpty). + // wxASSERT_MSG( (!value.IsNull()), "Must not pass a null string to wxTextCtrl::SetValue." ) ; m_inSetValue = TRUE; XmTextSetString ((Widget) m_mainWidget, (char*) (const char*) value); diff --git a/src/motif/window.cpp b/src/motif/window.cpp index dad35a5234..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, @@ -2735,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); @@ -3111,3 +3111,72 @@ void wxWindow::ClearUpdateRects() } 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; +} + diff --git a/src/stubs/combobox.cpp b/src/stubs/combobox.cpp index f1bbccaeb0..0be841bad4 100644 --- a/src/stubs/combobox.cpp +++ b/src/stubs/combobox.cpp @@ -114,3 +114,52 @@ void wxComboBox::SetSelection(long from, long to) // TODO } +void wxComboBox::Append(const wxString& item) +{ + // TODO +} + +void wxComboBox::Delete(int n) +{ + // TODO +} + +void wxComboBox::Clear() +{ + // TODO +} + +int wxComboBox::GetSelection() const +{ + // TODO + return -1; +} + +void wxComboBox::SetSelection(int n) +{ + // TODO +} + +int wxComboBox::FindString(const wxString& s) const +{ + // TODO + return -1; +} + +wxString wxComboBox::GetString(int n) const +{ + // TODO + return wxString(""); +} + +wxString wxComboBox::GetStringSelection() const +{ + // TODO + return wxString(""); +} + +bool wxComboBox::SetStringSelection(const wxString& sel) +{ + // TODO + return FALSE; +}