1. some fixes for wxSortedArrayString
2. wxChoice understands wxCB_SORT under GTK git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4135 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -30,6 +30,8 @@ public:
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxChoiceNameStr )
|
||||
{
|
||||
m_strings = (wxSortedArrayString *)NULL;
|
||||
|
||||
Create(parent, id, pos, size, n, choices, style, validator, name);
|
||||
}
|
||||
~wxChoice();
|
||||
@@ -53,13 +55,13 @@ public:
|
||||
wxString GetString( int n ) const;
|
||||
|
||||
// implementation
|
||||
wxList m_clientList;
|
||||
wxList m_clientList; // contains the client data for the items
|
||||
|
||||
void DisableEvents();
|
||||
void EnableEvents();
|
||||
void AppendCommon( const wxString &item );
|
||||
void ApplyWidgetStyle();
|
||||
|
||||
|
||||
protected:
|
||||
virtual int DoAppend(const wxString& item);
|
||||
|
||||
@@ -79,6 +81,13 @@ protected:
|
||||
{ return(wxWindowBase::DoGetClientObject()); };
|
||||
|
||||
private:
|
||||
// common part of Create() and DoAppend()
|
||||
size_t AppendHelper(GtkWidget *menu, const wxString& item);
|
||||
|
||||
// this array is only used for controls with wxCB_SORT style, so only
|
||||
// allocate it if it's needed (hence using pointer)
|
||||
wxSortedArrayString *m_strings;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxChoice)
|
||||
};
|
||||
|
||||
|
@@ -30,6 +30,8 @@ public:
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxChoiceNameStr )
|
||||
{
|
||||
m_strings = (wxSortedArrayString *)NULL;
|
||||
|
||||
Create(parent, id, pos, size, n, choices, style, validator, name);
|
||||
}
|
||||
~wxChoice();
|
||||
@@ -53,13 +55,13 @@ public:
|
||||
wxString GetString( int n ) const;
|
||||
|
||||
// implementation
|
||||
wxList m_clientList;
|
||||
wxList m_clientList; // contains the client data for the items
|
||||
|
||||
void DisableEvents();
|
||||
void EnableEvents();
|
||||
void AppendCommon( const wxString &item );
|
||||
void ApplyWidgetStyle();
|
||||
|
||||
|
||||
protected:
|
||||
virtual int DoAppend(const wxString& item);
|
||||
|
||||
@@ -79,6 +81,13 @@ protected:
|
||||
{ return(wxWindowBase::DoGetClientObject()); };
|
||||
|
||||
private:
|
||||
// common part of Create() and DoAppend()
|
||||
size_t AppendHelper(GtkWidget *menu, const wxString& item);
|
||||
|
||||
// this array is only used for controls with wxCB_SORT style, so only
|
||||
// allocate it if it's needed (hence using pointer)
|
||||
wxSortedArrayString *m_strings;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxChoice)
|
||||
};
|
||||
|
||||
|
@@ -912,8 +912,9 @@ public:
|
||||
// sensitive (default). Returns index of the first item matched or
|
||||
// wxNOT_FOUND
|
||||
int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const;
|
||||
// add new element at the end
|
||||
void Add(const wxString& str);
|
||||
// add new element at the end (if the array is not sorted), return its
|
||||
// index
|
||||
size_t Add(const wxString& str);
|
||||
// add new element at given position
|
||||
void Insert(const wxString& str, size_t uiIndex);
|
||||
// remove first item matching this value
|
||||
|
@@ -1844,7 +1844,7 @@ int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const
|
||||
}
|
||||
|
||||
// add item at the end
|
||||
void wxArrayString::Add(const wxString& str)
|
||||
size_t wxArrayString::Add(const wxString& str)
|
||||
{
|
||||
if ( m_autoSort ) {
|
||||
// insert the string at the correct position to keep the array sorted
|
||||
@@ -1869,6 +1869,8 @@ void wxArrayString::Add(const wxString& str)
|
||||
wxASSERT_MSG( lo == hi, wxT("binary search broken") );
|
||||
|
||||
Insert(str, lo);
|
||||
|
||||
return (size_t)lo;
|
||||
}
|
||||
else {
|
||||
wxASSERT( str.GetStringData()->IsValid() );
|
||||
@@ -1879,7 +1881,9 @@ void wxArrayString::Add(const wxString& str)
|
||||
str.GetStringData()->Lock();
|
||||
|
||||
// just append
|
||||
m_pItems[m_nCount++] = (wxChar *)str.c_str();
|
||||
m_pItems[m_nCount] = (wxChar *)str.c_str(); // const_cast
|
||||
|
||||
return m_nCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1888,8 +1892,6 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex)
|
||||
{
|
||||
wxASSERT( str.GetStringData()->IsValid() );
|
||||
|
||||
wxCHECK_RET( !m_autoSort, wxT("can't use this method with sorted arrays") );
|
||||
|
||||
wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArrayString::Insert") );
|
||||
|
||||
Grow();
|
||||
|
@@ -38,7 +38,7 @@ extern bool g_blockEventsOnDrag;
|
||||
|
||||
static void gtk_choice_clicked_callback( GtkWidget *WXUNUSED(widget), wxChoice *choice )
|
||||
{
|
||||
if (g_isIdle)
|
||||
if (g_isIdle)
|
||||
wxapp_install_idle_handler();
|
||||
|
||||
if (!choice->m_hasVMT) return;
|
||||
@@ -60,6 +60,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxChoice,wxControl)
|
||||
|
||||
wxChoice::wxChoice()
|
||||
{
|
||||
m_strings = (wxSortedArrayString *)NULL;
|
||||
}
|
||||
|
||||
bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
@@ -76,7 +77,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
!CreateBase( parent, id, pos, size, style, validator, name ))
|
||||
{
|
||||
wxFAIL_MSG( wxT("wxChoice creation failed") );
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_widget = gtk_option_menu_new();
|
||||
@@ -88,20 +89,20 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
newSize.y = 26;
|
||||
SetSize( newSize.x, newSize.y );
|
||||
|
||||
if ( style & wxCB_SORT )
|
||||
{
|
||||
// if our m_strings != NULL, DoAppend() will check for it and insert
|
||||
// items in the correct order
|
||||
m_strings = new wxSortedArrayString;
|
||||
}
|
||||
|
||||
GtkWidget *menu = gtk_menu_new();
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
|
||||
GtkWidget *item = gtk_menu_item_new_with_label( choices[i].mbc_str() );
|
||||
gtk_menu_append( GTK_MENU(menu), item );
|
||||
|
||||
gtk_widget_show( item );
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT( item ), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
|
||||
AppendHelper(menu, choices[i]);
|
||||
}
|
||||
|
||||
gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
|
||||
|
||||
m_parent->DoAddChild( this );
|
||||
@@ -120,6 +121,8 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
wxChoice::~wxChoice()
|
||||
{
|
||||
Clear();
|
||||
|
||||
delete m_strings;
|
||||
}
|
||||
|
||||
int wxChoice::DoAppend( const wxString &item )
|
||||
@@ -127,27 +130,8 @@ int wxChoice::DoAppend( const wxString &item )
|
||||
wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice") );
|
||||
|
||||
GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label( item.mbc_str() );
|
||||
|
||||
gtk_menu_append( GTK_MENU(menu), menu_item );
|
||||
|
||||
if (GTK_WIDGET_REALIZED(m_widget))
|
||||
{
|
||||
gtk_widget_realize( menu_item );
|
||||
gtk_widget_realize( GTK_BIN(menu_item)->child );
|
||||
|
||||
if (m_widgetStyle) ApplyWidgetStyle();
|
||||
}
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
|
||||
|
||||
gtk_widget_show( menu_item );
|
||||
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
|
||||
// return the index of the item in the control
|
||||
return GetCount() - 1;
|
||||
return AppendHelper(menu, item);
|
||||
}
|
||||
|
||||
void wxChoice::DoSetClientData( int n, void* clientData )
|
||||
@@ -204,13 +188,13 @@ void wxChoice::Clear()
|
||||
|
||||
if (m_clientDataItemsType == ClientData_Object)
|
||||
{
|
||||
wxNode *node = m_clientList.First();
|
||||
wxNode *node = m_clientList.First();
|
||||
while (node)
|
||||
{
|
||||
wxClientData *cd = (wxClientData*)node->Data();
|
||||
if (cd) delete cd;
|
||||
node = node->Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_clientList.Clear();
|
||||
}
|
||||
@@ -374,4 +358,56 @@ void wxChoice::ApplyWidgetStyle()
|
||||
}
|
||||
}
|
||||
|
||||
size_t wxChoice::AppendHelper(GtkWidget *menu, const wxString& item)
|
||||
{
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label( item.mbc_str() );
|
||||
|
||||
size_t index;
|
||||
if ( m_strings )
|
||||
{
|
||||
// sorted control, need to insert at the correct index
|
||||
index = m_strings->Add(item);
|
||||
|
||||
gtk_menu_insert( GTK_MENU(menu), menu_item, index );
|
||||
|
||||
if ( index )
|
||||
{
|
||||
m_clientList.Insert( m_clientList.Item(index - 1),
|
||||
(wxObject*) NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// can't use Insert() :-(
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal control, just append
|
||||
gtk_menu_append( GTK_MENU(menu), menu_item );
|
||||
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
|
||||
// don't call wxChoice::GetCount() from here because it doesn't work
|
||||
// if we're called from ctor (and GtkMenuShell is still NULL)
|
||||
index = m_clientList.GetCount();
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_REALIZED(m_widget))
|
||||
{
|
||||
gtk_widget_realize( menu_item );
|
||||
gtk_widget_realize( GTK_BIN(menu_item)->child );
|
||||
|
||||
if (m_widgetStyle) ApplyWidgetStyle();
|
||||
}
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
|
||||
|
||||
gtk_widget_show( menu_item );
|
||||
|
||||
// return the index of the item in the control
|
||||
return index;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -38,7 +38,7 @@ extern bool g_blockEventsOnDrag;
|
||||
|
||||
static void gtk_choice_clicked_callback( GtkWidget *WXUNUSED(widget), wxChoice *choice )
|
||||
{
|
||||
if (g_isIdle)
|
||||
if (g_isIdle)
|
||||
wxapp_install_idle_handler();
|
||||
|
||||
if (!choice->m_hasVMT) return;
|
||||
@@ -60,6 +60,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxChoice,wxControl)
|
||||
|
||||
wxChoice::wxChoice()
|
||||
{
|
||||
m_strings = (wxSortedArrayString *)NULL;
|
||||
}
|
||||
|
||||
bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
@@ -76,7 +77,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
!CreateBase( parent, id, pos, size, style, validator, name ))
|
||||
{
|
||||
wxFAIL_MSG( wxT("wxChoice creation failed") );
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_widget = gtk_option_menu_new();
|
||||
@@ -88,20 +89,20 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
newSize.y = 26;
|
||||
SetSize( newSize.x, newSize.y );
|
||||
|
||||
if ( style & wxCB_SORT )
|
||||
{
|
||||
// if our m_strings != NULL, DoAppend() will check for it and insert
|
||||
// items in the correct order
|
||||
m_strings = new wxSortedArrayString;
|
||||
}
|
||||
|
||||
GtkWidget *menu = gtk_menu_new();
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
|
||||
GtkWidget *item = gtk_menu_item_new_with_label( choices[i].mbc_str() );
|
||||
gtk_menu_append( GTK_MENU(menu), item );
|
||||
|
||||
gtk_widget_show( item );
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT( item ), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
|
||||
AppendHelper(menu, choices[i]);
|
||||
}
|
||||
|
||||
gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
|
||||
|
||||
m_parent->DoAddChild( this );
|
||||
@@ -120,6 +121,8 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
||||
wxChoice::~wxChoice()
|
||||
{
|
||||
Clear();
|
||||
|
||||
delete m_strings;
|
||||
}
|
||||
|
||||
int wxChoice::DoAppend( const wxString &item )
|
||||
@@ -127,27 +130,8 @@ int wxChoice::DoAppend( const wxString &item )
|
||||
wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice") );
|
||||
|
||||
GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label( item.mbc_str() );
|
||||
|
||||
gtk_menu_append( GTK_MENU(menu), menu_item );
|
||||
|
||||
if (GTK_WIDGET_REALIZED(m_widget))
|
||||
{
|
||||
gtk_widget_realize( menu_item );
|
||||
gtk_widget_realize( GTK_BIN(menu_item)->child );
|
||||
|
||||
if (m_widgetStyle) ApplyWidgetStyle();
|
||||
}
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
|
||||
|
||||
gtk_widget_show( menu_item );
|
||||
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
|
||||
// return the index of the item in the control
|
||||
return GetCount() - 1;
|
||||
return AppendHelper(menu, item);
|
||||
}
|
||||
|
||||
void wxChoice::DoSetClientData( int n, void* clientData )
|
||||
@@ -204,13 +188,13 @@ void wxChoice::Clear()
|
||||
|
||||
if (m_clientDataItemsType == ClientData_Object)
|
||||
{
|
||||
wxNode *node = m_clientList.First();
|
||||
wxNode *node = m_clientList.First();
|
||||
while (node)
|
||||
{
|
||||
wxClientData *cd = (wxClientData*)node->Data();
|
||||
if (cd) delete cd;
|
||||
node = node->Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_clientList.Clear();
|
||||
}
|
||||
@@ -374,4 +358,56 @@ void wxChoice::ApplyWidgetStyle()
|
||||
}
|
||||
}
|
||||
|
||||
size_t wxChoice::AppendHelper(GtkWidget *menu, const wxString& item)
|
||||
{
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label( item.mbc_str() );
|
||||
|
||||
size_t index;
|
||||
if ( m_strings )
|
||||
{
|
||||
// sorted control, need to insert at the correct index
|
||||
index = m_strings->Add(item);
|
||||
|
||||
gtk_menu_insert( GTK_MENU(menu), menu_item, index );
|
||||
|
||||
if ( index )
|
||||
{
|
||||
m_clientList.Insert( m_clientList.Item(index - 1),
|
||||
(wxObject*) NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// can't use Insert() :-(
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal control, just append
|
||||
gtk_menu_append( GTK_MENU(menu), menu_item );
|
||||
|
||||
m_clientList.Append( (wxObject*) NULL );
|
||||
|
||||
// don't call wxChoice::GetCount() from here because it doesn't work
|
||||
// if we're called from ctor (and GtkMenuShell is still NULL)
|
||||
index = m_clientList.GetCount();
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_REALIZED(m_widget))
|
||||
{
|
||||
gtk_widget_realize( menu_item );
|
||||
gtk_widget_realize( GTK_BIN(menu_item)->child );
|
||||
|
||||
if (m_widgetStyle) ApplyWidgetStyle();
|
||||
}
|
||||
|
||||
gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
|
||||
GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
|
||||
|
||||
gtk_widget_show( menu_item );
|
||||
|
||||
// return the index of the item in the control
|
||||
return index;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user