gtk2 intf: TComboBox: fixed widgets used for events

git-svn-id: trunk@11014 -
This commit is contained in:
mattias 2007-04-27 10:58:58 +00:00
parent 12eba79c0d
commit 0e395c80ce
5 changed files with 142 additions and 100 deletions

View File

@ -253,8 +253,12 @@ type
const FGColor,BGColor : TColor;
const Mask : tGtkStateEnum);
procedure SetWidgetFont(const AWidget : PGtkWidget;const AFONT : tFont);
procedure SetCallbackEx(const AMsg: LongInt; const AGTKObject: PGTKObject;
const ALCLObject: TObject; Direct: boolean); virtual;
procedure SetCallbackDirect(const AMsg: LongInt; const AGTKObject: PGTKObject;
const ALCLObject: TObject);
procedure SetCallback(const AMsg: LongInt; const AGTKObject: PGTKObject;
const ALCLObject: TObject); virtual;
const ALCLObject: TObject);
procedure SendPaintMessagesForInternalWidgets(AWinControl: TWinControl);
function LCLtoGtkMessagePending: boolean;virtual;
procedure SendCachedGtkMessages;virtual;

View File

@ -3581,18 +3581,20 @@ begin
end;
{------------------------------------------------------------------------------
Function: TGtkWidgetSet.SetCallback
Function: TGtkWidgetSet.SetCallbackEx
Params: AMsg - message for which to set a callback
AGTKObject - object to which callback will be send
ALCLObject - for compatebility reasons provided, will be used when
AGTKObject = nil
Direct - true: connect the signal to the AGTKObject
false: choose smart what gtkobject to use
Returns: nothing
Applies a Message to the sender
------------------------------------------------------------------------------}
//TODO: remove ALCLObject when creation splitup is finished
procedure TGtkWidgetSet.SetCallback(const AMsg: LongInt;
const AGTKObject: PGTKObject; const ALCLObject: TObject);
procedure TGtkWidgetSet.SetCallbackEx(const AMsg: LongInt;
const AGTKObject: PGTKObject; const ALCLObject: TObject; Direct: boolean);
procedure ConnectSenderSignal(const AnObject:PGTKObject; const ASignal: PChar;
const ACallBackProc: Pointer);
@ -3675,32 +3677,40 @@ var
gObject, gFixed, gCore, Adjustment: PGTKObject;
Info: PWidgetInfo;
gMain: PGtkObject;
MouseWidget: PGtkObject;
gMouse: PGtkObject;
begin
//debugln('TGtkWidgetSet.SetCallback A ALCLObject=',DbgSName(ALCLObject),' AMsg=',dbgs(AMsg));
if AGTKObject = nil
then gObject := ObjectToGTKObject(ALCLObject)
else gObject := AGTKObject;
if gObject = nil then Exit;
if Direct then begin
gMain:=AGTKObject;
gCore:=AGTKObject;
gFixed:=AGTKObject;
gMouse:=AGTKObject;
end else begin
if AGTKObject = nil
then gObject := ObjectToGTKObject(ALCLObject)
else gObject := AGTKObject;
if gObject = nil then Exit;
// gFixed is the widget with the client area (e.g. TGroupBox, TCustomForm have this)
gFixed := PGTKObject(GetFixedWidget(gObject));
if gFixed = nil then gFixed := gObject;
// gFixed is the widget with the client area (e.g. TGroupBox, TCustomForm have this)
gFixed := PGTKObject(GetFixedWidget(gObject));
if gFixed = nil then gFixed := gObject;
// gCore is the working widget (e.g. TListBox has a scrolling widget (=main widget) and a tree widget (=core widget))
Info:=GetWidgetInfo(gObject, True);
gCore:=PGtkObject(Info^.CoreWidget);
gMain:=GetMainWidget(gObject);
if (gMain=nil) then
gMain:=gObject;
if (gMain<>gObject) then
DebugLn(['TGtkWidgetSet.SetCallback WARNING: gObject<>MainWidget ',DbgSName(ALCLObject)]);
if gFixed<>gMain then
MouseWidget:=gFixed
else
MouseWidget:=gCore;
if MouseWidget=nil then
DebugLn(['TGtkWidgetSet.SetCallback WARNING: gMouseWidget=nil ',DbgSName(ALCLObject)]);
// gCore is the working widget (e.g. TListBox has a scrolling widget (=main widget) and a tree widget (=core widget))
Info:=GetWidgetInfo(gObject, True);
gCore:=PGtkObject(Info^.CoreWidget);
gMain:=GetMainWidget(gObject);
if (gMain=nil) then
gMain:=gObject;
if (gMain<>gObject) then
DebugLn(['TGtkWidgetSet.SetCallback WARNING: gObject<>MainWidget ',DbgSName(ALCLObject)]);
if gFixed<>gMain then
gMouse:=gFixed
else
gMouse:=gCore;
if gMouse=nil then
DebugLn(['TGtkWidgetSet.SetCallback WARNING: gMouseWidget=nil ',DbgSName(ALCLObject)]);
end;
//DebugLn(['TGtkWidgetSet.SetCallbackSmart MouseWidget=',GetWidgetDebugReport(PGtkWidget(gMouse))]);
case AMsg of
LM_SHOWWINDOW :
@ -3871,9 +3881,9 @@ begin
else
{$ENDIF}
begin
ConnectSenderSignal(MouseWidget, 'motion-notify-event', @GTKMotionNotify,
ConnectSenderSignal(gMouse, 'motion-notify-event', @GTKMotionNotify,
GDK_POINTER_MOTION_MASK);
ConnectSenderSignalAfter(MouseWidget, 'motion-notify-event',
ConnectSenderSignalAfter(gMouse, 'motion-notify-event',
@GTKMotionNotifyAfter, GDK_POINTER_MOTION_MASK);
end;
end;
@ -3903,9 +3913,9 @@ begin
else
{$ENDIF}
begin
ConnectSenderSignal(MouseWidget, 'button-press-event', @gtkMouseBtnPress,
ConnectSenderSignal(gMouse, 'button-press-event', @gtkMouseBtnPress,
GDK_BUTTON_PRESS_MASK);
ConnectSenderSignalAfter(MouseWidget, 'button-press-event',
ConnectSenderSignalAfter(gMouse, 'button-press-event',
@gtkMouseBtnPressAfter, GDK_BUTTON_PRESS_MASK);
end;
end;
@ -3936,9 +3946,9 @@ begin
else
{$ENDIF}
begin
ConnectSenderSignal(MouseWidget, 'button-release-event', @gtkMouseBtnRelease,
ConnectSenderSignal(gMouse, 'button-release-event', @gtkMouseBtnRelease,
GDK_BUTTON_RELEASE_MASK);
ConnectSenderSignalAfter(MouseWidget, 'button-release-event',
ConnectSenderSignalAfter(gMouse, 'button-release-event',
@gtkMouseBtnReleaseAfter,GDK_BUTTON_RELEASE_MASK);
end;
end;
@ -4116,6 +4126,18 @@ begin
end;
end;
procedure TGTKWidgetSet.SetCallbackDirect(const AMsg: LongInt;
const AGTKObject: PGTKObject; const ALCLObject: TObject);
begin
SetCallbackEx(AMsg,AGTKObject,ALCLObject,true);
end;
procedure TGTKWidgetSet.SetCallback(const AMsg: LongInt;
const AGTKObject: PGTKObject; const ALCLObject: TObject);
begin
SetCallbackEx(AMsg,AGTKObject,ALCLObject,false);
end;
{------------------------------------------------------------------------------
Function: TGtkWidgetSet.RemoveCallBacks

View File

@ -59,7 +59,7 @@ type
function GetText(Sender: TComponent; var Text: String): Boolean;
procedure HookSignals(const AGTKObject: PGTKObject; const ALCLObject: TObject); override;
function LoadStockPixmap(StockID: longint) : HBitmap; override;
procedure SetCallback(const AMsg: LongInt; const AGTKObject: PGTKObject; const ALCLObject: TObject);override;
procedure SetCallbackEx(const AMsg: LongInt; const AGTKObject: PGTKObject; const ALCLObject: TObject; Direct: boolean);override;
//procedure SetLabel(Sender : TObject; Data : Pointer);
procedure SetSelectionMode(Sender: TObject; Widget: PGtkWidget;
MultiSelect, ExtendedSelect: boolean); override;

View File

@ -391,14 +391,15 @@ begin
end;
{------------------------------------------------------------------------------
Function: TGtk2WidgetSet.SetCallback
Function: TGtk2WidgetSet.SetCallbackEx
Params: Msg - message for which to set a callback
sender - object to which callback will be send
Returns: nothing
Applies a Message to the sender
------------------------------------------------------------------------------}
procedure TGTK2WidgetSet.SetCallback(const AMsg: LongInt; const AGTKObject: PGTKObject; const ALCLObject: TObject);
procedure TGTK2WidgetSet.SetCallbackEx(const AMsg: LongInt;
const AGTKObject: PGTKObject; const ALCLObject: TObject; Direct: boolean);
procedure ConnectSenderSignal(const AnObject:PGTKObject; const ASignal: PChar;
const ACallBackProc: Pointer);
@ -452,15 +453,21 @@ var
gObject, gFixed, gCore: PGTKObject;
begin
//debugln('gtk2object.inc TGtkWidgetSet.SetCallback A ALCLObject=',DbgSName(ALCLObject),' AMsg=',dbgs(AMsg));
gObject := AGTKObject;
if gObject = nil then Exit;
if Direct then begin
gObject := AGTKObject;
gFixed := AGTKObject;
gCore := AGTKObject;
end else begin
gObject := AGTKObject;
if gObject = nil then Exit;
// gFixed is the widget with the client area (e.g. TGroupBox, TForm have this)
gFixed := PGTKObject(GetFixedWidget(gObject));
if gFixed = nil then gFixed := gObject;
// gFixed is the widget with the client area (e.g. TGroupBox, TForm have this)
gFixed := PGTKObject(GetFixedWidget(gObject));
if gFixed = nil then gFixed := gObject;
// gCore is the main widget (e.g. TListView has this)
gCore:= PGtkObject(GetWidgetInfo(gObject, True)^.CoreWidget);
// gCore is the main widget (e.g. TListView has this)
gCore:= PGtkObject(GetWidgetInfo(gObject, True)^.CoreWidget);
end;
case AMsg of
LM_FOCUS :
@ -490,7 +497,6 @@ begin
ConnectKeyPressReleaseEvents(gCore);
end;
LM_SHOWWINDOW :
begin
ConnectSenderSignal(gObject, 'show', @gtk2showCB);
@ -498,7 +504,7 @@ begin
end;
else
Inherited SetCallback(AMsg, AGTKObject, ALCLObject);
Inherited SetCallbackEx(AMsg, AGTKObject, ALCLObject, Direct);
end;
end;

View File

@ -64,6 +64,8 @@ type
scrolled_window: PGtkwidget;
end;
{ TGtk2WSScrollBar }
TGtk2WSScrollBar = class(TGtkWSScrollBar)
@ -677,13 +679,15 @@ class procedure TGtk2WSCustomComboBox.ReCreateCombo(
const ACustomComboBox: TCustomComboBox; const AWithEntry: Boolean;
const AWidgetInfo: PWidgetInfo);
var
p: PGtkWidget;
ComboWidget: PGtkWidget;
Model: PGtkTreeModel;
Index: Integer;
Text: String;
Box: PGtkWidget;
begin
p := AWidgetInfo^.CoreWidget;
Model := gtk_combo_box_get_model(PGtkComboBox(p));
Box:=PGtkWidget(ACustomComboBox.Handle);
ComboWidget := AWidgetInfo^.CoreWidget;
Model := gtk_combo_box_get_model(PGtkComboBox(ComboWidget));
g_object_ref(G_OBJECT(Model));
// this should work but may not in all circumstances
@ -694,16 +698,16 @@ begin
end;
if Index = -1 then Index := GetItemIndex(ACustomComboBox);
gtk_widget_destroy(p);
gtk_widget_destroy(ComboWidget);
case AWithEntry of
True : p := gtk_combo_box_entry_new_with_model(Model, 0);
False: p := gtk_combo_box_new_with_model(Model);
True : ComboWidget := gtk_combo_box_entry_new_with_model(Model, 0);
False: ComboWidget := gtk_combo_box_new_with_model(Model);
end;
SetMainWidget(p, GTK_BIN(p)^.child);
SetMainWidget(Box, GTK_BIN(ComboWidget)^.child);
g_object_unref (G_OBJECT(Model));
AWidgetInfo^.CoreWidget := p;
gtk_object_set_data(Pointer(p), 'widgetinfo', AWidgetInfo);
AWidgetInfo^.CoreWidget := ComboWidget;
gtk_object_set_data(Pointer(ComboWidget), 'widgetinfo', AWidgetInfo);
SetItemIndex(ACustomComboBox, Index);
@ -712,13 +716,12 @@ begin
SetReadOnly(ACustomComboBox, ACustomComboBox.ReadOnly);
end;
SetRenderer(ACustomComboBox, p);
SetRenderer(ACustomComboBox, ComboWidget);
gtk_container_add(PGtkContainer(AWidgetInfo^.ClientWidget), p);
gtk_container_add(PGtkContainer(AWidgetInfo^.ClientWidget), ComboWidget);
gtk_widget_show_all(AWidgetInfo^.ClientWidget);
SetCallbacks(ACustomComboBox, p, AWidgetInfo);
SetCallbacks(ACustomComboBox, Box, AWidgetInfo);
end;
class procedure TGtk2WSCustomComboBox.SetRenderer(
@ -777,12 +780,15 @@ var
APrivate: PGtkComboBoxPrivate;
BtnPressID: guint;
HandlerID: guint;
ComboWidget: PGtkComboBox;
InputObject: PGtkObject;
begin
AGtkObject := PGtkObject(AWidget);
AChild := PGtkObject(PGtkBin(AWidget)^.child);
APrivate := PGtkComboBoxPrivate(PGtkComboBox(AWidget)^.priv);
ComboWidget:=PGtkComboBox(AWidgetInfo^.CoreWidget);
AGtkObject := PGtkObject(AWidget);
AChild := PGtkObject(PGtkBin(ComboWidget)^.child);// the entry
APrivate := PGtkComboBoxPrivate(ComboWidget^.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);
@ -790,36 +796,40 @@ begin
g_signal_handler_disconnect(AButton, HandlerID);
end;
g_signal_connect(AWidget, 'changed', TGCallback(@GtkChangedCB), AWidgetInfo);
g_signal_connect(ComboWidget, '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);
// First the combo (or the entry)
if gtk_is_combo_box_entry(ComboWidget) then begin
InputObject:=AChild;
end else begin
InputObject:=AGTKObject;
end;
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEMOVE, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_LBUTTONDOWN, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_LBUTTONUP, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_LBUTTONDBLCLK, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_RBUTTONDBLCLK, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONDBLCLK, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_RBUTTONDOWN, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_RBUTTONUP, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONDOWN, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONUP, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEWHEEL, InputObject, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_PAINT, InputObject, 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);
// And now the same for the Button in the combo
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEENTER, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSELEAVE, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEMOVE, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_LBUTTONDOWN, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_LBUTTONUP, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_LBUTTONUP, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_RBUTTONDOWN, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_RBUTTONUP, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONDOWN, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MBUTTONUP, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_MOUSEWHEEL, AButton, AWinControl);
Gtk2WidgetSet.SetCallbackDirect(LM_PAINT, AButton, AWinControl);
// if we are a GtkComboBoxEntry
if GtkWidgetIsA(PGtkWidget(AChild), GTK_TYPE_ENTRY) then begin
@ -1109,7 +1119,7 @@ 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
ComboWidget: PGtkWidget; // ptr to the newly created GtkWidget
ListStore : PGtkListStore;
WidgetInfo: PWidgetInfo;
@ -1121,28 +1131,28 @@ begin
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);
csDropDown, csSimple: ComboWidget := 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));
csOwnerDrawVariable : ComboWidget := 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_container_add(PGtkContainer(Box), ComboWidget);
gtk_widget_show_all(Box);
SetRenderer(TCustomComboBox(AWinControl), p);
SetRenderer(TCustomComboBox(AWinControl), ComboWidget);
SetMainWidget(Box, p);
WidgetInfo^.CoreWidget := p;
WidgetInfo^.ClientWidget := Box;
SetMainWidget(Box, ComboWidget);
SetMainWidget(Box, GTK_BIN(ComboWidget)^.child);
WidgetInfo^.CoreWidget := ComboWidget;
//WidgetInfo^.ClientWidget := Box;
//gtk_widget_add_events(Box, GDK_ALL_EVENTS_MASK);
SetCallbacks(AWinControl, p, WidgetInfo);
SetCallbacks(AWinControl, Box, WidgetInfo);
Result := TLCLIntfHandle(Box);
end;