mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-21 05:01:50 +02:00
gtk2 intf: added custom cellrenderer for finer control of TListBox
git-svn-id: trunk@9551 -
This commit is contained in:
parent
823f5330a4
commit
f488b7ca3f
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2211,6 +2211,7 @@ lcl/interfaces/gtk/tests/lclclipboardunit.lfm svneol=native#text/plain
|
|||||||
lcl/interfaces/gtk/tests/lclclipboardunit.lrs svneol=native#text/plain
|
lcl/interfaces/gtk/tests/lclclipboardunit.lrs svneol=native#text/plain
|
||||||
lcl/interfaces/gtk/tests/lclclipboardunit.pas svneol=native#text/plain
|
lcl/interfaces/gtk/tests/lclclipboardunit.pas svneol=native#text/plain
|
||||||
lcl/interfaces/gtk/tnotebook_close_tab.xpm -text svneol=native#image/x-xpixmap
|
lcl/interfaces/gtk/tnotebook_close_tab.xpm -text svneol=native#image/x-xpixmap
|
||||||
|
lcl/interfaces/gtk2/gtk2cellrenderer.pas svneol=native#text/plain
|
||||||
lcl/interfaces/gtk2/gtk2int.pas svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2int.pas svneol=native#text/pascal
|
||||||
lcl/interfaces/gtk2/gtk2interface.lpk svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2interface.lpk svneol=native#text/pascal
|
||||||
lcl/interfaces/gtk2/gtk2interface.pas svneol=native#text/pascal
|
lcl/interfaces/gtk2/gtk2interface.pas svneol=native#text/pascal
|
||||||
|
@ -43,8 +43,7 @@ end;
|
|||||||
procedure TCustomListBox.Loaded;
|
procedure TCustomListBox.Loaded;
|
||||||
begin
|
begin
|
||||||
inherited Loaded;
|
inherited Loaded;
|
||||||
if HandleAllocated then
|
if HandleAllocated then begin
|
||||||
begin
|
|
||||||
LockSelectionChange;
|
LockSelectionChange;
|
||||||
SendItemIndex;
|
SendItemIndex;
|
||||||
UnlockSelectionChange;
|
UnlockSelectionChange;
|
||||||
|
190
lcl/interfaces/gtk2/gtk2cellrenderer.pas
Normal file
190
lcl/interfaces/gtk2/gtk2cellrenderer.pas
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
{ $Id: gtk2wsstdctrls.pp 9520 2006-06-28 21:26:52Z mattias $}
|
||||||
|
{
|
||||||
|
*****************************************************************************
|
||||||
|
* Gtk2CellRenderer.pas *
|
||||||
|
* -------------------- *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
*****************************************************************************
|
||||||
|
* *
|
||||||
|
* This file is part of the Lazarus Component Library (LCL) *
|
||||||
|
* *
|
||||||
|
* See the file COPYING.modifiedLGPL, included in this distribution, *
|
||||||
|
* for details about the copyright. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* *
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
An extended gtk_cell_renderer, to provide hooks for the LCL.
|
||||||
|
For example for custom drawing.
|
||||||
|
|
||||||
|
}
|
||||||
|
unit Gtk2CellRenderer;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, LCLType, LCLProc, Controls, StdCtrls, LMessages,
|
||||||
|
Gtk2Int, gtk2, gdk2, glib2, GtkProc, GtkDef;
|
||||||
|
|
||||||
|
type
|
||||||
|
PLCLIntfCellRenderer = ^TLCLIntfCellRenderer;
|
||||||
|
TLCLIntfCellRenderer = record
|
||||||
|
// ! the TextRenderer must be the first attribute of this record !
|
||||||
|
TextRenderer: TGtkCellRendererText;
|
||||||
|
ItemIndex: integer; // for TCustomListBox: the ItemIndex of the cell
|
||||||
|
end;
|
||||||
|
|
||||||
|
PLCLIntfCellRendererClass = ^TLCLIntfCellRendererClass;
|
||||||
|
TLCLIntfCellRendererClass = record
|
||||||
|
ParentClass: TGtkCellRendererTextClass;
|
||||||
|
DefaultGtkRender : procedure (cell:PGtkCellRenderer; window:PGdkWindow;
|
||||||
|
widget:PGtkWidget; background_area:PGdkRectangle;
|
||||||
|
cell_area:PGdkRectangle;
|
||||||
|
expose_area:PGdkRectangle; flags:TGtkCellRendererState); cdecl;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LCLIntfCellRenderer_GetType: TGtkType;
|
||||||
|
function LCLIntfCellRenderer_New: PGtkCellRenderer;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure LCLIntfCellRenderer_Render(cell: PGtkCellRenderer; Window: PGdkWindow;
|
||||||
|
Widget: PGtkWidget; background_area: PGdkRectangle; cell_area: PGdkRectangle;
|
||||||
|
expose_area: PGdkRectangle; flags: TGtkCellRendererState); cdecl;
|
||||||
|
var
|
||||||
|
CellClass: PLCLIntfCellRendererClass;
|
||||||
|
WidgetInfo: PWidgetInfo;
|
||||||
|
LCLObject: TObject;
|
||||||
|
MainWidget: PGtkWidget;
|
||||||
|
AWinControl: TWinControl;
|
||||||
|
ItemIndex: Integer;
|
||||||
|
AreaRect: TRect;
|
||||||
|
State: TBaseOwnerDrawState;
|
||||||
|
Msg: TLMDrawListItem;
|
||||||
|
begin
|
||||||
|
DebugLn(['LCLIntfCellRenderer_Render cell=',dbgs(cell),
|
||||||
|
' ',GetWidgetDebugReport(Widget),' ',
|
||||||
|
' background_area=',dbgGRect(background_area),
|
||||||
|
' cell_area=',dbgGRect(cell_area),
|
||||||
|
' expose_area=',dbgGRect(expose_area)]);
|
||||||
|
// draw default
|
||||||
|
CellClass:=PLCLIntfCellRendererClass(gtk_object_get_class(cell));
|
||||||
|
CellClass^.DefaultGtkRender(cell,Window,Widget,background_area,cell_area,
|
||||||
|
expose_area,flags);
|
||||||
|
// send LM_DrawListItem message
|
||||||
|
MainWidget:=GetMainWidget(Widget);
|
||||||
|
if MainWidget=nil then exit;
|
||||||
|
WidgetInfo:=GetWidgetInfo(MainWidget,false);
|
||||||
|
if WidgetInfo=nil then exit;
|
||||||
|
LCLObject:=WidgetInfo^.LCLObject; // the listbox
|
||||||
|
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
|
||||||
|
exit;
|
||||||
|
if AWinControl is TCustomCombobox then
|
||||||
|
if TCustomCombobox(AWinControl).Style < csOwnerDrawFixed then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
// get itemindex and area
|
||||||
|
ItemIndex:=0; // ToDo
|
||||||
|
//Model:=PGtkTreeModel(gtk_tree_view_get_model(PGtkTreeView(Widget)));
|
||||||
|
//gtk_tree_model_get(Model);
|
||||||
|
|
||||||
|
AreaRect:=Bounds(background_area^.x,background_area^.y,
|
||||||
|
background_area^.Width,background_area^.Height);
|
||||||
|
|
||||||
|
// collect state flags
|
||||||
|
State:=[odPainted];
|
||||||
|
if (flags and GTK_CELL_RENDERER_SELECTED)>0 then
|
||||||
|
Include(State,odSelected);
|
||||||
|
if not GTK_WIDGET_SENSITIVE(Widget) then
|
||||||
|
Include(State,odInactive);
|
||||||
|
if GTK_WIDGET_HAS_DEFAULT(Widget) then
|
||||||
|
Include(State,odDefault);
|
||||||
|
if GTK_WIDGET_HAS_FOCUS(Widget) then
|
||||||
|
Include(State,odFocused);
|
||||||
|
|
||||||
|
// create message and deliver
|
||||||
|
FillChar(Msg,SizeOf(Msg),0);
|
||||||
|
Msg.Msg:=LM_DrawListItem;
|
||||||
|
New(Msg.DrawListItemStruct);
|
||||||
|
try
|
||||||
|
FillChar(Msg.DrawListItemStruct^,SizeOf(TDrawListItemStruct),0);
|
||||||
|
with Msg.DrawListItemStruct^ do begin
|
||||||
|
ItemID:=ItemIndex;
|
||||||
|
Area:=AreaRect;
|
||||||
|
DC:=GTK2WidgetSet.CreateDCForWidget(Widget,Window,false);
|
||||||
|
ItemState:=State;
|
||||||
|
end;
|
||||||
|
DeliverMessage(AWinControl, Msg);
|
||||||
|
GTK2WidgetSet.ReleaseDC(HWnd(Widget),Msg.DrawListItemStruct^.DC);
|
||||||
|
finally
|
||||||
|
Dispose(Msg.DrawListItemStruct);
|
||||||
|
end;
|
||||||
|
|
||||||
|
DebugLn(['LCLIntfCellRenderer_Render END ',DbgSName(LCLObject)]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure LCLIntfCellRenderer_ClassInit(aClass: Pointer); cdecl;
|
||||||
|
//aClass: PLCLIntfCellRendererClass
|
||||||
|
var
|
||||||
|
LCLClass: PLCLIntfCellRendererClass;
|
||||||
|
RendererClass: PGtkCellRendererClass;
|
||||||
|
begin
|
||||||
|
DebugLn(['LCLIntfCellRenderer_ClassInit ']);
|
||||||
|
LCLClass:=PLCLIntfCellRendererClass(aClass);
|
||||||
|
RendererClass:=GTK_CELL_RENDERER_CLASS(aClass);
|
||||||
|
LCLClass^.DefaultGtkRender:=RendererClass^.render;
|
||||||
|
RendererClass^.render:=@LCLIntfCellRenderer_Render;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure LCLIntfCellRenderer_Init(Instance:PGTypeInstance;
|
||||||
|
theClass: Pointer); cdecl;
|
||||||
|
// Instance: PLCLIntfCellRenderer;
|
||||||
|
// theClass: PLCLIntfCellRendererClass
|
||||||
|
begin
|
||||||
|
DebugLn(['LCLIntfCellRenderer_Init ']);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LCLIntfCellRenderer_GetType: TGtkType;
|
||||||
|
const
|
||||||
|
CR_NAME = 'LCLIntfCellRenderer';
|
||||||
|
crType: TGtkType = 0;
|
||||||
|
crInfo: TGTKTypeInfo = (
|
||||||
|
type_name: CR_NAME;
|
||||||
|
object_size: SizeOf(TLCLIntfCellRenderer)+100; // a TLCLIntfCellRenderer
|
||||||
|
class_size: SizeOf(TLCLIntfCellRendererClass)+100;
|
||||||
|
class_init_func: @LCLIntfCellRenderer_ClassInit;
|
||||||
|
object_init_func : @LCLIntfCellRenderer_Init;
|
||||||
|
reserved_1: nil;
|
||||||
|
reserved_2: nil;
|
||||||
|
base_class_init_func: nil;
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
if (crType = 0)
|
||||||
|
then begin
|
||||||
|
crType := gtk_type_from_name(CR_NAME);
|
||||||
|
if crType = 0
|
||||||
|
then crType := gtk_type_unique(gtk_cell_renderer_text_get_type, @crInfo);
|
||||||
|
end;
|
||||||
|
Result := crType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LCLIntfCellRenderer_New: PGtkCellRenderer;
|
||||||
|
begin
|
||||||
|
Result := g_object_new(LCLIntfCellRenderer_GetType, nil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -38,8 +38,7 @@ uses
|
|||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
glib2, gdk2, gtk2, Pango,
|
glib2, gdk2, gtk2, Pango,
|
||||||
WSStdCtrls, WSLCLClasses, GtkWSStdCtrls, Gtk2Int, LCLType, GtkDef, LCLProc,
|
WSStdCtrls, WSLCLClasses, GtkWSStdCtrls, Gtk2Int, LCLType, GtkDef, LCLProc,
|
||||||
//Gtk2CellRenderer,
|
Gtk2CellRenderer, GTKWinApiWindow, gtkglobals, gtkproc, InterfaceBase;
|
||||||
GTKWinApiWindow, gtkglobals, gtkproc, InterfaceBase;
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -309,18 +308,15 @@ begin
|
|||||||
ListStoreModel := gtk_tree_view_get_model(PGtkTreeView(Widget));
|
ListStoreModel := gtk_tree_view_get_model(PGtkTreeView(Widget));
|
||||||
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
||||||
|
|
||||||
if gtk_tree_model_iter_nth_child(ListStoreModel, @Iter, nil, AnIndex) then begin
|
if gtk_tree_model_iter_nth_child(ListStoreModel, @Iter, nil, AnIndex) then
|
||||||
|
begin
|
||||||
case ASelected of
|
case ASelected of
|
||||||
True:
|
True:
|
||||||
begin
|
|
||||||
if not gtk_tree_selection_iter_is_selected(Selection, @Iter) then
|
if not gtk_tree_selection_iter_is_selected(Selection, @Iter) then
|
||||||
gtk_tree_selection_select_iter(Selection, @Iter);
|
gtk_tree_selection_select_iter(Selection, @Iter);
|
||||||
end;
|
|
||||||
False:
|
False:
|
||||||
begin
|
|
||||||
if gtk_tree_selection_iter_is_selected(Selection, @Iter) then
|
if gtk_tree_selection_iter_is_selected(Selection, @Iter) then
|
||||||
gtk_tree_selection_unselect_iter(Selection, @Iter);
|
gtk_tree_selection_unselect_iter(Selection, @Iter);
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -438,7 +434,7 @@ begin
|
|||||||
TempWidget:= gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
|
TempWidget:= gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
|
||||||
g_object_unref (G_OBJECT (liststore));
|
g_object_unref (G_OBJECT (liststore));
|
||||||
|
|
||||||
renderer := gtk_cell_renderer_text_new;// LCLIntfCellRenderer_New();
|
renderer := LCLIntfCellRenderer_New();
|
||||||
column := gtk_tree_view_column_new_with_attributes ('LISTITEMS', renderer,
|
column := gtk_tree_view_column_new_with_attributes ('LISTITEMS', renderer,
|
||||||
['text', 0, nil]);
|
['text', 0, nil]);
|
||||||
gtk_tree_view_append_column (GTK_TREE_VIEW (TempWidget), column);
|
gtk_tree_view_append_column (GTK_TREE_VIEW (TempWidget), column);
|
||||||
@ -535,8 +531,9 @@ begin
|
|||||||
begin
|
begin
|
||||||
Widget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
|
Widget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
|
||||||
Result := TGtkListStoreStringList.Create(
|
Result := TGtkListStoreStringList.Create(
|
||||||
gtk_tree_view_get_model(PGtkTreeView(Widget)),
|
gtk_tree_view_get_model(PGtkTreeView(Widget)),
|
||||||
Ord(ACustomListBox.fCompStyle = csCheckListBox) ,ACustomListBox);
|
Ord(ACustomListBox.fCompStyle = csCheckListBox),
|
||||||
|
ACustomListBox);
|
||||||
TGtkListStoreStringList(Result).Sorted := ACustomListBox.Sorted;
|
TGtkListStoreStringList(Result).Sorted := ACustomListBox.Sorted;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
|
@ -27,12 +27,17 @@
|
|||||||
<MinVersion Major="1" Valid="True"/>
|
<MinVersion Major="1" Valid="True"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="1">
|
<Units Count="2">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="test3_2listboxdrawitem.lpr"/>
|
<Filename Value="test3_2listboxdrawitem.lpr"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="test3_2listboxdrawitem"/>
|
<UnitName Value="test3_2listboxdrawitem"/>
|
||||||
</Unit0>
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="test3_1listboxdrawitem.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="test3_1listboxdrawitem"/>
|
||||||
|
</Unit1>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
Loading…
Reference in New Issue
Block a user