diff --git a/lcl/interfaces/gtk2/gtk2cellrenderer.pas b/lcl/interfaces/gtk2/gtk2cellrenderer.pas index 0d2f6dac30..d960358f48 100644 --- a/lcl/interfaces/gtk2/gtk2cellrenderer.pas +++ b/lcl/interfaces/gtk2/gtk2cellrenderer.pas @@ -55,6 +55,7 @@ function LCLIntfCellRenderer_GetType: TGtkType; function LCLIntfCellRenderer_New: PGtkCellRenderer; implementation +uses GtkExtra; procedure LCLIntfCellRenderer_Render(cell: PGtkCellRenderer; Window: PGdkWindow; Widget: PGtkWidget; background_area: PGdkRectangle; cell_area: PGdkRectangle; @@ -71,8 +72,6 @@ var Msg: TLMDrawListItem; ItemPath: PGtkTreePath; Column: PGtkTreeViewColumn; - Menu: PGtkMenuShell; - MenuItem: PGtkMenuItem; DCWidget: PGtkWidget; begin {DebugLn(['LCLIntfCellRenderer_Render cell=',dbgs(cell), @@ -90,11 +89,12 @@ begin MainWidget:=GetMainWidget(Widget); if MainWidget=nil then exit; WidgetInfo:=GetWidgetInfo(MainWidget,false); + if WidgetInfo=nil then WidgetInfo:=GetWidgetInfo(cell,false); if WidgetInfo=nil then exit; LCLObject:=WidgetInfo^.LCLObject; // the listbox or combobox AWinControl:=LCLObject as TWinControl; if [csDestroying,csLoading]*AWinControl.ComponentState<>[] then exit; - + // check if the LCL object wants item paint messages if AWinControl is TCustomListbox then if TCustomListbox(AWinControl).Style = lbStandard then @@ -122,25 +122,22 @@ begin end; end else if AWinControl is TCustomComboBox then begin - // ComboItem is set in gtk2wsstdctrls - MenuItem := g_object_get_data(G_OBJECT(cell), 'ComboItem'); - if MenuItem <> nil then begin - Menu := PGtkMenuShell(gtk_widget_get_parent(PGtkWidget(MenuItem))); - if Menu <> nil then - ItemIndex := g_list_index(Menu^.children, MenuItem); - if ItemIndex > -1 then begin + ItemPath := gtk_cell_view_get_displayed_row(Widget); + if ItemPath <> nil then + begin + ItemIndex := StrToInt(gtk_tree_path_to_string(ItemPath)); + gtk_tree_path_free(ItemPath); + if (Widget^.parent <> nil) and (GtkWidgetIsA(Widget^.parent,gtk_menu_item_get_type)) then AreaRect:=Bounds(0,0, - PGtkWidget(MenuItem)^.allocation.width, - PGtkWidget(MenuItem)^.allocation.height); - end; - end - else begin // it is a renderer not in the dropdown but the combo renderer itself - ItemIndex := TCustomComboBox(AWinControl).ItemIndex; - AreaRect:=Bounds(0,0, Widget^.allocation.Width, Widget^.allocation.height); + Widget^.Parent^.allocation.width, + Widget^.Parent^.allocation.height) + else + AreaRect:=Bounds(0,0, + Widget^.allocation.width, + Widget^.allocation.height); end; - end; - + if ItemIndex < 0 then ItemIndex := 0; // collect state flags diff --git a/lcl/interfaces/gtk2/gtk2extrah.inc b/lcl/interfaces/gtk2/gtk2extrah.inc index a6ee7388e8..a389e363cf 100644 --- a/lcl/interfaces/gtk2/gtk2extrah.inc +++ b/lcl/interfaces/gtk2/gtk2extrah.inc @@ -52,6 +52,9 @@ type PPPangoAttrList = ^PPangoAttrList; procedure gtk_im_context_get_preedit_string_laz(context:PGtkIMContext; str:PPgchar; attrs:PPPangoAttrList; cursor_pos:Pgint); cdecl; external gtklib name 'gtk_im_context_get_preedit_string'; +// gtk 2.6 +function gtk_cell_view_get_displayed_row(cell_view: Pointer): PGtkTreePath; cdecl; external; + // gdk 2.2 procedure gdk_display_get_pointer(display : PGdkDisplay; screen :PGdkScreen; x :Pgint; y : Pgint; mask : PGdkModifierType); cdecl; external gdklib; diff --git a/lcl/interfaces/gtk2/gtk2wsstdctrls.pp b/lcl/interfaces/gtk2/gtk2wsstdctrls.pp index 8c579f81a9..b4ff1a64dc 100644 --- a/lcl/interfaces/gtk2/gtk2wsstdctrls.pp +++ b/lcl/interfaces/gtk2/gtk2wsstdctrls.pp @@ -103,7 +103,7 @@ type private protected class procedure ReCreateCombo(const ACustomComboBox: TCustomComboBox; const AWithEntry: Boolean; const AWidgetInfo: PWidgetInfo); virtual; - class procedure SetRenderer(const ACustomComboBox: TCustomComboBox; AWidget: PGtkWidget); virtual; + class procedure SetRenderer(const ACustomComboBox: TCustomComboBox; AWidget: PGtkWidget; AWidgetInfo: PWidgetInfo); virtual; class procedure SetCallbacks(const AWinControl: tWinControl; const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; public class function GetSelStart(const ACustomComboBox: TCustomComboBox): integer; override; @@ -845,7 +845,7 @@ begin SetReadOnly(ACustomComboBox, ACustomComboBox.ReadOnly); end; - SetRenderer(ACustomComboBox, ComboWidget); + SetRenderer(ACustomComboBox, ComboWidget, AWidgetInfo); gtk_container_add(PGtkContainer(AWidgetInfo^.ClientWidget), ComboWidget); gtk_widget_show_all(AWidgetInfo^.ClientWidget); @@ -854,45 +854,21 @@ begin end; class procedure TGtk2WSCustomComboBox.SetRenderer( - const ACustomComboBox: TCustomComboBox; AWidget: PGtkWidget); + const ACustomComboBox: TCustomComboBox; AWidget: PGtkWidget; AWidgetInfo: PWidgetInfo); var renderer : PGtkCellRenderer; begin renderer := LCLIntfCellRenderer_New(); + g_object_set_data(G_OBJECT(renderer), 'widgetinfo', AWidgetInfo); gtk_cell_layout_clear(PGtkCellLayout(AWidget)); gtk_cell_layout_pack_start(PGtkCellLayout(AWidget), renderer, True); gtk_cell_layout_set_attributes(PGtkCellLayout(AWidget), renderer, ['text', 0, nil]); end; -procedure UpdateComboItemsCB(AComboItem: PGtkBin; WidgetInfo: PWidgetInfo); cdecl; -var - renderer : PGtkCellRenderer; - AItem: PGtkCellLayout; - // AItem is really a GtkCellView which implements GtkCellRenderer -begin - AItem := PGtkCellLayout(AComboItem^.child); - //WriteLn(G_OBJECT_CLASS_NAME(GTK_WIDGET_GET_CLASS(PGtkWidget(AItem)))); - - if g_object_get_data(G_OBJECT(AItem), 'ComboItem') <> nil then exit; - - renderer := LCLIntfCellRenderer_New(); - gtk_cell_layout_clear(AItem); - gtk_cell_layout_pack_start(AItem, renderer, True); - gtk_cell_layout_set_attributes(AItem, renderer, ['text', 0, nil]); - SetMainWidget(WidgetInfo^.CoreWidget, AItem); - g_object_set_data(G_OBJECT(AItem), 'ComboItem', AComboItem); - // used in gtk2cellrenderer. if you change this update cellrenderer as well - AH - g_object_set_data(G_OBJECT(renderer), 'ComboItem', AComboItem); -end; - procedure GtkPopupShowCB(AMenu: PGtkMenuShell; WidgetInfo: PWidgetInfo); cdecl; begin // let the LCL change the items on the fly: LCLSendDropDownMsg(TControl(WidgetInfo^.LCLObject)); - - // here we insure that the combo's menu items are using our internal renderer - // so we can use custom drawing - g_list_foreach(AMenu^.children, TGFunc(@UpdateComboItemsCB), WidgetInfo); end; procedure GtkPopupHideCB(AMenu: PGtkMenuShell; WidgetInfo: PWidgetInfo); cdecl; @@ -1331,8 +1307,8 @@ begin gtk_container_add(PGtkContainer(Box), ComboWidget); gtk_widget_show_all(Box); - - SetRenderer(ACustomComboBox, ComboWidget); + + SetRenderer(ACustomComboBox, ComboWidget, WidgetInfo); SetMainWidget(Box, ComboWidget); SetMainWidget(Box, GTK_BIN(ComboWidget)^.child);