diff --git a/contrib/src/stc/PlatWX.cpp b/contrib/src/stc/PlatWX.cpp index 7211cb06b8..e0eeab7d98 100644 --- a/contrib/src/stc/PlatWX.cpp +++ b/contrib/src/stc/PlatWX.cpp @@ -9,6 +9,11 @@ #include "Platform.h" #include "wx/stc/stc.h" + +#ifdef __WXGTK__ +#include +#endif + Point Point::FromLong(long lpoint) { return Point(lpoint & 0xFFFF, lpoint >> 16); } @@ -458,16 +463,65 @@ public: event.Skip(); } +#ifdef __WXGTK__ + void DoSetFirstItem(int n); +#endif + private: DECLARE_EVENT_TABLE() }; - BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox) EVT_SET_FOCUS(wxSTCListBox::OnFocus) END_EVENT_TABLE() + + +#ifdef __WXGTK__ + // This can be removed after 2.2.2 I think +void wxSTCListBox::DoSetFirstItem( int n ) +{ + wxCHECK_RET( m_list, wxT("invalid listbox") ); + + if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (m_list)) + return; + + // terribly efficient + const gchar *vadjustment_key = "gtk-vadjustment"; + guint vadjustment_key_id = g_quark_from_static_string (vadjustment_key); + + GtkAdjustment *adjustment = + (GtkAdjustment*) gtk_object_get_data_by_id (GTK_OBJECT (m_list), vadjustment_key_id); + wxCHECK_RET( adjustment, wxT("invalid listbox code") ); + + GList *target = g_list_nth( m_list->children, n ); + wxCHECK_RET( target, wxT("invalid listbox index") ); + + GtkWidget *item = GTK_WIDGET(target->data); + wxCHECK_RET( item, wxT("invalid listbox code") ); + + // find the last item before this one which is already realized + size_t nItemsBefore; + for ( nItemsBefore = 0; item && (item->allocation.y == -1); nItemsBefore++ ) + { + target = target->prev; + if ( !target ) + { + // nothing we can do if there are no allocated items yet + return; + } + + item = GTK_WIDGET(target->data); + } + + gtk_adjustment_set_value(adjustment, + item->allocation.y + + nItemsBefore*item->allocation.height); +} +#endif + + ListBox::ListBox() { } @@ -476,8 +530,8 @@ ListBox::~ListBox() { void ListBox::Create(Window &parent, int ctrlID) { id = new wxSTCListBox(parent.id, ctrlID); - //id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize, - // 0, NULL, wxLB_SINGLE | wxLB_SORT | wxSIMPLE_BORDER); +// id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize, +// 0, NULL, wxLB_SINGLE | wxLB_SORT | wxSIMPLE_BORDER); } PRectangle ListBox::GetDesiredRect() { @@ -517,6 +571,13 @@ int ListBox::Length() { void ListBox::Select(int n) { ((wxListBox*)id)->SetSelection(n); +#ifdef __WXGTK__ + if (n > 4) + n = n - 4; + else + n = 1; + ((wxListBox*)id)->SetFirstItem(n); +#endif } int ListBox::GetSelection() { diff --git a/contrib/src/stc/ScintillaWX.cpp b/contrib/src/stc/ScintillaWX.cpp index 650921ee5a..f7349c8d27 100644 --- a/contrib/src/stc/ScintillaWX.cpp +++ b/contrib/src/stc/ScintillaWX.cpp @@ -315,6 +315,11 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) { FullPaint(); } paintState = notPainting; +#ifdef __WXGTK__ + // On wxGTK the editor window paints can overwrite the listbox... + if (ac.Active()) + ((wxWindow*)ac.lb.GetID())->Refresh(TRUE); +#endif } diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 7211cb06b8..e0eeab7d98 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -9,6 +9,11 @@ #include "Platform.h" #include "wx/stc/stc.h" + +#ifdef __WXGTK__ +#include +#endif + Point Point::FromLong(long lpoint) { return Point(lpoint & 0xFFFF, lpoint >> 16); } @@ -458,16 +463,65 @@ public: event.Skip(); } +#ifdef __WXGTK__ + void DoSetFirstItem(int n); +#endif + private: DECLARE_EVENT_TABLE() }; - BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox) EVT_SET_FOCUS(wxSTCListBox::OnFocus) END_EVENT_TABLE() + + +#ifdef __WXGTK__ + // This can be removed after 2.2.2 I think +void wxSTCListBox::DoSetFirstItem( int n ) +{ + wxCHECK_RET( m_list, wxT("invalid listbox") ); + + if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (m_list)) + return; + + // terribly efficient + const gchar *vadjustment_key = "gtk-vadjustment"; + guint vadjustment_key_id = g_quark_from_static_string (vadjustment_key); + + GtkAdjustment *adjustment = + (GtkAdjustment*) gtk_object_get_data_by_id (GTK_OBJECT (m_list), vadjustment_key_id); + wxCHECK_RET( adjustment, wxT("invalid listbox code") ); + + GList *target = g_list_nth( m_list->children, n ); + wxCHECK_RET( target, wxT("invalid listbox index") ); + + GtkWidget *item = GTK_WIDGET(target->data); + wxCHECK_RET( item, wxT("invalid listbox code") ); + + // find the last item before this one which is already realized + size_t nItemsBefore; + for ( nItemsBefore = 0; item && (item->allocation.y == -1); nItemsBefore++ ) + { + target = target->prev; + if ( !target ) + { + // nothing we can do if there are no allocated items yet + return; + } + + item = GTK_WIDGET(target->data); + } + + gtk_adjustment_set_value(adjustment, + item->allocation.y + + nItemsBefore*item->allocation.height); +} +#endif + + ListBox::ListBox() { } @@ -476,8 +530,8 @@ ListBox::~ListBox() { void ListBox::Create(Window &parent, int ctrlID) { id = new wxSTCListBox(parent.id, ctrlID); - //id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize, - // 0, NULL, wxLB_SINGLE | wxLB_SORT | wxSIMPLE_BORDER); +// id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize, +// 0, NULL, wxLB_SINGLE | wxLB_SORT | wxSIMPLE_BORDER); } PRectangle ListBox::GetDesiredRect() { @@ -517,6 +571,13 @@ int ListBox::Length() { void ListBox::Select(int n) { ((wxListBox*)id)->SetSelection(n); +#ifdef __WXGTK__ + if (n > 4) + n = n - 4; + else + n = 1; + ((wxListBox*)id)->SetFirstItem(n); +#endif } int ListBox::GetSelection() { diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index 650921ee5a..f7349c8d27 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -315,6 +315,11 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) { FullPaint(); } paintState = notPainting; +#ifdef __WXGTK__ + // On wxGTK the editor window paints can overwrite the listbox... + if (ac.Active()) + ((wxWindow*)ac.lb.GetID())->Refresh(TRUE); +#endif }