mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-01 10:12:50 +02:00
1180 lines
39 KiB
ObjectPascal
1180 lines
39 KiB
ObjectPascal
{ $Id$}
|
|
{
|
|
*****************************************************************************
|
|
* Gtk2WSStdCtrls.pp *
|
|
* ----------------- *
|
|
* *
|
|
* *
|
|
*****************************************************************************
|
|
|
|
*****************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
*****************************************************************************
|
|
}
|
|
unit Gtk2WSStdCtrls;
|
|
|
|
{$mode objfpc}{$H+}
|
|
{$PACKRECORDS c}
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Math, Controls, Graphics,
|
|
////////////////////////////////////////////////////
|
|
// I M P O R T A N T
|
|
////////////////////////////////////////////////////
|
|
// To get as little as posible circles,
|
|
// uncomment only when needed for registration
|
|
////////////////////////////////////////////////////
|
|
StdCtrls, LMessages,
|
|
////////////////////////////////////////////////////
|
|
glib2, gdk2, gtk2, Pango,
|
|
WSStdCtrls, WSLCLClasses, GtkWSStdCtrls, Gtk2Int, LCLType, GtkDef, LCLProc,
|
|
Gtk2CellRenderer, GTKWinApiWindow, gtkglobals, gtkproc, InterfaceBase;
|
|
|
|
type
|
|
|
|
|
|
PGtkComboBoxPrivate = ^TGtkComboBoxPrivate;
|
|
TGtkComboBoxPrivate = record
|
|
model: PGtkTreeModel;
|
|
col_column,
|
|
row_column: gint;
|
|
wrap_width: gint;
|
|
active_row: PGtkTreeRowReference;
|
|
tree_view: PGtkWidget;
|
|
column: PGtkTreeViewColumn;
|
|
cell_view: PGtkWidget;
|
|
cell_view_frame: PGtkWidget;
|
|
button: PGtkwidget;
|
|
box: PGtkWidget;
|
|
arrow: PGtkWidget;
|
|
serarator: PGtkWidget;
|
|
popup_widget: PGtkWidget;
|
|
popup_window: PGtkWidget;
|
|
popup_frame: PGtkWidget;
|
|
scrolled_window: PGtkwidget;
|
|
end;
|
|
|
|
{ TGtk2WSScrollBar }
|
|
|
|
TGtk2WSScrollBar = class(TGtkWSScrollBar)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomGroupBox }
|
|
|
|
TGtk2WSCustomGroupBox = class(TGtkWSCustomGroupBox)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSGroupBox }
|
|
|
|
TGtk2WSGroupBox = class(TGtkWSGroupBox)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomComboBox }
|
|
|
|
TGtk2WSCustomComboBox = class(TGtkWSCustomComboBox)
|
|
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 SetCallbacks(const AWinControl: tWinControl; const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
|
|
public
|
|
class function GetSelStart(const ACustomComboBox: TCustomComboBox): integer; override;
|
|
class function GetSelLength(const ACustomComboBox: TCustomComboBox): integer; override;
|
|
class function GetItemIndex(const ACustomComboBox: TCustomComboBox): integer; override;
|
|
class function GetMaxLength(const ACustomComboBox: TCustomComboBox): integer; override;
|
|
class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override;
|
|
|
|
class procedure SetArrowKeysTraverseList(const ACustomComboBox: TCustomComboBox;
|
|
NewTraverseList: boolean); override;
|
|
class procedure SetSelStart(const ACustomComboBox: TCustomComboBox; NewStart: integer); override;
|
|
class procedure SetSelLength(const ACustomComboBox: TCustomComboBox; NewLength: integer); override;
|
|
class procedure SetItemIndex(const ACustomComboBox: TCustomComboBox; NewIndex: integer); override;
|
|
class procedure SetMaxLength(const ACustomComboBox: TCustomComboBox; NewLength: integer); override;
|
|
class procedure SetStyle(const ACustomComboBox: TCustomComboBox; NewStyle: TComboBoxStyle); override;
|
|
class procedure SetReadOnly(const ACustomComboBox: TCustomComboBox; NewReadOnly: boolean); override;
|
|
|
|
class function GetItems(const ACustomComboBox: TCustomComboBox): TStrings; override;
|
|
class procedure Sort(const ACustomComboBox: TCustomComboBox; AList: TStrings; IsSorted: boolean); override;
|
|
class procedure SetColor(const AWinControl: TWinControl); override;
|
|
class procedure SetFont(const AWinControl: TWinControl; const AFont : tFont); override;
|
|
class procedure SetText(const AWinControl: TWinControl; const AText: String); override;
|
|
|
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
|
end;
|
|
|
|
{ TGtk2WSComboBox }
|
|
|
|
TGtk2WSComboBox = class(TGtkWSComboBox)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomListBox }
|
|
|
|
TGtk2WSCustomListBox = class(TGtkWSCustomListBox)
|
|
private
|
|
protected
|
|
class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
|
|
public
|
|
class function GetSelCount(const ACustomListBox: TCustomListBox): integer; override;
|
|
class function GetSelected(const ACustomListBox: TCustomListBox; const AIndex: integer): boolean; override;
|
|
class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override;
|
|
class function GetItemIndex(const ACustomListBox: TCustomListBox): integer; override;
|
|
class function GetTopIndex(const ACustomListBox: TCustomListBox): integer; override;
|
|
class procedure SelectItem(const ACustomListBox: TCustomListBox; AnIndex: integer; ASelected: boolean); override;
|
|
class procedure SetBorder(const ACustomListBox: TCustomListBox); override;
|
|
class procedure SetItemIndex(const ACustomListBox: TCustomListBox; const AIndex: integer); override;
|
|
class procedure SetSelectionMode(const ACustomListBox: TCustomListBox; const AExtendedSelect,
|
|
AMultiSelect: boolean); override;
|
|
class procedure SetSorted(const ACustomListBox: TCustomListBox; AList: TStrings; ASorted: boolean); override;
|
|
class procedure SetTopIndex(const ACustomListBox: TCustomListBox; const NewTopIndex: integer); override;
|
|
class procedure SetFont(const AWinControl: TWinControl; const AFont : TFont); override;
|
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
|
end;
|
|
|
|
{ TGtk2WSListBox }
|
|
|
|
TGtk2WSListBox = class(TGtkWSListBox)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomEdit }
|
|
|
|
TGtk2WSCustomEdit = class(TGtkWSCustomEdit)
|
|
private
|
|
protected
|
|
public
|
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
|
class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;
|
|
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;
|
|
end;
|
|
|
|
{ TGtk2WSCustomMemo }
|
|
|
|
TGtk2WSCustomMemo = class(TGtkWSCustomMemo)
|
|
private
|
|
protected
|
|
class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
|
|
public
|
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
|
class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;
|
|
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;
|
|
class function GetStrings(const ACustomMemo: TCustomMemo): TStrings; override;
|
|
class procedure SetColor(const AWinControl: TWinControl);override;
|
|
class procedure SetFont(const AWinControl: TWinControl;const AFont : TFont);override;
|
|
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;
|
|
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;
|
|
end;
|
|
|
|
{ TGtk2WSEdit }
|
|
|
|
TGtk2WSEdit = class(TGtkWSEdit)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSMemo }
|
|
|
|
TGtk2WSMemo = class(TGtkWSMemo)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomLabel }
|
|
|
|
{
|
|
TGtk2WSCustomLabel = class(TGtkWSCustomLabel)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
}
|
|
{ TGtk2WSLabel }
|
|
|
|
{
|
|
TGtk2WSLabel = class(TGtkWSLabel)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
}
|
|
|
|
{ TGtk2WSButtonControl }
|
|
|
|
TGtk2WSButtonControl = class(TGtkWSButtonControl)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomCheckBox }
|
|
|
|
TGtk2WSCustomCheckBox = class(TGtkWSCustomCheckBox)
|
|
private
|
|
protected
|
|
public
|
|
class function RetrieveState(const ACustomCheckBox: TCustomCheckBox
|
|
): TCheckBoxState; override;
|
|
class procedure SetState(const ACustomCheckBox: TCustomCheckBox;
|
|
const NewState: TCheckBoxState); override;
|
|
end;
|
|
|
|
{ TGtk2WSCheckBox }
|
|
|
|
TGtk2WSCheckBox = class(TGtkWSCheckBox)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSToggleBox }
|
|
|
|
TGtk2WSToggleBox = class(TGtkWSToggleBox)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSRadioButton }
|
|
|
|
TGtk2WSRadioButton = class(TGtkWSRadioButton)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSCustomStaticText }
|
|
|
|
TGtk2WSCustomStaticText = class(TGtkWSCustomStaticText)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{ TGtk2WSStaticText }
|
|
|
|
TGtk2WSStaticText = class(TGtkWSStaticText)
|
|
private
|
|
protected
|
|
public
|
|
end;
|
|
|
|
{$DEFINE MEMOHEADER}
|
|
{$I gtk2memostrings.inc}
|
|
{$UNDEF MEMOHEADER}
|
|
|
|
implementation
|
|
|
|
uses GtkWSControls, LCLMessageGlue;
|
|
|
|
{$I gtk2memostrings.inc}
|
|
|
|
{ TGtk2WSCustomListBox }
|
|
|
|
procedure Gtk2WS_ListBoxChange(Selection: PGtkTreeSelection; WidgetInfo: PWidgetInfo); cdecl;
|
|
var
|
|
Mess: TLMessage;
|
|
begin
|
|
{$IFDEF EventTrace}
|
|
EventTrace('Gtk2WS_ListBoxChange', WidgetInfo^.LCLObject);
|
|
{$ENDIF}
|
|
FillChar(Mess,SizeOf(Mess),0);
|
|
Mess.msg := LM_SelChange;
|
|
DeliverMessage(WidgetInfo^.LCLObject, Mess);
|
|
end;
|
|
|
|
class function TGtk2WSCustomListBox.GetItemIndex(
|
|
const ACustomListBox: TCustomListBox): integer;
|
|
var
|
|
Handle: HWND;
|
|
Widget: PGtkWidget;
|
|
TreeView: PGtkTreeView;
|
|
Selection: PGtkTreeSelection;
|
|
Model: PGtkTreeModel;
|
|
ListModel: TGtkListStore;
|
|
Iter: TGtkTreeIter;
|
|
Path: PGtkTreePath;
|
|
begin
|
|
Result := -1;
|
|
Handle := ACustomListBox.Handle;
|
|
if Handle<>0 then
|
|
begin
|
|
Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget;
|
|
if GtkWidgetIsA(Widget,gtk_tree_view_get_type) then begin
|
|
TreeView := PGtkTreeView(Widget);
|
|
Selection := Gtk_tree_view_get_selection(TreeView);
|
|
Model := @ListModel;
|
|
if gtk_tree_selection_get_selected(Selection, @Model, @Iter) then begin
|
|
Path := gtk_tree_model_get_path(Model, @Iter);
|
|
if Path <> nil then begin
|
|
Result := gtk_tree_path_get_indices(Path)^;
|
|
gtk_tree_path_free(Path);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomListBox.GetTopIndex(
|
|
const ACustomListBox: TCustomListBox): integer;
|
|
begin
|
|
Result:=inherited GetTopIndex(ACustomListBox);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SelectItem(
|
|
const ACustomListBox: TCustomListBox; AnIndex: integer; ASelected: boolean);
|
|
var
|
|
Handle: HWND;
|
|
Widget: PGtkWidget; // pointer to gtk-widget (local use when neccessary)
|
|
Selection: PGtkTreeSelection;
|
|
ListStoreModel: PGtkTreeModel;
|
|
Iter : TGtkTreeIter;
|
|
begin
|
|
Handle := ACustomListBox.Handle;
|
|
Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget;
|
|
ListStoreModel := gtk_tree_view_get_model(PGtkTreeView(Widget));
|
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
|
|
|
if gtk_tree_model_iter_nth_child(ListStoreModel, @Iter, nil, AnIndex) then
|
|
begin
|
|
case ASelected of
|
|
True:
|
|
if not gtk_tree_selection_iter_is_selected(Selection, @Iter) then
|
|
gtk_tree_selection_select_iter(Selection, @Iter);
|
|
False:
|
|
if gtk_tree_selection_iter_is_selected(Selection, @Iter) then
|
|
gtk_tree_selection_unselect_iter(Selection, @Iter);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetBorder(
|
|
const ACustomListBox: TCustomListBox);
|
|
begin
|
|
// TODO
|
|
debugln('TGtk2WSCustomListBox.SetBorder TODO');
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetItemIndex(
|
|
const ACustomListBox: TCustomListBox; const AIndex: integer);
|
|
var
|
|
Handle: HWND;
|
|
Widget: PGtkWidget;
|
|
ListStoreModel: PGtkTreeModel;
|
|
Selection: PGtkTreeSelection;
|
|
Iter: TGtkTreeIter;
|
|
begin
|
|
Handle := ACustomListBox.Handle;
|
|
if Handle=0 then exit;
|
|
Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget;
|
|
if not GtkWidgetIsA(Widget,gtk_tree_view_get_type) then
|
|
raise Exception.Create('');
|
|
Selection := Gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
|
if AIndex >= 0 then begin
|
|
ListStoreModel := gtk_tree_view_get_model(PGtkTreeView(Widget));
|
|
if gtk_tree_model_iter_nth_child(ListStoreModel, @Iter, nil, AIndex) then begin
|
|
gtk_tree_selection_select_iter(Selection, @Iter);
|
|
end;
|
|
end else
|
|
gtk_tree_selection_unselect_all(Selection);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetSelectionMode(
|
|
const ACustomListBox: TCustomListBox; const AExtendedSelect,
|
|
AMultiSelect: boolean);
|
|
var
|
|
Handle: HWND;
|
|
Widget: PGtkWidget; // pointer to gtk-widget (local use when neccessary)
|
|
Selection: PGtkTreeSelection;
|
|
begin
|
|
Handle := ACustomListBox.Handle;
|
|
Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget;
|
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
|
|
|
case AMultiSelect of
|
|
True : gtk_tree_selection_set_mode(Selection, GTK_SELECTION_MULTIPLE);
|
|
False: gtk_tree_selection_set_mode(Selection, GTK_SELECTION_SINGLE);
|
|
//GTK_SELECTION_NONE,
|
|
//GTK_SELECTION_SINGLE,
|
|
//GTK_SELECTION_BROWSE,
|
|
//GTK_SELECTION_MULTIPLE
|
|
end;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetSorted(const ACustomListBox: TCustomListBox;
|
|
AList: TStrings; ASorted: boolean);
|
|
begin
|
|
if AList is TGtkListStoreStringList then
|
|
TGtkListStoreStringList(AList).Sorted := ASorted
|
|
//else if AList is TGtkCListStringList then
|
|
// TGtkCListStringList(AList).Sorted := ASorted
|
|
else
|
|
raise Exception.Create('');
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetTopIndex(
|
|
const ACustomListBox: TCustomListBox; const NewTopIndex: integer);
|
|
var
|
|
Widget: PGtkWidget;
|
|
ListStoreModel: PGtkTreeModel;
|
|
Iter: TGtkTreeIter;
|
|
TreeView: PGtkTreeView;
|
|
APath: Pointer;
|
|
begin
|
|
Widget:=GetWidgetInfo(Pointer(ACustomListBox.Handle),True)^.CoreWidget;
|
|
TreeView:=PGtkTreeView(Widget);
|
|
ListStoreModel:=gtk_tree_view_get_model(TreeView);
|
|
|
|
if not gtk_tree_model_iter_nth_child(ListStoreModel, @Iter, nil, NewTopIndex)
|
|
then exit;
|
|
|
|
APath := gtk_tree_model_get_path(ListStoreModel, @Iter);
|
|
gtk_tree_view_scroll_to_cell(TreeView, APath, NULL, true, 0.0, 0.0);
|
|
gtk_tree_path_free(APath);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetFont(const AWinControl: TWinControl;
|
|
const AFont: TFont);
|
|
var
|
|
Widget: PGtkWidget;
|
|
begin
|
|
Widget:=GetWidgetInfo(Pointer(AWinControl.Handle),True)^.CoreWidget;
|
|
|
|
Gtk2WidgetSet.SetWidgetColor(Widget, AWinControl.Font.Color, clNone,
|
|
[GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]);
|
|
Gtk2WidgetSet.SetWidgetFont(Widget, AFont);
|
|
|
|
end;
|
|
|
|
class function TGtk2WSCustomListBox.CreateHandle(const AWinControl: TWinControl;
|
|
const AParams: TCreateParams): TLCLIntfHandle;
|
|
var
|
|
TempWidget: PGtkWidget;
|
|
p: PGtkWidget; // ptr to the newly created GtkWidget
|
|
liststore : PGtkListStore;
|
|
Selection: PGtkTreeSelection;
|
|
renderer : PGtkCellRenderer;
|
|
column : PGtkTreeViewColumn;
|
|
WidgetInfo: PWidgetInfo;
|
|
begin
|
|
Result := TGtkWSBaseScrollingWinControl.CreateHandle(AWinControl,AParams);
|
|
p:= PGtkWidget(Result);
|
|
|
|
if Result = 0 then exit;
|
|
|
|
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 (2, [G_TYPE_STRING, G_TYPE_POINTER, nil]);
|
|
|
|
TempWidget:= gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
|
|
g_object_unref (G_OBJECT (liststore));
|
|
|
|
renderer := LCLIntfCellRenderer_New();
|
|
column := gtk_tree_view_column_new_with_attributes ('LISTITEMS', renderer,
|
|
['text', 0, nil]);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (TempWidget), column);
|
|
gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (TempWidget), False);
|
|
|
|
gtk_container_add(GTK_CONTAINER(p), TempWidget);
|
|
gtk_widget_show(TempWidget);
|
|
|
|
SetMainWidget(p, TempWidget);
|
|
GetWidgetInfo(p, True)^.CoreWidget := TempWidget;
|
|
|
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(TempWidget));
|
|
|
|
case TCustomListBox(AWinControl).MultiSelect of
|
|
True : gtk_tree_selection_set_mode(Selection, GTK_SELECTION_MULTIPLE);
|
|
False: gtk_tree_selection_set_mode(Selection, GTK_SELECTION_SINGLE);
|
|
end;
|
|
|
|
WidgetInfo := GetWidgetInfo(p, False);
|
|
SetCallbacks(TempWidget, WidgetInfo);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomListBox.SetCallbacks(
|
|
const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo);
|
|
var
|
|
Selection: PGtkTreeSelection;
|
|
begin
|
|
TGtkWSBaseScrollingWinControl.SetCallbacks(AGtkWidget,AWidgetInfo);
|
|
|
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(AWidgetInfo^.CoreWidget));
|
|
SignalConnect(PGtkWidget(Selection), 'changed', @Gtk2WS_ListBoxChange, AWidgetInfo);
|
|
end;
|
|
|
|
class function TGtk2WSCustomListBox.GetSelCount(
|
|
const ACustomListBox: TCustomListBox): integer;
|
|
var
|
|
Handle: HWND;
|
|
Widget: PGtkWidget; // pointer to gtk-widget (local use when neccessary)
|
|
Selection: PGtkTreeSelection;
|
|
ListStoreModel: PGtkTreeModel;
|
|
Rows: PGList;
|
|
begin
|
|
Result := 0;
|
|
Handle := ACustomListBox.Handle;
|
|
Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget;
|
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
|
|
|
Rows := gtk_tree_selection_get_selected_rows(Selection, @ListStoreModel);
|
|
Result := g_list_length(Rows);
|
|
g_list_free(Rows);
|
|
end;
|
|
|
|
class function TGtk2WSCustomListBox.GetSelected(
|
|
const ACustomListBox: TCustomListBox; const AIndex: integer): boolean;
|
|
var
|
|
Handle: HWND;
|
|
Widget: PGtkWidget; // pointer to gtk-widget (local use when neccessary)
|
|
Selection: PGtkTreeSelection;
|
|
ListStoreModel: PGtkTreeModel;
|
|
Item : TGtkTreeIter;
|
|
begin
|
|
Result := false; { assume: nothing found }
|
|
Handle := ACustomListBox.Handle;
|
|
Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget;
|
|
ListStoreModel := gtk_tree_view_get_model(PGtkTreeView(Widget));
|
|
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
|
|
|
if gtk_tree_model_iter_nth_child(ListStoreModel, @Item, nil, AIndex) then begin
|
|
Result := gtk_tree_selection_iter_is_selected(Selection, @Item);
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomListBox.GetStrings(
|
|
const ACustomListBox: TCustomListBox): TStrings;
|
|
var
|
|
Widget: PGtkWidget;// pointer to gtk-widget
|
|
Handle: HWND;
|
|
begin
|
|
Handle := ACustomListBox.Handle;
|
|
case ACustomListBox.fCompStyle of
|
|
{csCListBox:
|
|
begin
|
|
Widget:= GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
|
|
|
|
Result := TGtkCListStringList.Create(PGtkCList(Widget));
|
|
if ACustomListBox is TCustomListBox then
|
|
TGtkCListStringList(Result).Sorted :=
|
|
TCustomListBox(ACustomListBox).Sorted;
|
|
end;
|
|
}
|
|
csCheckListBox, csListBox:
|
|
begin
|
|
Widget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
|
|
Result := TGtkListStoreStringList.Create(
|
|
gtk_tree_view_get_model(PGtkTreeView(Widget)),
|
|
Ord(ACustomListBox.fCompStyle = csCheckListBox),
|
|
ACustomListBox);
|
|
TGtkListStoreStringList(Result).Sorted := ACustomListBox.Sorted;
|
|
end;
|
|
else
|
|
raise Exception.Create('TGtk2WSCustomListBox.GetStrings');
|
|
end;
|
|
end;
|
|
|
|
{ TGtk2WSCustomCheckBox }
|
|
|
|
class function TGtk2WSCustomCheckBox.RetrieveState(
|
|
const ACustomCheckBox: TCustomCheckBox): TCheckBoxState;
|
|
var
|
|
ToggleButton: PGtkToggleButton;
|
|
begin
|
|
ToggleButton:=PGtkToggleButton(ACustomCheckBox.Handle);
|
|
if ACustomCheckBox.AllowGrayed
|
|
and gtk_toggle_button_get_inconsistent(ToggleButton) then
|
|
Result:=cbGrayed
|
|
else if gtk_toggle_button_get_active(ToggleButton) then
|
|
Result := cbChecked
|
|
else
|
|
Result := cbUnChecked;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomCheckBox.SetState(
|
|
const ACustomCheckBox: TCustomCheckBox; const NewState: TCheckBoxState);
|
|
var
|
|
GtkObject: PGtkObject;
|
|
ToggleButton: PGtkToggleButton;
|
|
begin
|
|
//debugln('TGtk2WSCustomCheckBox.SetState A ',DbgSName(ACustomCheckBox),' State=',dbgs(ord(ACustomCheckBox.State)));
|
|
GtkObject := PGtkObject(ACustomCheckBox.Handle);
|
|
LockOnChange(GtkObject,1);
|
|
ToggleButton:=PGtkToggleButton(GtkObject);
|
|
gtk_toggle_button_set_active(ToggleButton, NewState=cbChecked);
|
|
gtk_toggle_button_set_inconsistent(ToggleButton, NewState=cbGrayed);
|
|
LockOnChange(GtkObject,-1);
|
|
end;
|
|
|
|
{$I gtk2wscustommemo.inc}
|
|
|
|
{ TGtk2WSCustomEdit }
|
|
|
|
class function TGtk2WSCustomEdit.CreateHandle(const AWinControl: TWinControl;
|
|
const AParams: TCreateParams): TLCLIntfHandle;
|
|
var
|
|
p: PGtkWidget; // ptr to the newly created GtkWidget
|
|
begin
|
|
p := gtk_entry_new();
|
|
gtk_editable_set_editable (PGtkEditable(P), not TCustomEdit(AWinControl).ReadOnly);
|
|
gtk_widget_show_all(P);
|
|
Result := TLCLIntfHandle(P);
|
|
if result = 0 then exit;
|
|
gtk2WidgetSet.FinishComponentCreate(AWinControl, P);
|
|
end;
|
|
|
|
|
|
class function TGtk2WSCustomEdit.GetSelStart(const ACustomEdit: TCustomEdit
|
|
): integer;
|
|
var
|
|
Entry: PGtkEntry;
|
|
begin
|
|
Entry := PGtkEntry(ACustomEdit.Handle);
|
|
Result := Min(Entry^.current_pos, Entry^.selection_bound);
|
|
end;
|
|
|
|
class function TGtk2WSCustomEdit.GetSelLength(const ACustomEdit: TCustomEdit
|
|
): integer;
|
|
var
|
|
Entry: PGtkEntry;
|
|
begin
|
|
Entry := PGtkEntry(ACustomEdit.Handle);
|
|
Result := ABS(Entry^.current_pos - Entry^.selection_bound);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.ReCreateCombo(
|
|
const ACustomComboBox: TCustomComboBox; const AWithEntry: Boolean;
|
|
const AWidgetInfo: PWidgetInfo);
|
|
var
|
|
p: PGtkWidget;
|
|
Model: PGtkTreeModel;
|
|
Index: Integer;
|
|
Text: String;
|
|
begin
|
|
p := AWidgetInfo^.CoreWidget;
|
|
Model := gtk_combo_box_get_model(PGtkComboBox(p));
|
|
g_object_ref(G_OBJECT(Model));
|
|
|
|
// this should work but may not in all circumstances
|
|
Index := -1;
|
|
if AWithEntry = False then begin // the current widget HAS an entry
|
|
GetText(ACustomComboBox, Text);
|
|
Index := ACustomComboBox.Items.IndexOf(Text);
|
|
end;
|
|
if Index = -1 then Index := GetItemIndex(ACustomComboBox);
|
|
|
|
gtk_widget_destroy(p);
|
|
|
|
case AWithEntry of
|
|
True : p := gtk_combo_box_entry_new_with_model(Model, 0);
|
|
False: p := gtk_combo_box_new_with_model(Model);
|
|
end;
|
|
SetMainWidget(p, GTK_BIN(p)^.child);
|
|
g_object_unref (G_OBJECT(Model));
|
|
AWidgetInfo^.CoreWidget := p;
|
|
gtk_object_set_data(Pointer(p), 'widgetinfo', AWidgetInfo);
|
|
|
|
SetItemIndex(ACustomComboBox, Index);
|
|
|
|
if AWithEntry then begin
|
|
SetMaxLength(ACustomComboBox, TComboBox(ACustomComboBox).MaxLength);
|
|
SetReadOnly(ACustomComboBox, ACustomComboBox.ReadOnly);
|
|
end;
|
|
|
|
SetRenderer(ACustomComboBox, p);
|
|
|
|
gtk_container_add(PGtkContainer(AWidgetInfo^.ClientWidget), p);
|
|
gtk_widget_show_all(AWidgetInfo^.ClientWidget);
|
|
|
|
SetCallbacks(ACustomComboBox, p, AWidgetInfo);
|
|
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetRenderer(
|
|
const ACustomComboBox: TCustomComboBox; AWidget: PGtkWidget);
|
|
var
|
|
renderer : PGtkCellRenderer;
|
|
begin
|
|
renderer := LCLIntfCellRenderer_New();
|
|
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 UpdateMenuItemsCB(AMenuItem: PGtkBin; WidgetInfo: PWidgetInfo); cdecl;
|
|
var
|
|
renderer : PGtkCellRenderer;
|
|
AItem: PGtkCellLayout;
|
|
// AItem is really a GtkCellView which implements GtkCellRenderer
|
|
begin
|
|
AItem := PGtkCellLayout(AMenuItem^.child);
|
|
//WriteLn(G_OBJECT_CLASS_NAME(GTK_WIDGET_GET_CLASS(PGtkWidget(AItem))));
|
|
|
|
if g_object_get_data(G_OBJECT(AItem), 'MenuItem') <> 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), 'MenuItem', AMenuItem);
|
|
g_object_set_data(G_OBJECT(renderer), 'MenuItem', AMenuItem);
|
|
end;
|
|
|
|
procedure GtkPopupShowCB(AMenu: PGtkMenuShell; WidgetInfo: PWidgetInfo); cdecl;
|
|
begin
|
|
// 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(@UpdateMenuItemsCB), WidgetInfo);
|
|
|
|
LCLSendDropDownMsg(TControl(WidgetInfo^.LCLObject));
|
|
end;
|
|
|
|
procedure GtkChangedCB(AWidget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl;
|
|
begin
|
|
if WidgetInfo^.UserData <> nil then Exit;
|
|
LCLSendChangedMsg(TControl(WidgetInfo^.LCLObject));
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetCallbacks(
|
|
const AWinControl: TWinControl; const AWidget: PGtkWidget;
|
|
const AWidgetInfo: PWidgetInfo);
|
|
var
|
|
AGtkObject: PGtkObject;
|
|
AChild: PGtkObject;
|
|
AButton: PGtkObject;
|
|
APrivate: PGtkComboBoxPrivate;
|
|
BtnPressID: guint;
|
|
HandlerID: guint;
|
|
begin
|
|
AGtkObject := PGtkObject(AWidget);
|
|
AChild := PGtkObject(PGtkBin(AWidget)^.child);
|
|
APrivate := PGtkComboBoxPrivate(PGtkComboBox(AWidget)^.priv);
|
|
AButton := PGtkObject(APrivate^.button);
|
|
|
|
// we have to remove the handler gtk sets up because we will never get the mouse down messages
|
|
BtnPressID := g_signal_lookup('button_press_event', GTK_TYPE_COMBO_BOX);
|
|
HandlerID := g_signal_handler_find(AButton, G_SIGNAL_MATCH_ID, BtnPressID, 0, nil, nil, nil);
|
|
if HandlerID > 0 then begin
|
|
g_signal_handler_disconnect(AButton, HandlerID);
|
|
end;
|
|
|
|
g_signal_connect(AWidget, 'changed', TGCallback(@GtkChangedCB), AWidgetInfo);
|
|
|
|
// First the combo
|
|
Gtk2WidgetSet.SetCallback(LM_MOUSEMOVE, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_LBUTTONDOWN, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_LBUTTONUP, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_LBUTTONDBLCLK, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_RBUTTONDBLCLK, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MBUTTONDBLCLK, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_RBUTTONDOWN, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_RBUTTONUP, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MBUTTONDOWN, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MBUTTONUP, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MOUSEWHEEL, AGTKObject, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_PAINT, AGTKObject, AWinControl);
|
|
|
|
//And now the same for the Button in the combo
|
|
|
|
Gtk2WidgetSet.SetCallback(LM_MOUSEENTER, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MOUSELEAVE, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MOUSEMOVE, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_LBUTTONDOWN, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_LBUTTONUP, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_LBUTTONUP, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_RBUTTONDOWN, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_RBUTTONUP, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MBUTTONDOWN, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MBUTTONUP, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_MOUSEWHEEL, AButton, AWinControl);
|
|
Gtk2WidgetSet.SetCallback(LM_PAINT, AGTKObject, AWinControl);
|
|
|
|
// if we are a GtkComboBoxEntry
|
|
if GtkWidgetIsA(PGtkWidget(AChild), GTK_TYPE_ENTRY) then begin
|
|
// Anything?
|
|
end;
|
|
|
|
g_signal_connect(APrivate^.popup_widget, 'show', TGCallback(@GtkPopupShowCB), AWidgetInfo);
|
|
g_object_set_data(G_OBJECT(AWidget), 'Menu', APrivate^.popup_widget);
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.GetSelStart(
|
|
const ACustomComboBox: TCustomComboBox): integer;
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkEntry;
|
|
begin
|
|
Result := 0;
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
// if the combo is an editable ...
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_ENTRY(GTK_BIN(WidgetInfo^.CoreWidget)^.child);
|
|
Result := Min(Entry^.current_pos, Entry^.selection_bound);
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.GetSelLength(
|
|
const ACustomComboBox: TCustomComboBox): integer;
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkEntry;
|
|
begin
|
|
Result := 0;
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
// if the combo is an editable ...
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_ENTRY(GTK_BIN(WidgetInfo^.CoreWidget)^.child);
|
|
Result := ABS(Entry^.current_pos - Entry^.selection_bound);
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.GetItemIndex(
|
|
const ACustomComboBox: TCustomComboBox): integer;
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkEntry;
|
|
Text: String;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
Result := gtk_combo_box_get_active(PGtkComboBox(WidgetInfo^.CoreWidget));
|
|
|
|
// if the combo is an editable ...
|
|
if (Result = -1) and gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_ENTRY(GTK_BIN(WidgetInfo^.CoreWidget)^.child);
|
|
Text := gtk_entry_get_text(Entry);
|
|
Result := ACustomComboBox.Items.IndexOf(Text);
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.GetMaxLength(
|
|
const ACustomComboBox: TCustomComboBox): integer;
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkEntry;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
// if the combo is an editable ...
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_ENTRY(GTK_BIN(WidgetInfo^.CoreWidget)^.child);
|
|
Result := gtk_entry_get_max_length(Entry);
|
|
end
|
|
else begin
|
|
Result := PtrInt(g_object_get_data(PGObject(WidgetInfo^.ClientWidget), 'max-length'));
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.GetText(const AWinControl: TWinControl;
|
|
var AText: String): Boolean;
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkWidget;
|
|
Index: Integer;
|
|
begin
|
|
Result := True;
|
|
WidgetInfo := GetWidgetInfo(Pointer(AWinControl.Handle));
|
|
|
|
// if the combo is an editable ...
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
AText := gtk_entry_get_text(PGtkEntry(Entry));
|
|
exit;
|
|
end;
|
|
|
|
// if we are a fixed un-editable combo then ...
|
|
Index := GetItemIndex(TCustomComboBox(AWinControl));
|
|
if Index > -1 then AText := TCustomComboBox(AWinControl).Items.Strings[Index]
|
|
else Result := False;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetArrowKeysTraverseList(
|
|
const ACustomComboBox: TCustomComboBox; NewTraverseList: boolean);
|
|
begin
|
|
// TODO
|
|
// This is not an option that is available for this widget
|
|
// we will have to eat the keystrokes to set this to false
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetSelStart(
|
|
const ACustomComboBox: TCustomComboBox; NewStart: integer);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkWidget;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
gtk_entry_select_region(PGtkEntry(Entry), NewStart, NewStart);
|
|
end;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetSelLength(
|
|
const ACustomComboBox: TCustomComboBox; NewLength: integer);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkWidget;
|
|
Start: Integer;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
Start := GetSelStart(ACustomComboBox);
|
|
gtk_entry_select_region(PGtkEntry(Entry), Start, NewLength);
|
|
end;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetItemIndex(
|
|
const ACustomComboBox: TCustomComboBox; NewIndex: integer);
|
|
var
|
|
P: PGtkWidget;
|
|
WidgetInfo: PWidgetInfo;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
p := WidgetInfo^.CoreWidget;
|
|
if gtk_combo_box_get_active(PGtkComboBox(p)) = NewIndex then exit;
|
|
// to be delphi compatible OnChange only fires in response to user actions not program actions
|
|
// so we use WidgetInfo^.Userdata as a flag to not signal the OnChange Event
|
|
WidgetInfo^.UserData := Pointer(1);
|
|
gtk_combo_box_set_active(PGtkComboBox(p), NewIndex);
|
|
WidgetInfo^.UserData := Pointer(nil);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetMaxLength(
|
|
const ACustomComboBox: TCustomComboBox; NewLength: integer);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkWidget;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
gtk_entry_set_max_length(PGtkEntry(Entry), NewLength);
|
|
end;
|
|
// We save this in the ClientWidget for when the Entry Changes styles
|
|
g_object_set_data(PGObject(WidgetInfo^.ClientWidget), 'max-length', Pointer(PtrInt(NewLength)));
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetStyle(
|
|
const ACustomComboBox: TCustomComboBox; NewStyle: TComboBoxStyle);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
p: PGtkWidget;
|
|
begin
|
|
if csDesigning in ACustomComboBox.ComponentState then exit;
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
p := WidgetInfo^.CoreWidget;
|
|
case NewStyle of
|
|
csDropDown,
|
|
csSimple:
|
|
begin
|
|
if gtk_is_combo_box_entry(p) then Exit;
|
|
ReCreateCombo(ACustomComboBox, True, WidgetInfo);
|
|
end;
|
|
csDropDownList,
|
|
csOwnerDrawFixed,
|
|
csOwnerDrawVariable:
|
|
begin
|
|
if not gtk_is_combo_box_entry(p) then Exit;
|
|
ReCreateCombo(ACustomComboBox, False, WidgetInfo);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetReadOnly(
|
|
const ACustomComboBox: TCustomComboBox; NewReadOnly: boolean);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkWidget;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(ACustomComboBox.Handle));
|
|
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
gtk_entry_set_editable(PGtkEntry(Entry), not NewReadOnly);
|
|
end;
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.GetItems(const ACustomComboBox: TCustomComboBox
|
|
): TStrings;
|
|
var
|
|
Widget: PGtkWidget;// pointer to gtk-widget
|
|
Handle: HWND;
|
|
begin
|
|
Handle := ACustomComboBox.Handle;
|
|
|
|
Widget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
|
|
Result := TGtkListStoreStringList.Create(
|
|
gtk_combo_box_get_model(PGtkComboBox(Widget)),
|
|
0,
|
|
ACustomComboBox);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.Sort(const ACustomComboBox: TCustomComboBox;
|
|
AList: TStrings; IsSorted: boolean);
|
|
begin
|
|
// TODO
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetColor(const AWinControl: TWinControl);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Child: PGtkWidget; // can be GtkCellRenderer or GtkEntry
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(AWinControl.Handle));
|
|
|
|
Child := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
Gtk2WidgetSet.SetWidgetColor(Child, AWinControl.Font.Color, AWinControl.Color,[GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED,GTK_STYLE_BASE]);
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetFont(const AWinControl: TWinControl;
|
|
const AFont : TFont);
|
|
var
|
|
AWidget: PGTKWidget;
|
|
EntryWidget: PGtkWidget;
|
|
begin
|
|
if not AWinControl.HandleAllocated then exit;
|
|
if AFont.IsDefault then exit;
|
|
|
|
AWidget:= PGtkWidget(AWinControl.Handle);
|
|
EntryWidget:=PGtkCombo(AWidget)^.entry;
|
|
|
|
if EntryWidget<>nil then begin
|
|
Gtk2WidgetSet.SetWidgetColor(EntryWidget, AWinControl.font.color, clNone,
|
|
[GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED,GTK_STYLE_TEXT]);
|
|
Gtk2WidgetSet.SetWidgetFont(EntryWidget, AFont);
|
|
end;
|
|
end;
|
|
|
|
class procedure TGtk2WSCustomComboBox.SetText(const AWinControl: TWinControl;
|
|
const AText: String);
|
|
var
|
|
WidgetInfo: PWidgetInfo;
|
|
Entry: PGtkWidget;
|
|
Index: Integer;
|
|
begin
|
|
WidgetInfo := GetWidgetInfo(Pointer(AWinControl.Handle));
|
|
// we use user data to not signal onchange
|
|
WidgetInfo^.UserData := Pointer(1);
|
|
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
|
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
|
gtk_entry_set_text(PGtkEntry(Entry), PChar(AText));
|
|
end
|
|
else begin
|
|
// if not an entry it is a readonly list so we will try to comply by matching the text to an item
|
|
Index := TCustomComboBox(AWinControl).Items.IndexOf(AText);
|
|
SetItemIndex(TCustomComboBox(AWinControl), Index);
|
|
end;
|
|
WidgetInfo^.UserData := nil;
|
|
end;
|
|
|
|
class function TGtk2WSCustomComboBox.CreateHandle(const AWinControl: TWinControl;
|
|
const AParams: TCreateParams): TLCLIntfHandle;
|
|
var
|
|
Box, // this makes it easy to switch between GtkComBox and GtkComboBoxEntry
|
|
p: PGtkWidget; // ptr to the newly created GtkWidget
|
|
|
|
ListStore : PGtkListStore;
|
|
WidgetInfo: PWidgetInfo;
|
|
begin
|
|
Box := gtk_event_box_new;
|
|
|
|
WidgetInfo := CreateWidgetInfo(Box, AWinControl, AParams);
|
|
|
|
ListStore := gtk_list_store_new (2, [G_TYPE_STRING, G_TYPE_POINTER, nil]);
|
|
|
|
case TCustomComboBox(AWinControl).Style of
|
|
csDropDown, csSimple: p := gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL (ListStore), 0);
|
|
csDropDownList,
|
|
csOwnerDrawFixed,
|
|
csOwnerDrawVariable : p := gtk_combo_box_new_with_model(GTK_TREE_MODEL (ListStore));
|
|
end;
|
|
|
|
SetMainWidget(p, GTK_BIN(p)^.child);
|
|
|
|
g_object_unref (G_OBJECT (liststore));
|
|
|
|
gtk_container_add(PGtkContainer(Box), p);
|
|
gtk_widget_show_all(Box);
|
|
|
|
SetRenderer(TCustomComboBox(AWinControl), p);
|
|
|
|
SetMainWidget(Box, p);
|
|
WidgetInfo^.CoreWidget := p;
|
|
WidgetInfo^.ClientWidget := Box;
|
|
|
|
//gtk_widget_add_events(Box, GDK_ALL_EVENTS_MASK);
|
|
|
|
SetCallbacks(AWinControl, p, WidgetInfo);
|
|
|
|
Result := TLCLIntfHandle(Box);
|
|
end;
|
|
|
|
initialization
|
|
|
|
////////////////////////////////////////////////////
|
|
// I M P O R T A N T
|
|
////////////////////////////////////////////////////
|
|
// To improve speed, register only classes
|
|
// which actually implement something
|
|
////////////////////////////////////////////////////
|
|
// RegisterWSComponent(TScrollBar, TGtk2WSScrollBar);
|
|
// RegisterWSComponent(TCustomGroupBox, TGtk2WSCustomGroupBox);
|
|
// RegisterWSComponent(TGroupBox, TGtk2WSGroupBox);
|
|
RegisterWSComponent(TCustomComboBox, TGtk2WSCustomComboBox);
|
|
// RegisterWSComponent(TComboBox, TGtk2WSComboBox);
|
|
RegisterWSComponent(TCustomListBox, TGtk2WSCustomListBox);
|
|
// RegisterWSComponent(TListBox, TGtk2WSListBox);
|
|
RegisterWSComponent(TCustomEdit, TGtk2WSCustomEdit);
|
|
RegisterWSComponent(TCustomMemo, TGtk2WSCustomMemo);
|
|
// RegisterWSComponent(TEdit, TGtk2WSEdit);
|
|
// RegisterWSComponent(TMemo, TGtk2WSMemo);
|
|
// RegisterWSComponent(TCustomLabel, TGtk2WSCustomLabel);
|
|
// RegisterWSComponent(TLabel, TGtk2WSLabel);
|
|
// RegisterWSComponent(TButtonControl, TGtk2WSButtonControl);
|
|
// RegisterWSComponent(TCustomCheckBox, TGtk2WSCustomCheckBox);
|
|
RegisterWSComponent(TCustomCheckBox, TGtk2WSCustomCheckBox);
|
|
// RegisterWSComponent(TToggleBox, TGtk2WSToggleBox);
|
|
// RegisterWSComponent(TRadioButton, TGtk2WSRadioButton);
|
|
// RegisterWSComponent(TCustomStaticText, TGtk2WSCustomStaticText);
|
|
// RegisterWSComponent(TStaticText, TGtk2WSStaticText);
|
|
////////////////////////////////////////////////////
|
|
end.
|