mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-07 12:16:20 +02:00
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:
parent
0c359236ac
commit
35e76c1971
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user