fixed gtk2 combobox to use only one gtkrenderertext and not one for each item. It should improve loading a large list of items into a combobox

git-svn-id: trunk@12571 -
This commit is contained in:
andrew 2007-10-24 00:33:52 +00:00
parent 0c359236ac
commit 35e76c1971
3 changed files with 25 additions and 49 deletions

View File

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

View File

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

View File

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