mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 19:39:24 +02:00
gtk+gtk2+win32 intf: TComboBox: fixed LM_CHANGED, LM_SELCHANGED events, now LM_CHANGED are sent, whenever the text changes, from Luiz
git-svn-id: trunk@15831 -
This commit is contained in:
parent
fc59aceece
commit
b26fda5243
@ -204,11 +204,8 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TCustomComboBox.Select;
|
||||
begin
|
||||
if ItemIndex>=0 then
|
||||
if Assigned(FOnSelect) then
|
||||
FOnSelect(Self)
|
||||
else
|
||||
Change;
|
||||
if Assigned(FOnSelect) and (ItemIndex >= 0) then
|
||||
FOnSelect(Self);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
|
@ -414,28 +414,16 @@ end;
|
||||
function gtkchangedCB( widget: PGtkWidget; data: gPointer) : GBoolean; cdecl;
|
||||
var
|
||||
Mess : TLMessage;
|
||||
AComboBox: TComboBox;
|
||||
GtkComboWidget: PGtkCombo;
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
|
||||
if ComponentIsDestroyingHandle(TWinControl(Data))
|
||||
or (LockOnChange(PgtkObject(Widget),0)>0) then exit;
|
||||
|
||||
if (TObject(Data) is TComboBox) then begin
|
||||
AComboBox:=TComboBox(Data);
|
||||
GtkComboWidget:=PGtkCombo(AComboBox.Handle);
|
||||
if (GtkComboWidget^.popwin<>nil)
|
||||
and (GTK_WIDGET_VISIBLE(GtkComboWidget^.popwin)) then begin
|
||||
// Ignoring changed events during popup
|
||||
//DebugLn(['gtkchangedCB Ignoring changed events during popup']);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF EventTrace}
|
||||
EventTrace('changed', data);
|
||||
{$ENDIF}
|
||||
FillChar(Mess, SizeOf(Mess), 0);
|
||||
Mess.Msg := LM_CHANGED;
|
||||
DeliverMessage(Data, Mess);
|
||||
end;
|
||||
@ -453,8 +441,6 @@ begin
|
||||
|
||||
Mess.Msg := CM_TEXTCHANGED;
|
||||
DeliverMessage(Data, Mess);
|
||||
|
||||
Result := CallBackDefaultReturn;
|
||||
end;
|
||||
|
||||
function gtkdaychanged(Widget: PGtkWidget; data: gPointer) : GBoolean; cdecl;
|
||||
|
@ -564,6 +564,9 @@ end;
|
||||
|
||||
procedure TGtkListStringList.BeginUpdate;
|
||||
begin
|
||||
//NOTE: in TComboBox, event handling is done inside the 'changed' event
|
||||
// of the entry widget. Here we are locking the main combo widget.
|
||||
// Currently, there's no know bug origined from this flaw.
|
||||
inc(FUpdateCount);
|
||||
if (FUpdateCount=1) and (Owner<>nil) and (Owner.HandleAllocated) then
|
||||
LockOnChange(PGtkObject(Owner.Handle),+1);
|
||||
@ -830,7 +833,7 @@ begin
|
||||
// change selection mode if needed
|
||||
if (gtkListGetSelectionMode(FGtkList)=GTK_SELECTION_BROWSE)
|
||||
and (FGtkList^.selection<>nil)
|
||||
and (g_list_nth_data(FGtkList^.children, Index)=FGtkList^.selection) then begin
|
||||
and (g_list_nth_data(FGtkList^.children, Index)=FGtkList^.selection^.data) then begin
|
||||
// item is selected and BROWSE mode is enabled
|
||||
// -> change selection mode to prevent, that gtk auto selects another child
|
||||
gtk_list_set_selection_mode(FGtkList,GTK_SELECTION_SINGLE);
|
||||
@ -855,6 +858,10 @@ begin
|
||||
gtk_list_clear_items(FGtkList, Index, Index + 1);
|
||||
Include(FStates,glsItemCacheNeedsUpdate);
|
||||
|
||||
//Clear the combobox text
|
||||
if FOwner is TCustomComboBox then
|
||||
SetComboBoxText(PGtkCombo(FOwner.Handle), '');
|
||||
|
||||
{$IFDEF CheckGtkList}
|
||||
ConsistencyCheck;
|
||||
{$ENDIF}
|
||||
|
@ -867,23 +867,22 @@ end;
|
||||
|
||||
Sets the text of the combobox entry.
|
||||
------------------------------------------------------------------------------}
|
||||
procedure SetComboBoxText(ComboWidget: PGtkCombo; NewText: PChar);
|
||||
|
||||
procedure SetComboBoxText(ComboWidget: PGtkCombo; const NewText: String);
|
||||
begin
|
||||
//DebugLn('SetComboBoxText ',DbgS(ComboWidget),' "',NewText,'"');
|
||||
// lock combobox, so that no OnChange event is fired
|
||||
LockOnChange(PGtkObject(ComboWidget^.entry),+1);
|
||||
LockOnChange(PGtkObject(ComboWidget^.list),+1);
|
||||
// lock combobox, so that no OnChange event is not fired
|
||||
LockOnChange(PGtkObject(ComboWidget^.entry), +1);
|
||||
// set text
|
||||
if NewText = nil then NewText:=#0; // gtk expects at least a #0
|
||||
gtk_entry_set_text(PGtkEntry(ComboWidget^.entry), NewText);
|
||||
// The String > PChar conversion ensures at least a null terminated string
|
||||
gtk_entry_set_text(PGtkEntry(ComboWidget^.entry), PChar(NewText));
|
||||
// unlock combobox
|
||||
LockOnChange(PGtkObject(ComboWidget^.list),-1);
|
||||
LockOnChange(PGtkObject(ComboWidget^.entry),-1);
|
||||
LockOnChange(PGtkObject(ComboWidget^.entry), -1);
|
||||
end;
|
||||
|
||||
|
||||
function GetComboBoxText(ComboWidget: PGtkCombo): string;
|
||||
begin
|
||||
Result:=StrPas(gtk_entry_get_text(PGtkEntry(ComboWidget^.entry)));
|
||||
Result := String(gtk_entry_get_text(PGtkEntry(ComboWidget^.entry)));
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -909,23 +908,29 @@ end;
|
||||
{------------------------------------------------------------------------------
|
||||
procedure SetComboBoxItemIndex(ComboBox: TCustomComboBox; Index: integer);
|
||||
|
||||
Returns the current ItemIndex of a TComboBox
|
||||
Set the current ItemIndex of a TComboBox
|
||||
------------------------------------------------------------------------------}
|
||||
procedure SetComboBoxItemIndex(ComboBox: TCustomComboBox; Index: integer);
|
||||
var
|
||||
ComboWidget: PGtkCombo;
|
||||
ComboStrings: TStrings;
|
||||
WidgetInfo: PWidgetInfo;
|
||||
begin
|
||||
ComboWidget:=PGtkCombo(ComboBox.Handle);
|
||||
LockOnChange(PGtkObject(ComboWidget),+1);
|
||||
gtk_list_select_item(PGtkList(ComboWidget^.list),Index);
|
||||
if Index>=0 then begin
|
||||
ComboStrings:=TStrings(gtk_object_get_data(PGtkObject(ComboWidget),GtkListItemLCLListTag));
|
||||
if Index < ComboStrings.Count
|
||||
then SetComboBoxText(ComboWidget, PChar(ComboStrings[Index]))
|
||||
else SetComboBoxText(ComboWidget, '#error#');
|
||||
ComboWidget := PGtkCombo(ComboBox.Handle);
|
||||
WidgetInfo := GetWidgetInfo(ComboWidget);
|
||||
//Store the LCLIndex
|
||||
PInteger(WidgetInfo^.UserData)^ := Index;
|
||||
//Avoid calling OnChange/OnSelect events
|
||||
LockOnChange(PGtkObject(ComboWidget), +1);
|
||||
//gtk_list_select_item does not update the list when Index is -1
|
||||
if Index > -1 then
|
||||
gtk_list_select_item(PGtkList(ComboWidget^.list), Index)
|
||||
else
|
||||
begin
|
||||
gtk_list_set_selection_mode(PGtkList(ComboWidget^.list),
|
||||
GTK_SELECTION_SINGLE);
|
||||
SetComboBoxText(ComboWidget, '');
|
||||
end;
|
||||
LockOnChange(PGtkObject(ComboWidget),-1);
|
||||
LockOnChange(PGtkObject(ComboWidget), -1);
|
||||
end;
|
||||
|
||||
procedure SetLabelAlignment(LabelWidget: PGtkLabel;
|
||||
@ -6348,22 +6353,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function gtkListSelectChild(widget: PGtkWidget; child: PGtkWidget;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
var
|
||||
Mess: TLMessage;
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
if LockOnChange(PgtkObject(TWinControl(Data).Handle),0) > 0 then Exit;
|
||||
|
||||
{$IFDEF EventTrace}
|
||||
EventTrace('gtkListSelectChild', data);
|
||||
{$ENDIF}
|
||||
FillChar(Mess,SizeOf(Mess),0);
|
||||
Mess.msg := LM_SelChange;
|
||||
DeliverMessage(Data, Mess);
|
||||
end;
|
||||
|
||||
function gtkListGetSelectionMode(list: PGtkList): TGtkSelectionMode; cdecl;
|
||||
begin
|
||||
Result:=TGtkSelectionMode(
|
||||
|
@ -62,7 +62,6 @@ uses
|
||||
const
|
||||
GtkListItemGtkListTag = 'GtkList';
|
||||
GtkListItemLCLListTag = 'LCLList';
|
||||
GtkComboLCLItemIndexTag = 'LCLItemIndex';
|
||||
|
||||
|
||||
type
|
||||
@ -355,7 +354,7 @@ procedure GrabMouseToForm(AForm: TCustomForm);
|
||||
procedure ReleaseMouseFromForm(AForm: TCustomForm);
|
||||
|
||||
// combobox
|
||||
procedure SetComboBoxText(ComboWidget: PGtkCombo; NewText: PChar);
|
||||
procedure SetComboBoxText(ComboWidget: PGtkCombo; const NewText: String);
|
||||
function GetComboBoxText(ComboWidget: PGtkCombo): string;
|
||||
function GetComboBoxItemIndex(ComboBox: TCustomComboBox): integer;
|
||||
procedure SetComboBoxItemIndex(ComboBox: TCustomComboBox; Index: integer);
|
||||
@ -665,11 +664,8 @@ procedure UpdateStatusBarPanel(StatusBar: TObject; Index: integer;
|
||||
StatusPanelWidget: PGtkWidget);
|
||||
|
||||
// list
|
||||
function gtkListSelectChild(widget: PGtkWidget; child: PGtkWidget;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
function gtkListGetSelectionMode(list: PGtkList): TGtkSelectionMode;cdecl;
|
||||
|
||||
|
||||
// sizing
|
||||
procedure SaveSizeNotification(Widget: PGtkWidget);
|
||||
procedure SaveClientSizeNotification(FixWidget: PGtkWidget);
|
||||
|
@ -3103,10 +3103,6 @@ begin
|
||||
'value_changed', @gtkvaluechanged);
|
||||
end
|
||||
else
|
||||
if ALCLObject is TCustomCombobox then
|
||||
ConnectSenderSignal (PGtkObject(
|
||||
PGtkCombo(gObject)^.entry), 'changed', @gtkchangedCB)
|
||||
else
|
||||
if ALCLObject is TCustomMemo then
|
||||
ConnectSenderSignal(gCore, 'changed', @gtkchanged_editbox)
|
||||
else if ALCLObject is TCustomCheckbox then
|
||||
@ -3449,13 +3445,9 @@ begin
|
||||
|
||||
LM_SelChange:
|
||||
begin
|
||||
if ALCLObject is TCustomListBox then begin
|
||||
if ALCLObject is TCustomListBox then
|
||||
ConnectSenderSignalAfter(PgtkObject(gCore),
|
||||
'selection_changed', @gtkListBoxSelectionChangedAfter);
|
||||
end else if ALCLObject is TCustomCombobox then begin
|
||||
ConnectSenderSignal (PGtkObject(PGtkCombo(gObject)^.list),
|
||||
'unselect_child', @gtkListSelectChild);
|
||||
end;
|
||||
end;
|
||||
|
||||
LM_DROPFILES:
|
||||
@ -3654,7 +3646,7 @@ begin
|
||||
if GtkWidgetIsA(Widget,GTK_COMBO_GET_TYPE) then begin
|
||||
g_signal_handlers_destroy(PGtkObject(PGtkCombo(Widget)^.Entry));
|
||||
g_signal_handlers_destroy(PGtkObject(PGtkCombo(Widget)^.List));
|
||||
SetComboBoxText(PGtkCombo(Widget),nil);
|
||||
SetComboBoxText(PGtkCombo(Widget), '');
|
||||
|
||||
// MWE:
|
||||
// TODO: Check: Why is there widgetinfo on subwidgets ???
|
||||
|
@ -675,7 +675,7 @@ begin
|
||||
begin
|
||||
//DebugLn('SetLabel: ',TComboBox(Sender).Name,':',TComboBox(Sender).ClassName,
|
||||
// ' ',DbgS(TComboBox(Sender).Handle),' "',PLabel,'"');
|
||||
SetComboBoxText(PGtkCombo(TComboBox(AWinControl).Handle), PLabel);
|
||||
SetComboBoxText(PGtkCombo(TComboBox(AWinControl).Handle), AText)
|
||||
end;
|
||||
|
||||
else
|
||||
|
@ -804,15 +804,64 @@ end;
|
||||
{ TGtkWSCustomComboBox }
|
||||
|
||||
{$IFDEF GTK1}
|
||||
|
||||
function gtkComboBoxChanged(widget: PGtkWidget; data: gPointer) : GBoolean; cdecl;
|
||||
var
|
||||
Mess : TLMessage;
|
||||
GtkComboWidget: PGtkCombo;
|
||||
GtkListWidget: PGtkList;
|
||||
LCLIndex: PInteger;
|
||||
GtkIndex: Integer;
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
|
||||
if ComponentIsDestroyingHandle(TWinControl(Data)) or
|
||||
(LockOnChange(PGtkObject(Widget), 0) > 0) or
|
||||
(gtk_signal_n_emissions_by_name(PGtkObject(widget), 'changed') > 1)
|
||||
then exit;
|
||||
|
||||
{$IFDEF EventTrace}
|
||||
EventTrace('changed', data);
|
||||
{$ENDIF}
|
||||
FillChar(Mess, SizeOf(Mess), 0);
|
||||
Mess.Msg := LM_CHANGED;
|
||||
DeliverMessage(Data, Mess);
|
||||
|
||||
GtkComboWidget := PGtkCombo(TComboBox(Data).Handle);
|
||||
GtkListWidget := PGtkList(GtkComboWidget^.list);
|
||||
LCLIndex := PInteger(GetWidgetInfo(GtkComboWidget)^.UserData);
|
||||
|
||||
//Check if an item is selected
|
||||
if (GtkListWidget^.selection <> nil) then
|
||||
begin
|
||||
GtkIndex := gtk_list_child_position(GtkListWidget,
|
||||
PGtkWidget(GtkListWidget^.selection^.data));
|
||||
//If the selected item index changed send a LM_SELCHANGE msg
|
||||
if LCLIndex^ <> GtkIndex then
|
||||
begin
|
||||
gtk_list_set_selection_mode(GtkListWidget, GTK_SELECTION_BROWSE);
|
||||
LCLIndex^ := GtkIndex;
|
||||
Mess.Msg := LM_SELCHANGE;
|
||||
DeliverMessage(Data, Mess);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
LCLIndex^ := -1;
|
||||
gtk_list_set_selection_mode(GtkListWidget, GTK_SELECTION_SINGLE);
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TGtkWSCustomComboBox.SetCallbacks(const AGtkWidget: PGtkWidget;
|
||||
const AWidgetInfo: PWidgetInfo);
|
||||
begin
|
||||
TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
|
||||
with TGtkWidgetset(Widgetset) do
|
||||
begin
|
||||
SetCallback(LM_CHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject);
|
||||
//gtk1 and gtk2 have different 'changed' event handlers
|
||||
ConnectSignal(PGtkObject(PGtkCombo(AGtkWidget)^.entry),
|
||||
'changed', @gtkComboBoxChanged, AWidgetInfo^.LCLObject);
|
||||
SetCallback(LM_COMMAND, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject);
|
||||
SetCallback(LM_SELCHANGE, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -826,6 +875,7 @@ var
|
||||
ItemList: TGtkListStringList;
|
||||
GtkList: PGtkList;
|
||||
Allocation: TGtkAllocation;
|
||||
LCLIndex: PInteger;
|
||||
begin
|
||||
Widget := gtk_combo_new();
|
||||
|
||||
@ -834,13 +884,19 @@ begin
|
||||
gtk_combo_disable_activate(ComboWidget);
|
||||
gtk_combo_set_case_sensitive(ComboWidget, GdkTrue);
|
||||
|
||||
// Prevents the OnSelect event be fired after inserting the first item
|
||||
// or deleting the selected item
|
||||
GtkList:=PGtkList(ComboWidget^.List);
|
||||
if GtkList^.selection = nil then
|
||||
gtk_list_set_selection_mode(GtkList, GTK_SELECTION_SINGLE)
|
||||
else
|
||||
gtk_list_set_selection_mode(GtkList, GTK_SELECTION_BROWSE);
|
||||
|
||||
// Switching the selection mode is necessary to avoid the following problems:
|
||||
// - The first added item is automatically selected when mode is "BROWSE"
|
||||
// - Is not possible to select the previous selected item if mode is "BROWSE"
|
||||
// and current index is -1
|
||||
// - The item is deselected after a second click if mode is "SINGLE"
|
||||
// - The OnSelect event could be fired after add the first item when mode is
|
||||
// "BROWSE". Since LM_SELCHANGE is sent in 'changed' event now, no problem.
|
||||
// So basically the mode is set to BROWSE when a item is selected and
|
||||
// "SINGLE" when there's no item selected
|
||||
|
||||
gtk_list_set_selection_mode(GtkList, GTK_SELECTION_SINGLE);
|
||||
|
||||
// Items
|
||||
ItemList:= TGtkListStringList.Create(GtkList, ComboBox, False);
|
||||
@ -848,9 +904,18 @@ begin
|
||||
ItemList.Assign(ComboBox.Items);
|
||||
ItemList.Sorted:= ComboBox.Sorted;
|
||||
|
||||
WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams);
|
||||
New(LCLIndex);
|
||||
WidgetInfo^.UserData := LCLIndex;
|
||||
WidgetInfo^.DataOwner := True;
|
||||
// ItemIndex
|
||||
if ComboBox.ItemIndex >= 0 then
|
||||
begin
|
||||
gtk_list_select_item(GtkList, ComboBox.ItemIndex);
|
||||
LCLIndex^ := ComboBox.ItemIndex;
|
||||
end
|
||||
else
|
||||
LCLIndex^ := -1;
|
||||
|
||||
// MaxLength
|
||||
gtk_entry_set_max_length(PGtkEntry(ComboWidget^.entry),guint16(ComboBox.MaxLength));
|
||||
@ -859,7 +924,7 @@ begin
|
||||
DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl));
|
||||
{$ENDIF}
|
||||
Result := THandle(PtrUInt(Widget));
|
||||
WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams);
|
||||
|
||||
|
||||
Allocation.X := AParams.X;
|
||||
Allocation.Y := AParams.Y;
|
||||
|
@ -488,10 +488,23 @@ end;
|
||||
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TGtkListStoreStringList.Clear;
|
||||
var
|
||||
WidgetInfo: PWidgetInfo;
|
||||
begin
|
||||
//DebugLn(['TGtkListStoreStringList.Clear ']);
|
||||
//while Count>0 do Delete(Count-1);
|
||||
gtk_list_store_clear(FGtkListStore);
|
||||
|
||||
//Lock the widget to avoid trigger events
|
||||
//Note: Assign/Clear is called inside CreateHandle before Handle is set
|
||||
if FOwner.HandleAllocated then begin
|
||||
WidgetInfo := GetWidgetInfo(Pointer(FOwner.Handle), False);
|
||||
if WidgetInfo <> nil then
|
||||
Inc(WidgetInfo^.ChangeLock);
|
||||
gtk_list_store_clear(FGtkListStore);
|
||||
if WidgetInfo <> nil then
|
||||
Dec(WidgetInfo^.ChangeLock);
|
||||
end;
|
||||
|
||||
IncreaseChangeStamp;
|
||||
|
||||
ReAllocMem(FCachedItems,0);
|
||||
@ -511,6 +524,7 @@ end;
|
||||
procedure TGtkListStoreStringList.Delete(Index : integer);
|
||||
var
|
||||
ListItem: TGtkTreeIter;
|
||||
WidgetInfo: PWidgetInfo;
|
||||
begin
|
||||
if not (glsItemCacheNeedsUpdate in FStates) then
|
||||
ListItem := FCachedItems[Index]
|
||||
@ -518,8 +532,11 @@ begin
|
||||
gtk_tree_model_iter_nth_child(FGtkListStore, @ListItem, nil, Index);
|
||||
|
||||
//gtk_list_store_g
|
||||
WidgetInfo := GetWidgetInfo(Pointer(FOwner.Handle));
|
||||
//Lock the widget to avoid trigger events
|
||||
Inc(WidgetInfo^.ChangeLock);
|
||||
gtk_list_store_remove(FGtkListStore, @ListItem);
|
||||
|
||||
Dec(WidgetInfo^.ChangeLock);
|
||||
IncreaseChangeStamp;
|
||||
|
||||
if not (glsCountNeedsUpdate in FStates) then
|
||||
@ -532,6 +549,9 @@ begin
|
||||
ShrinkCache;
|
||||
end else
|
||||
Include(FStates, glsItemCacheNeedsUpdate);
|
||||
|
||||
if FOwner is TCustomComboBox then
|
||||
TGtk2WSCustomComboBox.SetText(FOwner, '');
|
||||
end;
|
||||
|
||||
function TGtkListStoreStringList.IndexOf(const S: string): Integer;
|
||||
|
@ -460,6 +460,7 @@ class procedure TGtk2WSCustomListBox.SetItemIndex(
|
||||
const ACustomListBox: TCustomListBox; const AIndex: integer);
|
||||
var
|
||||
Widget: PGtkWidget;
|
||||
WidgetInfo: PWidgetInfo;
|
||||
Selection: PGtkTreeSelection;
|
||||
Path: PGtkTreePath;
|
||||
|
||||
@ -476,12 +477,14 @@ begin
|
||||
if not WSCheckHandleAllocated(ACustomListBox, 'SetItemIndex') then
|
||||
Exit;
|
||||
|
||||
Widget := GetWidgetInfo(Pointer(ACustomListBox.Handle), True)^.CoreWidget;
|
||||
WidgetInfo := GetWidgetInfo(Pointer(ACustomListBox.Handle), True);
|
||||
Widget := WidgetInfo^.CoreWidget;
|
||||
if not GtkWidgetIsA(Widget, gtk_tree_view_get_type) then
|
||||
raise Exception.Create('');
|
||||
|
||||
Selection := gtk_tree_view_get_selection(PGtkTreeView(Widget));
|
||||
|
||||
Inc(WidgetInfo^.ChangeLock);
|
||||
if (AIndex < 0) then
|
||||
if (gtk_tree_selection_get_mode(Selection) <> GTK_SELECTION_SINGLE) then
|
||||
Path := gtk_tree_path_new_first
|
||||
@ -502,6 +505,7 @@ begin
|
||||
|
||||
if Path <> nil then
|
||||
gtk_tree_path_free(Path);
|
||||
Dec(WidgetInfo^.ChangeLock);
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomListBox.SetSelectionMode(
|
||||
@ -576,17 +580,19 @@ begin
|
||||
end;
|
||||
|
||||
function gtk2ListBoxSelectionChangedAfter(Widget: PGtkWidget;
|
||||
AWinControl: TWinControl): gboolean; cdecl;
|
||||
WidgetInfo: PWidgetInfo): gboolean; cdecl;
|
||||
var
|
||||
Mess: TLMessage;
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
if WidgetInfo^.ChangeLock > 0 then
|
||||
Exit;
|
||||
{$IFDEF EventTrace}
|
||||
EventTrace('gtk2ListSelectionChangedAfter', dbgsName(AWinControl));
|
||||
EventTrace('gtk2ListSelectionChangedAfter', WidgetInfo^.LCLObject);
|
||||
{$ENDIF}
|
||||
FillChar(Mess,SizeOf(Mess),0);
|
||||
Mess.msg := LM_SelChange;
|
||||
DeliverMessage(AWinControl, Mess);
|
||||
DeliverMessage(WidgetInfo^.LCLObject, Mess);
|
||||
end;
|
||||
|
||||
class function TGtk2WSCustomListBox.CreateHandle(const AWinControl: TWinControl;
|
||||
@ -646,7 +652,7 @@ begin
|
||||
end;
|
||||
|
||||
g_signal_connect_after(Selection, 'changed',
|
||||
G_CALLBACK(@gtk2ListBoxSelectionChangedAfter), AWinControl);
|
||||
G_CALLBACK(@gtk2ListBoxSelectionChangedAfter), WidgetInfo);
|
||||
|
||||
// Sets the callbacks
|
||||
SetCallbacks(p, WidgetInfo);
|
||||
@ -964,11 +970,13 @@ begin
|
||||
// keep items
|
||||
ItemList := ACustomComboBox.Items as TGtkListStoreStringList;
|
||||
|
||||
LCLIndex := gtk_object_get_data(GTK_OBJECT(ComboWidget), GtkComboLCLItemIndexTag);
|
||||
LCLIndex := AWidgetInfo^.UserData;
|
||||
if not Assigned(LCLIndex) then begin
|
||||
//debugln('Gtk2WSCustomComboBox ReCreateCombo: LCLIndex unassigned!');
|
||||
LCLIndex := New(PLongint);
|
||||
LCLIndex^ := -1;
|
||||
AWidgetInfo^.UserData := LCLIndex;
|
||||
AWidgetInfo^.DataOwner := True;
|
||||
end;
|
||||
|
||||
// this should work but may not in all circumstances
|
||||
@ -980,7 +988,6 @@ begin
|
||||
if Index = -1 then Index := GetItemIndex(ACustomComboBox);
|
||||
|
||||
gtk_object_set_data(PGtkObject(ComboWidget), GtkListItemLCLListTag,nil);
|
||||
gtk_object_set_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag, nil);
|
||||
gtk_widget_destroy(ComboWidget);
|
||||
|
||||
// create the new widget with the old model
|
||||
@ -990,7 +997,6 @@ begin
|
||||
end;
|
||||
// undone the above increase of the ref count
|
||||
gtk_object_set_data(PGtkObject(ComboWidget),GtkListItemLCLListTag,ItemList);
|
||||
gtk_object_set_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag, LCLIndex);
|
||||
g_object_unref (G_OBJECT(Model));
|
||||
|
||||
SetMainWidget(Box, GTK_BIN(ComboWidget)^.child);
|
||||
@ -1070,11 +1076,11 @@ var
|
||||
LCLIndex: PLongint;
|
||||
Index, GtkIndex: Integer;
|
||||
begin
|
||||
if WidgetInfo^.UserData <> nil then Exit;
|
||||
if WidgetInfo^.ChangeLock > 0 then Exit;
|
||||
LCLSendChangedMsg(TControl(WidgetInfo^.LCLObject));
|
||||
|
||||
Index := -1;
|
||||
LCLIndex := gtk_object_get_data(GTK_OBJECT(WidgetInfo^.CoreWidget), GtkComboLCLItemIndexTag);
|
||||
LCLIndex := WidgetInfo^.UserData;
|
||||
if Assigned(LCLIndex) then
|
||||
Index := LCLIndex^
|
||||
else
|
||||
@ -1287,8 +1293,7 @@ begin
|
||||
|
||||
// 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;
|
||||
if Index > -1 then AText := TCustomComboBox(AWinControl).Items.Strings[Index];
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomComboBox.SetArrowKeysTraverseList(
|
||||
@ -1341,17 +1346,20 @@ begin
|
||||
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);
|
||||
// so we use WidgetInfo^.ChangeLock as a flag to not signal the OnChange Event
|
||||
Inc(WidgetInfo^.ChangeLock);
|
||||
gtk_combo_box_set_active(PGtkComboBox(p), NewIndex);
|
||||
|
||||
LCLIndex := gtk_object_get_data(GTK_OBJECT(p), GtkComboLCLItemIndexTag);
|
||||
LCLIndex := WidgetInfo^.UserData;
|
||||
if not Assigned(LCLIndex) then
|
||||
begin
|
||||
LCLIndex := New(PLongint);
|
||||
WidgetInfo^.UserData := LCLIndex;
|
||||
WidgetInfo^.DataOwner := True;
|
||||
end;
|
||||
LCLIndex^ := NewIndex;
|
||||
gtk_object_set_data(GTK_OBJECT(p), GtkComboLCLItemIndexTag, LCLIndex); // set LCLIndex for OnChange -> OnSelect
|
||||
|
||||
WidgetInfo^.UserData := Pointer(nil);
|
||||
Dec(WidgetInfo^.ChangeLock);
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomComboBox.SetMaxLength(
|
||||
@ -1472,8 +1480,8 @@ var
|
||||
Index: Integer;
|
||||
begin
|
||||
WidgetInfo := GetWidgetInfo(Pointer(AWinControl.Handle));
|
||||
// we use user data to not signal onchange
|
||||
WidgetInfo^.UserData := Pointer(1);
|
||||
// we use user ChangeLock to not signal onchange
|
||||
Inc(WidgetInfo^.ChangeLock);
|
||||
if gtk_is_combo_box_entry(WidgetInfo^.CoreWidget) then begin
|
||||
Entry := GTK_BIN(WidgetInfo^.CoreWidget)^.child;
|
||||
gtk_entry_set_text(PGtkEntry(Entry), PChar(AText));
|
||||
@ -1483,7 +1491,7 @@ begin
|
||||
Index := TCustomComboBox(AWinControl).Items.IndexOf(AText);
|
||||
SetItemIndex(TCustomComboBox(AWinControl), Index);
|
||||
end;
|
||||
WidgetInfo^.UserData := nil;
|
||||
Dec(WidgetInfo^.ChangeLock);
|
||||
end;
|
||||
|
||||
class function TGtk2WSCustomComboBox.CreateHandle(const AWinControl: TWinControl;
|
||||
@ -1529,12 +1537,13 @@ begin
|
||||
if PGtkComboBoxPrivate(PGtkComboBox(ComboWidget)^.priv)^.button <> nil then
|
||||
SetMainWidget(Box, PGtkComboBoxPrivate(PGtkComboBox(ComboWidget)^.priv)^.button);
|
||||
|
||||
LCLIndex := New(PLongint);
|
||||
//Should not set the ItemIndex value here?
|
||||
LCLIndex^ := -1;
|
||||
WidgetInfo^.CoreWidget := ComboWidget;
|
||||
WidgetInfo^.ClientWidget := Box;
|
||||
|
||||
LCLIndex := New(PLongint);
|
||||
LCLIndex^ := -1;
|
||||
gtk_object_set_data(GTK_OBJECT(ComboWidget), GtkComboLCLItemIndexTag, LCLIndex);
|
||||
WidgetInfo^.UserData := LCLIndex;
|
||||
WidgetInfo^.DataOwner := True;
|
||||
|
||||
//gtk_widget_add_events(Box, GDK_ALL_EVENTS_MASK);
|
||||
|
||||
@ -1556,17 +1565,10 @@ class procedure TGtk2WSCustomComboBox.DestroyHandle(
|
||||
var
|
||||
Handle: HWND;
|
||||
ComboWidget: PGtkWidget;
|
||||
LCLIndex: PLongint;
|
||||
begin
|
||||
Handle := AWinControl.Handle;
|
||||
ComboWidget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget;
|
||||
gtk_object_set_data(PGtkObject(ComboWidget),GtkListItemLCLListTag,nil);
|
||||
LCLIndex := gtk_object_get_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag);
|
||||
if Assigned(LCLIndex) then begin
|
||||
gtk_object_set_data(PGtkObject(ComboWidget), GtkComboLCLItemIndexTag, nil);
|
||||
Dispose(LCLIndex);
|
||||
end else
|
||||
debugln('Gtk2WSCustomComboBox DestroyHandle: LCLIndex unassigned!');
|
||||
|
||||
//DebugLn(['TGtk2WSCustomComboBox.DestroyHandle ',dbgsName(AWinControl),' ClassParent=',ClassParent.ClassName]);
|
||||
|
||||
|
@ -1374,6 +1374,7 @@ begin
|
||||
itemindex is updated, so set text manually }
|
||||
CBN_SELCHANGE: begin
|
||||
UpdateComboBoxText(TCustomComboBox(lWinControl));
|
||||
SendSimpleMessage(lWinControl, LM_CHANGED);
|
||||
LMessage.Msg := LM_SELCHANGE;
|
||||
end;
|
||||
{ closeup message is sent before text is actually changed... *sigh*
|
||||
|
@ -280,7 +280,7 @@ uses
|
||||
// Win32WSToolwin,
|
||||
Win32Themes,
|
||||
////////////////////////////////////////////////////
|
||||
Arrow, Calendar, Spin, CheckLst, Win32Extra, LclProc;
|
||||
Arrow, Calendar, Spin, CheckLst, Win32Extra, LclProc, LCLMessageGlue;
|
||||
|
||||
type
|
||||
TMouseDownFocusStatus = (mfNone, mfFocusSense, mfFocusChanged);
|
||||
|
Loading…
Reference in New Issue
Block a user