From e1aae5288576cd0066d2cbbf92935a969110bcea Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Sun, 23 Feb 2003 20:33:43 +0000 Subject: [PATCH] Implemented DoGetBestSize for wxListBox, (native) wxComboBox and wxTextCtrl, and used it when wxSize(-1, -1) is passed to Create, to set the initial size. Added wxDoChangeFont and wxXmStringToString helper functions, removed the use of m_stringList in native wxComboBox, removed some duplicated code in wxWindow. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19296 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/motif/combobox.h | 3 + include/wx/motif/listbox.h | 2 + include/wx/motif/private.h | 10 ++- include/wx/motif/textctrl.h | 3 +- src/motif/choice.cpp | 6 +- src/motif/combobox_native.cpp | 82 ++++++++++++++++++------- src/motif/listbox.cpp | 111 +++++++++++++++++++++++++--------- src/motif/settings.cpp | 7 +-- src/motif/textctrl.cpp | 74 +++++++++++++---------- src/motif/utils.cpp | 29 +++++++++ src/motif/window.cpp | 46 +++----------- 11 files changed, 244 insertions(+), 129 deletions(-) diff --git a/include/wx/motif/combobox.h b/include/wx/motif/combobox.h index ebf2238539..618756c345 100644 --- a/include/wx/motif/combobox.h +++ b/include/wx/motif/combobox.h @@ -91,6 +91,9 @@ protected: virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); +private: + // only implemented for native combo box + void AdjustDropDownListSize(); }; #endif diff --git a/include/wx/motif/listbox.h b/include/wx/motif/listbox.h index 5f5cbc99c8..4702db06a5 100644 --- a/include/wx/motif/listbox.h +++ b/include/wx/motif/listbox.h @@ -88,6 +88,8 @@ public: virtual void DoToggleItem(int item, int x) {}; #endif protected: + virtual wxSize DoGetBestSize() const; + int m_noItems; // List mapping positions->client data diff --git a/include/wx/motif/private.h b/include/wx/motif/private.h index 8f21c4e12c..da2bc7f308 100644 --- a/include/wx/motif/private.h +++ b/include/wx/motif/private.h @@ -64,6 +64,7 @@ extern void wxDoChangeForegroundColour(WXWidget widget, extern void wxDoChangeBackgroundColour(WXWidget widget, wxColour& backgroundColour, bool changeArmColour = FALSE); +extern void wxDoChangeFont(WXWidget widget, wxFont& font); #define wxNO_COLORS 0x00 #define wxBACK_COLORS 0x01 @@ -107,13 +108,20 @@ private: XmString m_string; }; +wxString wxXmStringToString( const XmString& xmString ); + // ---------------------------------------------------------------------------- // Routines used in both wxTextCtrl/wxListBox and nativa wxComboBox // (defined in src/motif/listbox.cpp or src/motif/textctrl.cpp // ---------------------------------------------------------------------------- int wxDoFindStringInList( Widget listWidget, const wxString& str ); -int wxDoGetSelectionInList(Widget listWidget); +int wxDoGetSelectionInList( Widget listWidget ); +wxString wxDoGetStringInList( Widget listWidget, int n ); +wxSize wxDoGetListBoxBestSize( Widget listWidget, const wxWindow* window ); + +wxSize wxDoGetSingleTextCtrlBestSize( Widget textWidget, + const wxWindow* window ); // ---------------------------------------------------------------------------- // executes one main loop iteration (implemented in src/motif/evtloop.cpp) diff --git a/include/wx/motif/textctrl.h b/include/wx/motif/textctrl.h index 7355c85555..59d3510eb1 100644 --- a/include/wx/motif/textctrl.h +++ b/include/wx/motif/textctrl.h @@ -133,7 +133,8 @@ public: protected: wxString m_fileName; - + + virtual wxSize DoGetBestSize() const; public: // Motif-specific void* m_tempCallbackStruct; diff --git a/src/motif/choice.cpp b/src/motif/choice.cpp index a3e57838b9..fa5340e378 100644 --- a/src/motif/choice.cpp +++ b/src/motif/choice.cpp @@ -176,10 +176,8 @@ int wxChoice::DoAppend(const wxString& item) DoChangeBackgroundColour((WXWidget) w, m_backgroundColour); - if (m_font.Ok()) - XtVaSetValues (w, - XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) m_formWidget)), - NULL); + if( m_font.Ok() ) + wxDoChangeFont( w, m_font ); m_widgetArray.Add(w); diff --git a/src/motif/combobox_native.cpp b/src/motif/combobox_native.cpp index 9c11990fe3..aa8eac0f0d 100644 --- a/src/motif/combobox_native.cpp +++ b/src/motif/combobox_native.cpp @@ -83,6 +83,8 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, ( style & wxCB_DROPDOWN ) ? XmDROP_DOWN_COMBO_BOX : // default to wxCB_DROPDOWN XmDROP_DOWN_COMBO_BOX; + if( cb_type == XmDROP_DOWN_COMBO_BOX ) + SetWindowStyle( style | wxCB_DROPDOWN ); Widget buttonWidget= XtVaCreateManagedWidget(name.c_str(), xmComboBoxWidgetClass, parentWidget, @@ -108,19 +110,36 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, (XtCallbackProc) wxComboBoxCallback, (XtPointer) this); + wxSize best = GetBestSize(); + if( size.x != -1 ) best.x = size.x; + if( size.y != -1 ) best.y = size.y; + SetCanAddEventHandler(true); AttachWidget (parent, m_mainWidget, (WXWidget) NULL, - pos.x, pos.y, size.x, size.y); - - XtVaSetValues (GetXmList(this), - XmNvisibleItemCount, 10, - NULL); + pos.x, pos.y, best.x, best.y); ChangeBackgroundColour(); return true; } +void wxComboBox::AdjustDropDownListSize() +{ + int newListCount = -1, itemCount = GetCount(); + const int MAX = 12; + + if( !itemCount ) + newListCount = 1; + else if( itemCount < MAX ) + newListCount = itemCount; + else + newListCount = MAX; + + XtVaSetValues( GetXmList(this), + XmNvisibleItemCount, newListCount, + NULL ); +} + wxComboBox::~wxComboBox() { DetachWidget((Widget) m_mainWidget); // Removes event handlers @@ -171,8 +190,8 @@ int wxComboBox::DoAppend(const wxString& item) { wxXmString str( item.c_str() ); XmComboBoxAddItem((Widget) m_mainWidget, str(), 0, False); - m_stringList.Add(item); m_noStrings ++; + AdjustDropDownListSize(); return GetCount() - 1; } @@ -185,14 +204,10 @@ void wxComboBox::Delete(int n) XmComboBoxDeletePos((Widget) m_mainWidget, n+1); #endif - wxStringList::Node *node = m_stringList.Item(n); - if (node) - { - delete[] node->GetData(); - delete node; - } m_clientDataDict.Delete(n, HasClientObjectData()); m_noStrings--; + + AdjustDropDownListSize(); } void wxComboBox::Clear() @@ -204,13 +219,12 @@ void wxComboBox::Clear() { XmComboBoxDeletePos((Widget) m_mainWidget, m_noStrings--); } - #endif - - m_stringList.Clear(); +#endif if ( HasClientObjectData() ) m_clientDataDict.DestroyData(); m_noStrings = 0; + AdjustDropDownListSize(); } void wxComboBox::SetSelection (int n) @@ -237,11 +251,7 @@ int wxComboBox::GetSelection (void) const wxString wxComboBox::GetString(int n) const { - wxStringList::Node *node = m_stringList.Item(n); - if (node) - return wxString(node->GetData ()); - else - return wxEmptyString; + return wxDoGetStringInList( GetXmList(this), n ); } int wxComboBox::FindString(const wxString& s) const @@ -356,6 +366,12 @@ void wxComboBoxCallback (Widget WXUNUSED(w), XtPointer clientData, void wxComboBox::ChangeFont(bool keepOriginalSize) { + if( m_font.Ok() ) + { + wxDoChangeFont( GetXmText(this), m_font ); + wxDoChangeFont( GetXmList(this), m_font ); + } + // Don't use the base class wxChoice's ChangeFont wxWindow::ChangeFont(keepOriginalSize); } @@ -372,7 +388,31 @@ void wxComboBox::ChangeForegroundColour() wxSize wxComboBox::DoGetBestSize() const { - return wxWindow::DoGetBestSize(); + if( (GetWindowStyle() & wxCB_DROPDOWN) == wxCB_DROPDOWN || + (GetWindowStyle() & wxCB_READONLY) == wxCB_READONLY ) + { + Dimension arrowW, arrowS, highlight, xmargin, ymargin, shadow; + + XtVaGetValues( (Widget)m_mainWidget, + XmNarrowSize, &arrowW, + XmNarrowSpacing, &arrowS, + XmNhighlightThickness, &highlight, + XmNmarginWidth, &xmargin, + XmNmarginHeight, &ymargin, + XmNshadowThickness, &shadow, + NULL ); + + wxSize listSize = wxDoGetListBoxBestSize( GetXmList(this), this ); + wxSize textSize = wxDoGetSingleTextCtrlBestSize( GetXmText(this), + this ); + + // FIXME arbitrary constants + return wxSize( listSize.x + arrowW + arrowS + 2 * highlight + + 2 * shadow + 2 * xmargin , + textSize.y + 2 * highlight + 2 * ymargin + 2 * shadow ); + } + else + return wxWindow::DoGetBestSize(); } #endif // XmVersion >= 2000 diff --git a/src/motif/listbox.cpp b/src/motif/listbox.cpp index 045bbc81d0..ddcbd3fa2f 100644 --- a/src/motif/listbox.cpp +++ b/src/motif/listbox.cpp @@ -92,17 +92,30 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, Widget parentWidget = (Widget) parent->GetClientWidget(); - Arg args[3]; + XmFontList fontList = (XmFontList)NULL; + + if( m_font.Ok() ) + { + fontList = (XmFontList)m_font.GetFontList(1.0, + XtDisplay(parentWidget)); + } + + Arg args[4]; int count = 0; - XtSetArg( args[0], XmNlistSizePolicy, XmCONSTANT ); ++count; - XtSetArg( args[1], XmNselectionPolicy, + XtSetArg( args[count], XmNlistSizePolicy, XmCONSTANT ); ++count; + XtSetArg( args[count], XmNselectionPolicy, ( m_windowStyle & wxLB_MULTIPLE ) ? XmMULTIPLE_SELECT : ( m_windowStyle & wxLB_EXTENDED ) ? XmEXTENDED_SELECT : XmBROWSE_SELECT ); ++count; + if( fontList ) + { + XtSetArg( args[count], XmNfontList, fontList ); + ++count; + } if( m_windowStyle & wxLB_ALWAYS_SB ) { - XtSetArg( args[2], XmNscrollBarDisplayPolicy, XmSTATIC ); + XtSetArg( args[count], XmNscrollBarDisplayPolicy, XmSTATIC ); ++count; } @@ -115,12 +128,9 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, XtManageChild (listWidget); - long width = size.x; - long height = size.y; - if (width == -1) - width = 150; - if (height == -1) - height = 80; + wxSize best = GetBestSize(); + if( size.x != -1 ) best.x = size.x; + if( size.y != -1 ) best.y = size.y; XtAddCallback (listWidget, XmNbrowseSelectionCallback, @@ -139,11 +149,9 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, (XtCallbackProc) wxListBoxCallback, (XtPointer) this); - ChangeFont(FALSE); - SetCanAddEventHandler(TRUE); AttachWidget (parent, m_mainWidget, (WXWidget) NULL, - pos.x, pos.y, width, height); + pos.x, pos.y, best.x, best.y); ChangeBackgroundColour(); @@ -443,28 +451,25 @@ int wxListBox::GetSelection() const } // Find string for position -wxString wxListBox::GetString(int N) const +wxString wxDoGetStringInList( Widget listBox, int n ) { - Widget listBox = (Widget) m_mainWidget; XmString *strlist; - int n; - XtVaGetValues (listBox, XmNitemCount, &n, XmNitems, &strlist, NULL); - if (N <= n && N >= 0) - { - char *txt; - if (XmStringGetLtoR (strlist[N], XmSTRING_DEFAULT_CHARSET, &txt)) - { - wxString str(txt); - XtFree (txt); - return str; - } - else - return wxEmptyString; - } + int count; + XtVaGetValues( listBox, + XmNitemCount, &count, + XmNitems, &strlist, + NULL ); + if( n <= count && n >= 0 ) + return wxXmStringToString( strlist[n] ); else return wxEmptyString; } +wxString wxListBox::GetString( int n ) const +{ + return wxDoGetStringInList( (Widget)m_mainWidget, n ); +} + void wxListBox::DoInsertItems(const wxArrayString& items, int pos) { wxSizeKeeper sk( this ); @@ -653,3 +658,51 @@ int wxListBox::GetCount() const { return m_noItems; } + +#define LIST_SCROLL_SPACING 6 + +wxSize wxDoGetListBoxBestSize( Widget listWidget, const wxWindow* window ) +{ + int max; + Dimension spacing, highlight, xmargin, ymargin, shadow; + int width = 0; + int x, y; + + XtVaGetValues( listWidget, + XmNitemCount, &max, + XmNlistSpacing, &spacing, + XmNhighlightThickness, &highlight, + XmNlistMarginWidth, &xmargin, + XmNlistMarginHeight, &ymargin, + XmNshadowThickness, &shadow, + NULL ); + + for( size_t i = 0; i < (size_t)max; ++i ) + { + window->GetTextExtent( wxDoGetStringInList( listWidget, i ), &x, &y ); + width = wxMax( width, x ); + } + + // use some arbitrary value if there are no strings + if( width == 0 ) + width = 100; + + // get my + window->GetTextExtent( "v", &x, &y ); + + // make it a little larger than widest string, plus the scrollbar + width += wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ) + + 2 * highlight + LIST_SCROLL_SPACING + 2 * xmargin + 2 * shadow; + + // at least 3 items, at most 10 + int height = wxMax( 3, wxMin( 10, max ) ) * + ( y + spacing + 2 * highlight ) + 2 * ymargin + 2 * shadow; + + return wxSize( width, height ); +} + +wxSize wxListBox::DoGetBestSize() const +{ + return wxDoGetListBoxBestSize( (Widget)m_mainWidget, this ); +} + diff --git a/src/motif/settings.cpp b/src/motif/settings.cpp index e8d4c9b01b..91f8fc631b 100644 --- a/src/motif/settings.cpp +++ b/src/motif/settings.cpp @@ -181,6 +181,9 @@ int wxSystemSettingsNative::GetMetric(wxSystemMetric index) { switch ( index) { + case wxSYS_HSCROLL_Y: + case wxSYS_VSCROLL_X: + return 15; case wxSYS_MOUSE_BUTTONS: // TODO case wxSYS_BORDER_X: @@ -233,10 +236,6 @@ int wxSystemSettingsNative::GetMetric(wxSystemMetric index) // TODO case wxSYS_SMALLICON_Y: // TODO - case wxSYS_HSCROLL_Y: - // TODO - case wxSYS_VSCROLL_X: - // TODO case wxSYS_VSCROLL_ARROW_X: // TODO case wxSYS_VSCROLL_ARROW_Y: diff --git a/src/motif/textctrl.cpp b/src/motif/textctrl.cpp index 7bb9799cae..6512988d93 100644 --- a/src/motif/textctrl.cpp +++ b/src/motif/textctrl.cpp @@ -107,24 +107,14 @@ bool wxTextCtrl::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { + if( !CreateControl( parent, id, pos, size, style, validator, name ) ) + return false; + m_tempCallbackStruct = (void*) NULL; m_modified = FALSE; m_processedDefault = FALSE; - // m_backgroundColour = parent->GetBackgroundColour(); - m_backgroundColour = * wxWHITE; - m_foregroundColour = parent->GetForegroundColour(); - - SetName(name); - SetValidator(validator); - if (parent) - parent->AddChild(this); - m_windowStyle = style; - - if ( id == -1 ) - m_windowId = (int)NewControlId(); - else - m_windowId = id; + m_backgroundColour = *wxWHITE; Widget parentWidget = (Widget) parent->GetClientWidget(); @@ -180,20 +170,13 @@ bool wxTextCtrl::Create(wxWindow *parent, NULL); } - if ( !!value ) + if ( !value.empty() ) { -#if 0 - // don't do this because it is just linking the text to a source - // string which is unsafe. MB - // - XmTextSetString ((Widget) m_mainWidget, (char*)value.c_str()); -#else // do this instead... MB // XtVaSetValues( (Widget) m_mainWidget, XmNvalue, (char *)value.c_str(), NULL); -#endif } // install callbacks @@ -208,11 +191,15 @@ bool wxTextCtrl::Create(wxWindow *parent, XtAddCallback((Widget) m_mainWidget, XmNlosingFocusCallback, (XtCallbackProc)wxTextWindowLoseFocusProc, (XtPointer)this); // font - m_font = parent->GetFont(); ChangeFont(FALSE); + wxSize best = GetBestSize(); + if( size.x != -1 ) best.x = size.x; + if( size.y != -1 ) best.y = size.y; + SetCanAddEventHandler(TRUE); - AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y); + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, + pos.x, pos.y, best.x, best.y); ChangeBackgroundColour(); @@ -260,18 +247,11 @@ void wxTextCtrl::SetValue(const wxString& value) { m_inSetValue = TRUE; -#if 0 - // don't do this because it is just linking the text to a source - // string which is unsafe. MB - // - XmTextSetString ((Widget) m_mainWidget, (char*)value.c_str()); -#else // do this instead... MB // XtVaSetValues( (Widget) m_mainWidget, XmNvalue, (char *)value.c_str(), NULL); -#endif m_inSetValue = FALSE; } @@ -735,6 +715,38 @@ void wxTextCtrl::DoSendEvents(void *wxcbs, long keycode) m_tempCallbackStruct = NULL; } +wxSize wxDoGetSingleTextCtrlBestSize( Widget textWidget, + const wxWindow* window ) +{ + Dimension xmargin, ymargin, highlight, shadow; + char* value; + + XtVaGetValues( textWidget, + XmNmarginWidth, &xmargin, + XmNmarginHeight, &ymargin, + XmNvalue, &value, + XmNhighlightThickness, &highlight, + XmNshadowThickness, &shadow, + NULL ); + if( !value ) + value = "|"; + + int x, y; + window->GetTextExtent( value, &x, &y ); + + return wxSize( x + 2 * xmargin + 2 * highlight + 2 * shadow, + // MBN: +2 necessary: Lesstif bug or mine? + y + 2 * ymargin + 2 * highlight + 2 * shadow + 2 ); +} + +wxSize wxTextCtrl::DoGetBestSize() const +{ + if( IsSingleLine() ) + return wxDoGetSingleTextCtrlBestSize( (Widget)m_mainWidget, this ); + else + return wxWindow::DoGetBestSize(); +} + // ---------------------------------------------------------------------------- // helpers and Motif callbacks // ---------------------------------------------------------------------------- diff --git a/src/motif/utils.cpp b/src/motif/utils.cpp index 36df02e7fc..78989f932c 100644 --- a/src/motif/utils.cpp +++ b/src/motif/utils.cpp @@ -1247,6 +1247,21 @@ void wxDoChangeBackgroundColour(WXWidget widget, wxColour& backgroundColour, boo NULL); } +extern void wxDoChangeFont(WXWidget widget, wxFont& font) +{ + // lesstif 0.87 hangs here, but 0.93 does not +#if !defined(LESSTIF_VERSION) \ + || (defined(LesstifVersion) && LesstifVersion >= 93) + + Widget w = (Widget)widget; + XmFontList fontList = (XmFontList)font.GetFontList(1.0, XtDisplay(w)); + XtVaSetValues( w, + XmNfontList, fontList, + NULL ); +#endif + +} + #endif // __WXMOTIF__ @@ -1257,3 +1272,17 @@ bool wxWindowIsVisible(Window win) return (wa.map_state == IsViewable); } + +wxString wxXmStringToString( const XmString& xmString ) +{ + char *txt; + if( XmStringGetLtoR( xmString, XmSTRING_DEFAULT_CHARSET, &txt ) ) + { + wxString str(txt); + XtFree (txt); + return str; + } + + return wxEmptyString; +} + diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 88dff30462..f68c56bcb9 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -2914,41 +2914,17 @@ void wxWindow::ChangeForegroundColour() } // Change a widget's foreground and background colours. -void wxWindow::DoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour) +void wxWindow::DoChangeForegroundColour(WXWidget widget, + wxColour& foregroundColour) { - // When should we specify the foreground, if it's calculated - // by wxComputeColours? - // Solution: say we start with the default (computed) foreground colour. - // If we call SetForegroundColour explicitly for a control or window, - // then the foreground is changed. - // Therefore SetBackgroundColour computes the foreground colour, and - // SetForegroundColour changes the foreground colour. The ordering is - // important. - - Widget w = (Widget)widget; - XtVaSetValues( - w, - XmNforeground, foregroundColour.AllocColour(XtDisplay(w)), - NULL - ); + wxDoChangeForegroundColour( widget, foregroundColour ); } -void wxWindow::DoChangeBackgroundColour(WXWidget widget, wxColour& backgroundColour, bool changeArmColour) +void wxWindow::DoChangeBackgroundColour(WXWidget widget, + wxColour& backgroundColour, + bool changeArmColour) { - wxComputeColours (XtDisplay((Widget) widget), & backgroundColour, - (wxColour*) NULL); - - XtVaSetValues ((Widget) widget, - XmNbackground, g_itemColors[wxBACK_INDEX].pixel, - XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel, - XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel, - XmNforeground, g_itemColors[wxFORE_INDEX].pixel, - NULL); - - if (changeArmColour) - XtVaSetValues ((Widget) widget, - XmNarmColor, g_itemColors[wxSELE_INDEX].pixel, - NULL); + wxDoChangeBackgroundColour( widget, backgroundColour, changeArmColour ); } bool wxWindow::SetBackgroundColour(const wxColour& col) @@ -2982,13 +2958,7 @@ void wxWindow::ChangeFont(bool keepOriginalSize) int width, height, width1, height1; GetSize(& width, & height); - // lesstif 0.87 hangs here, but 0.93 does not -#if !defined(LESSTIF_VERSION) \ - || (defined(LesstifVersion) && LesstifVersion >= 93) - XtVaSetValues (w, - XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay(w)), - NULL); -#endif + wxDoChangeFont( GetLabelWidget(), m_font ); GetSize(& width1, & height1); if (keepOriginalSize && (width != width1 || height != height1)) -- 2.45.2