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
This commit is contained in:
Mattia Barbon 2003-02-23 20:33:43 +00:00
parent 8dcc14725d
commit e1aae52885
11 changed files with 244 additions and 129 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -133,7 +133,8 @@ public:
protected:
wxString m_fileName;
virtual wxSize DoGetBestSize() const;
public:
// Motif-specific
void* m_tempCallbackStruct;

View File

@ -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);

View File

@ -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

View File

@ -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 );
}

View File

@ -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:

View File

@ -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
// ----------------------------------------------------------------------------

View File

@ -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;
}

View File

@ -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))