gtk3: implemented TCheckListBox handle - TGtk3CheckListBox

git-svn-id: trunk@42974 -
This commit is contained in:
zeljko 2013-09-27 08:47:13 +00:00
parent 347238c5e8
commit d31c6bc623
4 changed files with 192 additions and 174 deletions

View File

@ -230,6 +230,12 @@ const
// Used by TScrollbar, TScrollbox and TWinApiWidget
odnScrollBarLastPos = 'ScrollBarLastPos';
// checklistbox states
gtk3CLBState = 0; // byte
gtk3CLBText = 1; // PGChar
gtk3CLBDisabled = 3; // gboolean
function Gtk3IsObject(AWidget: PGObject): GBoolean;

View File

@ -49,7 +49,7 @@ type
wtContainer, wtMenuBar, wtMenu, wtMenuItem, wtEntry, wtSpinEdit,
wtNotebook, wtComboBox,
wtGroupBox, wtCalendar, wtTrackBar, wtScrollBar,
wtScrollingWin, wtListBox, wtListView, wtMemo, wtTreeModel,
wtScrollingWin, wtListBox, wtListView, wtCheckListBox, wtMemo, wtTreeModel,
wtCustomControl, wtScrollingWinControl,
wtWindow, wtDialog, wtHintWindow);
TGtk3WidgetTypes = set of TGtk3WidgetType;
@ -510,6 +510,13 @@ type
property ListBoxStyle: TListBoxStyle read FListBoxStyle write SetListBoxStyle;
end;
{ TGtk3CheckListBox }
TGtk3CheckListBox = class(TGtk3ListBox)
protected
function CreateWidget(const Params: TCreateParams): PGtkWidget; override;
end;
{ TGtk3ListView }
TGtk3ListView = class(TGtk3ScrollableWin)
@ -775,7 +782,8 @@ type
function Gtk3WidgetEvent(widget: PGtkWidget; event: PGdkEvent; data: GPointer): gboolean; cdecl;
implementation
uses Spin, gtk3int, gtk3procs, gtk3private, Gtk3CellRenderer, ExtDlgs, math;
uses Spin, gtk3int, gtk3procs, gtk3private, Gtk3CellRenderer, ExtDlgs, math,
CheckLst;
function Gtk3EventToStr(AEvent: TGdkEventType): String;
begin
@ -4850,6 +4858,147 @@ begin
APath^.free;
end;
{ TGtk3CheckListBox }
procedure Gtk3WS_CheckListBoxDataFunc({%H-}tree_column: PGtkTreeViewColumn;
cell: PGtkCellRenderer; tree_model: PGtkTreeModel; iter: PGtkTreeIter; {%H-}data: Pointer); cdecl;
var
b: byte;
ADisabled: gboolean;
AValue: TCheckBoxState;
begin
B := 0;
ADisabled := False;
gtk_tree_model_get(tree_model, iter, [gtk3CLBState, @b, -1]);
gtk_tree_model_get(tree_model, iter, [gtk3CLBDisabled, @ADisabled, -1]);
AValue := TCheckBoxState(b); // TCheckBoxState is 4 byte
g_object_set(cell, 'inconsistent', [gboolean(AValue = cbGrayed), nil]);
if AValue <> cbGrayed then
gtk_cell_renderer_toggle_set_active(PGtkCellRendererToggle(cell), AValue = cbChecked);
g_object_set(cell, 'activatable', [gboolean(not ADisabled), nil]);
end;
procedure Gtk3WS_CheckListBoxToggle({%H-}cellrenderertoggle : PGtkCellRendererToggle;
arg1 : PGChar; AData: GPointer); cdecl;
var
Mess: TLMessage;
Param: PtrInt;
Iter, IterParent : TGtkTreeIter;
TreeView: PGtkTreeView;
ListStore: PGtkTreeModel;
Path: PGtkTreePath;
AState: TCheckBoxState;
begin
Val(arg1, Param);
TreeView := PGtkTreeView(TGtk3CheckListBox(AData).GetContainerWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, Param) then
begin
TCustomCheckListBox(TGtk3Widget(AData).LCLObject).Toggle(Param);
AState := TCustomCheckListBox(TGtk3Widget(AData).LCLObject).State[Param];
gtk_list_store_set(PGtkListStore(ListStore), @Iter, [gtk3CLBState,
Byte(AState), -1]);
end;
Path := gtk_tree_path_new_from_indices(Param, [-1]);
if Path <> nil then
begin
gtk_tree_view_set_cursor(TreeView, Path, nil, False);
gtk_tree_path_free(Path);
end;
FillChar(Mess{%H-}, SizeOf(Mess), #0);
Mess.Msg := LM_CHANGED;
Mess.Result := 0;
Mess.WParam := Param;
DeliverMessage(TGtk3Widget(AData).LCLObject, Mess);
end;
function TGtk3CheckListBox.CreateWidget(const Params: TCreateParams
): PGtkWidget;
var
ACheckListBox: TCustomCheckListBox;
ListStore: PGtkListStore;
ItemList: TGtkListStoreStringList;
AColumn: PGtkTreeViewColumn;
Toggle: PGtkCellRendererToggle;
Renderer : PGtkCellRendererText;
VAdjust, HAdjust: PGtkAdjustment;
AScrollStyle: TPoint;
TreeModel: PGtkTreeModel;
begin
FScrollX := 0;
FScrollY := 0;
FWidgetType := FWidgetType + [wtTreeModel, wtListBox, wtCheckListBox, wtScrollingWin];
ACheckListBox := TCustomCheckListBox(LCLObject);
FListBoxStyle := lbStandard;
Result := PGtkScrolledWindow(TGtkScrolledWindow.new(nil, nil));
Result^.show;
ListStore := gtk_list_store_new (4, [G_TYPE_UCHAR, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, nil]);
FCentralWidget := TGtkTreeView.new_with_model(PGtkTreeModel(ListStore));
PGtkTreeView(FCentralWidget)^.set_headers_visible(False);
g_object_unref (liststore);
AColumn := gtk_tree_view_column_new;
// checkable column
Toggle := gtk_cell_renderer_toggle_new;
g_object_set_data(PGObject(Toggle), 'lclwidget', Self);
AColumn^.set_title('CHECKBINS');
AColumn^.pack_start(Toggle, True);
AColumn^.set_cell_data_func(Toggle, @Gtk3WS_CheckListBoxDataFunc, Self, nil);
Toggle^.set_active(True);
PGtkTreeView(FCentralWidget)^.append_column(AColumn);
AColumn^.set_clickable(True);
g_signal_connect_data(Toggle, 'toggled', TGCallback(@Gtk3WS_CheckListBoxToggle), Self, nil, 0);
Renderer := gtk_cell_renderer_text_new;
g_object_set_data(PGObject(Renderer), 'lclwidget', Self);
AColumn := gtk_tree_view_column_new_with_attributes ('LISTITEMS', Renderer,
['text', 1, nil]);
g_object_set_data(PGObject(AColumn), 'lclwidget', Self);
// AColumn^.pack_start(Renderer, True);
PGtkTreeView(FCentralWidget)^.append_column(AColumn);
ItemList := TGtkListStoreStringList.Create(PGtkListStore(PGtkTreeView(FCentralWidget)^.get_model), 1, LCLObject);
g_object_set_data(PGObject(FCentralWidget),GtkListItemLCLListTag, ItemList);
AColumn^.set_clickable(True);
// AColumn^set_cell_data_func(AColumn, renderer, @LCLIntfRenderer_ColumnCellDataFunc, Self, nil);
PGtkScrolledWindow(Result)^.add(FCentralWidget);
PGtkScrolledWindow(Result)^.get_vscrollbar^.set_can_focus(False);
PGtkScrolledWindow(Result)^.get_hscrollbar^.set_can_focus(False);
PGtkScrolledWindow(Result)^.set_policy(GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
FListBoxStyle := ACheckListBox.Style;
// AListBox.Style;
if FListBoxStyle <> lbOwnerDrawVariable then
begin
//AColumn^.set_sizing(GTK_TREE_VIEW_COLUMN_FIXED);
//PGtkTreeView(FCentralWidget)^.set_fixed_height_mode(True);
end;
end;
{ TGtk3ListView }
function Gtk3WS_ListViewItemPreSelected({%H-}selection: PGtkTreeSelection; {%H-}model: PGtkTreeModel;

View File

@ -22,6 +22,7 @@ interface
uses
LazGObject2, LazGtk3, LazGLib2,
gtk3widgets,
////////////////////////////////////////////////////
// I M P O R T A N T
////////////////////////////////////////////////////
@ -30,7 +31,7 @@ uses
////////////////////////////////////////////////////
CheckLst, StdCtrls, Controls, LCLType, SysUtils, Classes, LMessages, LCLProc,
////////////////////////////////////////////////////
WSCheckLst, WSLCLClasses;
WSCheckLst, WSLCLClasses, WSProc;
type
@ -57,151 +58,14 @@ implementation
uses
Gtk3WSControls, gtk3procs;
const
gtk3CLBState = 0; // byte
gtk3CLBText = 1; // PGChar
gtk3CLBDisabled = 3; // gboolean
{ TGtk2WSCheckListBox }
procedure Gtk3WS_CheckListBoxDataFunc({%H-}tree_column: PGtkTreeViewColumn;
cell: PGtkCellRenderer; tree_model: PGtkTreeModel; iter: PGtkTreeIter; {%H-}data: Pointer); cdecl;
var
b: byte;
ADisabled: gboolean;
AValue: TCheckBoxState;
begin
gtk_tree_model_get(tree_model, iter, [gtk3CLBState, @b, -1]);
gtk_tree_model_get(tree_model, iter, [gtk3CLBDisabled, @ADisabled, -1]);
AValue := TCheckBoxState(b); // TCheckBoxState is 4 byte
g_object_set(cell, 'inconsistent', [gboolean(AValue = cbGrayed), nil]);
if AValue <> cbGrayed then
gtk_cell_renderer_toggle_set_active(PGtkCellRendererToggle(cell), AValue = cbChecked);
g_object_set(cell, 'activatable', [gboolean(not ADisabled), nil]);
end;
(*
procedure Gtk3WS_CheckListBoxToggle({%H-}cellrenderertoggle : PGtkCellRendererToggle;
arg1 : PGChar; WidgetInfo: PWidgetInfo); cdecl;
var
Mess: TLMessage;
Param: PtrInt;
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
ListStore: PGtkTreeModel;
Path: PGtkTreePath;
AState: TCheckBoxState;
begin
{$IFDEF EventTrace}
EventTrace('Gtk2WS_CheckListBoxToggle', WidgetInfo^.LCLObject);
{$ENDIF}
Val(arg1, Param);
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, Param) then
begin
TCustomCheckListBox(WidgetInfo^.LCLObject).Toggle(Param);
AState:=TCustomCheckListBox(WidgetInfo^.LCLObject).State[Param];
gtk_list_store_set(ListStore, @Iter, [gtk2CLBState,
Byte(AState), -1]);
end;
Path := gtk_tree_path_new_from_indices(Param, -1);
if Path <> nil then
begin
if TreeView^.priv^.tree <> nil then
gtk_tree_view_set_cursor(TreeView, Path, nil, False);
gtk_tree_path_free(Path);
end;
FillChar(Mess{%H-}, SizeOf(Mess), #0);
Mess.Msg := LM_CHANGED;
Mess.Result := 0;
Mess.WParam := Param;
DeliverMessage(widgetInfo^.lclObject, Mess);
end;
*)
{ TGtk3WSCheckListBox }
class function TGtk3WSCustomCheckListBox.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
var
TreeViewWidget: PGtkWidget;
p: PGtkWidget; // ptr to the newly created GtkWidget
liststore : PGtkListStore;
Selection: PGtkTreeSelection;
renderer : PGtkCellRenderer;
column : PGtkTreeViewColumn;
// WidgetInfo: PWidgetInfo;
begin
Result := 0;
(*
Result := TGtk2WSBaseScrollingWinControl.CreateHandle(AWinControl,AParams);
p := {%H-}PGtkWidget(Result);
if Result = 0 then exit;
WidgetInfo := GetWidgetInfo(p, False);
GTK_WIDGET_UNSET_FLAGS(PGtkScrolledWindow(p)^.hscrollbar, GTK_CAN_FOCUS);
GTK_WIDGET_UNSET_FLAGS(PGtkScrolledWindow(p)^.vscrollbar, GTK_CAN_FOCUS);
gtk_scrolled_window_set_policy(PGtkScrolledWindow(p),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(PGtkScrolledWindow(p), GTK_SHADOW_IN);
gtk_widget_show(p);
liststore := gtk_list_store_new (4,
[G_TYPE_UCHAR, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, nil]);
TreeViewWidget := gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
g_object_unref(G_OBJECT(liststore));
// Check Column
renderer := gtk_cell_renderer_toggle_new();
{$ifdef windows}
// standard indicator size = 13 and its looks ugly under windows
g_object_set(renderer, 'indicator-size', [14, nil]);
{$endif}
column := gtk_tree_view_column_new;
gtk_tree_view_column_set_title(column, 'CHECKBTNS');
gtk_tree_view_column_pack_start(column, renderer, True);
gtk_tree_view_column_set_cell_data_func(column, renderer,
@Gtk2WS_CheckListBoxDataFunc, WidgetInfo, nil);
gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(renderer), True);
gtk_tree_view_append_column(GTK_TREE_VIEW(TreeViewWidget), column);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), True);
SignalConnect(PGtkWidget(renderer), 'toggled', @Gtk2WS_CheckListBoxToggle, WidgetInfo);
// Text Column
renderer := gtk_cell_renderer_text_new();
column := gtk_tree_view_column_new_with_attributes(
'LISTITEMS', renderer, ['text', gtk2CLBText, nil]);
gtk_tree_view_append_column(GTK_TREE_VIEW(TreeViewWidget), column);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), True);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(TreeViewWidget), False);
gtk_container_add(GTK_CONTAINER(p), TreeViewWidget);
gtk_widget_show(TreeViewWidget);
SetMainWidget(p, TreeViewWidget);
GetWidgetInfo(p, True)^.CoreWidget := TreeViewWidget;
Selection := gtk_tree_view_get_selection(PGtkTreeView(TreeViewWidget));
case TCustomCheckListBox(AWinControl).MultiSelect of
True : gtk_tree_selection_set_mode(Selection, GTK_SELECTION_MULTIPLE);
False: gtk_tree_selection_set_mode(Selection, GTK_SELECTION_SINGLE);
end;
Set_RC_Name(AWinControl, P);
SetCallbacks(p, WidgetInfo);
*)
// DebugLn('>TGtk3WSCustomCheckListBox.CreateHandle');
Result := TLCLIntfHandle(TGtk3CheckListBox.Create(AWinControl, AParams));
// DebugLn('<TGtk3WSCustomCheckListBox.CreateHandle: Result=',dbgHex(Result));
end;
class function TGtk3WSCustomCheckListBox.GetItemEnabled(
@ -209,22 +73,20 @@ class function TGtk3WSCustomCheckListBox.GetItemEnabled(
var
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
// WidgetInfo: PWidgetInfo;
ListStore: PGtkTreeModel;
Disabled: gboolean;
begin
Result := True;
(*
WidgetInfo := GetWidgetInfo({%H-}PGtkWidget(ACheckListBox.Handle));
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
Result := False;
if not WSCheckHandleAllocated(ACheckListBox, 'GetItemEnabled') then
Exit;
// DebugLn('TGtk3WSCustomCheckListBox.GetItemEnabled AIndex=',dbgs(AIndex));
TreeView := PGtkTreeView(TGtk3CheckListBox(ACheckListBox.Handle).GetContainerWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then
begin
gtk_tree_model_get(ListStore, @Iter, [gtk2CLBDisabled, @Disabled, -1]);
gtk_tree_model_get(ListStore, @Iter, [gtk3CLBDisabled, @Disabled, -1]);
Result := not Disabled;
end;
*)
end;
class function TGtk3WSCustomCheckListBox.GetState(
@ -233,22 +95,22 @@ class function TGtk3WSCustomCheckListBox.GetState(
var
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
// WidgetInfo: PWidgetInfo;
ListStore: PGtkTreeModel;
b: byte;
begin
Result := cbUnchecked;
(*
WidgetInfo := GetWidgetInfo({%H-}PGtkWidget(ACheckListBox.Handle));
if not WSCheckHandleAllocated(ACheckListBox, 'GetState') then
Exit;
// DebugLn('TGtk3WSCustomCheckListBox.GetState AIndex=',dbgs(AIndex));
TreeView := PGtkTreeView(TGtk3CheckListBox(ACheckListBox.Handle).GetContainerWidget);
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then
begin
gtk_tree_model_get(ListStore, @Iter, [gtk2CLBState, @b, -1]);
gtk_tree_model_get(ListStore, @Iter, [gtk3CLBState, @b, -1]);
Result := TCheckBoxState(b);
end;
*)
end;
class procedure TGtk3WSCustomCheckListBox.SetItemEnabled(
@ -260,14 +122,16 @@ var
ListStore: PGtkTreeModel;
Disabled: gboolean;
begin
(*
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
if not WSCheckHandleAllocated(ACheckListBox, 'SetItemEnabled') then
Exit;
// DebugLn('TGtk3WSCustomCheckListBox.SetItemEnabled AIndex=',dbgs(AIndex),' AEnabled=',dbgs(AEnabled));
TreeView := PGtkTreeView(TGtk3CheckListBox(ACheckListBox.Handle).GetContainerWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then begin
Disabled:=not AEnabled;
gtk_list_store_set(ListStore, @Iter, [gtk2CLBDisabled, Disabled, -1]);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then
begin
Disabled := not AEnabled;
gtk_list_store_set(PGtkListStore(ListStore), @Iter, [gtk3CLBDisabled, Disabled, -1]);
end;
*)
end;
class procedure TGtk3WSCustomCheckListBox.SetState(
@ -278,16 +142,15 @@ var
TreeView: PGtkTreeView;
ListStore: PGtkTreeModel;
begin
(*
WidgetInfo := GetWidgetInfo({%H-}PGtkWidget(ACheckListBox.Handle));
if not WSCheckHandleAllocated(ACheckListBox, 'SetState') then
Exit;
// DebugLn('TGtk3WSCustomCheckListBox.SetState AIndex=',dbgs(AIndex),' AEnabled=',dbgs(Ord(AState)));
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
TreeView := PGtkTreeView(TGtk3CheckListBox(ACheckListBox.Handle).GetContainerWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then
begin
gtk_list_store_set(ListStore, @Iter, [gtk2CLBState, Byte(AState), -1]);
end;
*)
gtk_list_store_set(PGtkListStore(ListStore), @Iter, [gtk3CLBState, Byte(AState), -1]);
end;
end.

View File

@ -139,7 +139,7 @@ uses
uses
Gtk3WSImgList, Gtk3WSControls, Gtk3WSForms, Gtk3WSButtons, Gtk3WSStdCtrls,
Gtk3WSComCtrls, Gtk3WSExtCtrls, Gtk3WSSpin, Gtk3WSMenus, Gtk3WSCalendar,
Gtk3WSDialogs;
Gtk3WSDialogs, Gtk3WSCheckLst;
// imglist
function RegisterCustomImageList: Boolean; alias : 'WSRegisterCustomImageList';
@ -536,8 +536,8 @@ end;
// CheckLst
function RegisterCustomCheckListBox: Boolean; alias : 'WSRegisterCustomCheckListBox';
begin
// RegisterWSComponent(TCustomCheckListBox, TGtk2WSCustomCheckListBox);
Result := False;
RegisterWSComponent(TCustomCheckListBox, TGtk3WSCustomCheckListBox);
Result := True;
end;
// Forms