* cursor patch from Paul Ishenin

+ added extra handle checks
* enabled some gtk2.2 code for getting cursorpos

git-svn-id: trunk@10597 -
This commit is contained in:
marc 2007-02-06 01:34:29 +00:00
parent 6bd2881a7f
commit 6737a6ef3d
19 changed files with 145 additions and 139 deletions

View File

@ -5278,6 +5278,11 @@ begin
TWSWinControlClass(WidgetSetClass).SetText(Self, CachedText);
InvalidatePreferredSize;
end;
if csDesigning in ComponentState
then TWSWinControlClass(WidgetSetClass).SetCursor(Self, Screen.Cursors[crDefault])
else TWSWinControlClass(WidgetSetClass).SetCursor(Self, Screen.Cursors[Cursor]);
// send pending resize event
Resize;

View File

@ -97,10 +97,10 @@ Procedure gdk_pixbuf_render_pixmap_and_mask(pixbuf: PGdkPixbuf;
//Wrapper around window functions like gtk2 -->
Function gdk_drawable_get_depth(Drawable: PGDKDrawable): gint;
Procedure gdk_drawable_get_size(Drawable: PGDKDrawable; Width, Height: PGInt);
Function gdk_drawable_get_image(Drawable: PGDKDrawable;
procedure gdk_drawable_get_size(Drawable: PGDKDrawable; Width, Height: PGInt);
function gdk_drawable_get_image(Drawable: PGDKDrawable;
x, y, width, height: gint): PGdkImage;
Function gdk_drawable_get_colormap(Drawable: PGDKDrawable): PGdkColormap;
function gdk_drawable_get_colormap(Drawable: PGDKDrawable): PGdkColormap;
function GTK_TYPE_WIDGET : TGTKType; cdecl; external gtkdll name 'gtk_widget_get_type';

View File

@ -32,6 +32,7 @@ interface
uses
// libs
Gtk, Glib, Gdk,
// LCL
LCLType, LMessages, LCLProc, Controls, Classes, SysUtils, Forms,
// widgetset
@ -101,6 +102,7 @@ type
end;
implementation
// {$I Gtk1PrivateWidget.inc}
end.

View File

@ -245,7 +245,7 @@ begin
if TheWinControl<>nil then
begin
TheWinControl.CNPreferredSizeChanged;
SetCursor(TheWinControl, Screen.Cursors[TheWinControl.Cursor]);
TGtkPrivateWidgetClass(TheWinControl.WidgetSetClass.WSPrivate).UpdateCursor(WinWidgetInfo);
ConnectInternalWidgetsSignals(MainWidget,TheWinControl);
if TheWinControl is TCustomPage then

View File

@ -244,6 +244,7 @@ type
ExStyle: Integer;
EventMask: TGdkEventMask;
DoubleBuffer: PGdkPixmap;
ControlCursor: HCursor; // cursor, that control contain
Flags: TWidgetInfoFlags;
ChangeLock: Integer; // lock events
DataOwner: Boolean; // Set if the UserData should be freed when the info is freed

View File

@ -40,7 +40,7 @@ interface
{$endif}
{$ifdef gtk2}
{$I ../gtk2/gtk2extrah.inc}
{$I gtk2extrah.inc}
{$endif}
@ -51,7 +51,7 @@ implementation
{$endif}
{$ifdef gtk2}
{$I ../gtk2/gtk2extra.inc}
{$I gtk2extra.inc}
{$endif}
end.

View File

@ -3526,10 +3526,18 @@ begin
end;
procedure TGtkWidgetSet.SetDesigning(AComponent: TComponent);
{var
AWinControl: TWinControl absolute AComponent;
}
begin
// change cursor
//if AComponent is TWinControl then
// gtkproc.SetCursor(TWinControl(AComponent), Screen.Cursors[TWinControl(AComponent).Cursor]);
{
Paul Ishenin:
this will never happen
if (AComponent is TWinControl) and (AWinControl.HandleAllocated) then
TGtkWSWinControl(AWinControl.WidgetSetClass).SetCursor(AWinControl, Screen.Cursors[crDefault]);
}
end;
{------------------------------------------------------------------------------

View File

@ -144,6 +144,8 @@ type
public
end;
function GetWidgetWithWindow(const AHandle: THandle): PGtkWidget;
procedure SetWindowCursor(AWindow: PGdkWindow; ACursor: HCursor; ARecursive: Boolean);
implementation
@ -164,6 +166,43 @@ begin
end;
end;
{------------------------------------------------------------------------------
procedure: SetWindowCursor
Params: AWindow : PGDkWindow, ACursor: HCursor, ARecursive: Boolean
Returns: Nothing
Sets the cursor for a window (or recursively for window with childs)
------------------------------------------------------------------------------}
procedure SetWindowCursor(AWindow: PGdkWindow; ACursor: HCursor; ARecursive: Boolean);
var
Cursor: PGdkCursor;
procedure SetCursorRecursive(AWindow: PGdkWindow);
var
ChildWindows, ListEntry: PGList;
begin
gdk_window_set_cursor(AWindow, Cursor);
ChildWindows := gdk_window_get_children(AWindow);
ListEntry := ChildWindows;
while ListEntry <> nil do
begin
SetCursorRecursive(PGdkWindow(ListEntry^.Data));
ListEntry := ListEntry^.Next;
end;
g_list_free(ChildWindows);
end;
begin
Cursor := PGdkCursor(ACursor);
if Cursor = nil then Exit;
if ARecursive
then SetCursorRecursive(AWindow)
else gdk_window_set_cursor(AWindow, Cursor);
end;
{ TGtkPrivateScrolling }
{ temp class to keep things working }

View File

@ -18,9 +18,15 @@
{ TGtkPrivateWidget }
class procedure TGtkPrivateWidget.UpdateCursor(AInfo: PWidgetInfo);
var
Widget, FixWidget: PGtkWidget;
Window: PGdkWindow;
begin
//move code from gtkproc.inc here
Widget := AInfo^.CoreWidget;
FixWidget := GetFixedWidget(Widget);
Window := GetControlWindow(FixWidget);
if Window = nil then Exit;
SetWindowCursor(Window, AInfo^.ControlCursor, False);
end;
class procedure TGtkPrivateWidget.SetZPosition(const AWinControl: TWinControl; const APosition: TWSZPosition);

View File

@ -4631,58 +4631,6 @@ begin
ReleaseMouseCapture;
end;
{------------------------------------------------------------------------------
procedure: SetCursor
Params: AWinControl : TWinControl
Returns: Nothing
Sets the cursor for a widget.
------------------------------------------------------------------------------}
procedure SetCursor(AWinControl : TWinControl; ACursor: HCursor);
procedure DoSetCursor(AWindow: PGdkWindow; Cursor: pGDKCursor);
begin
if Cursor <> nil then begin
gdk_window_set_cursor(AWindow, Cursor);
end;
end;
procedure SetCursorRecursive(AWindow: PGdkWindow; Cursor: PGdkCursor);
var
ChildWindows, ListEntry: PGList;
begin
DoSetCursor(AWindow, Cursor);
ChildWindows:=gdk_window_get_children(AWindow);
ListEntry:=ChildWindows;
while ListEntry<>nil do begin
SetCursorRecursive(PGdkWindow(ListEntry^.Data), Cursor);
ListEntry:=ListEntry^.Next;
end;
g_list_free(ChildWindows);
end;
var
AWidget, FixWidget: PGtkWidget;
AWindow: PGdkWindow;
NewCursor: PGdkCursor;
begin
if not ((AWinControl is TWinControl) and AWinControl.HandleAllocated)
then exit;
AWidget:= PGtkWidget(AWinControl.Handle);
FixWidget:= GetFixedWidget(AWidget);
AWindow:= GetControlWindow(FixWidget);
if AWindow = nil then exit;
NewCursor := PGdkCursor(ACursor);
if NewCursor = nil then Exit;
SetCursorRecursive(AWindow, NewCursor);
end;
{-------------------------------------------------------------------------------
procedure: SignalConnect
Params: AWidget: PGTKWidget

View File

@ -490,8 +490,6 @@ procedure ReleaseMouseCapture;
procedure ReleaseCaptureWidget(Widget : PGtkWidget);
procedure UpdateMouseCaptureControl;
// mouse cursor
procedure SetCursor(AWinControl: TWinControl; ACursor: HCursor);
const
// for now return the same value, in the future we may want to return an
@ -786,7 +784,7 @@ implementation
uses
{$IFDEF StaticXinerama} Xinerama, {$ENDIF}
dynlibs;
dynlibs, GtkPrivate;
const
KCINFO_FLAG_SHIFT = $01;

View File

@ -1323,8 +1323,6 @@ function TGtkWidgetSet.CreateCursor(ACursorInfo: PIconInfo): hCursor;
gdk_image_unref(MaskImage);
end;
var
FG, BG: TGDKColor;
Img, Msk: PGdkPixmap;
@ -1337,8 +1335,9 @@ begin
Img := PGDIObject(ACursorInfo^.hbmColor)^.GDIBitmapObject;
Msk := PGDIObject(ACursorInfo^.hbmColor)^.GDIBitmapMaskObject;
gdk_drawable_get_size(Img, @W, @H);
bitlen := (W * H) shr 3;
SetLength(ImgBits, bitlen);
SetLength(MskBits, bitlen);
@ -1363,7 +1362,6 @@ begin
bg.blue := 0;
bg.pixel := 0;
// TODO: for gtk2, use gdk_cursor_new_from_pixbuf for colored cursors
Result := hCursor(gdk_cursor_new_from_pixmap (srcbitmap, mskbitmap, @fg, @bg,
ACursorInfo^.xHotspot, ACursorInfo^.yHotspot));

View File

@ -29,9 +29,9 @@ interface
uses
// libs
{$IFDEF GTK2}
GLib2, Gtk2,
GLib2, Gtk2, Gtk2Private,
{$ELSE}
GLib, Gtk,
GLib, Gtk, Gtk1Private,
{$ENDIF}
// LCL
Classes, LCLProc, LCLType, LMessages, Controls, Graphics, Buttons,
@ -582,9 +582,14 @@ initialization
////////////////////////////////////////////////////
// To improve speed, register only classes
// which actually implement something
////////////////////////////////////////////////////
RegisterWSComponent(TCustomButton, TGtkWSButton);
RegisterWSComponent(TCustomBitBtn, TGtkWSBitBtn); // register it to fallback to default
////////////////////////////////////////////////////
{$ifdef gtk1}
RegisterWSComponent(TCustomButton, TGtkWSButton, TGtk1PrivateButton);
RegisterWSComponent(TCustomBitBtn, TGtkWSBitBtn, TGtk1PrivateButton); // register it to fallback to default
{$else}
RegisterWSComponent(TCustomButton, TGtkWSButton, TGtk2PrivateButton);
RegisterWSComponent(TCustomBitBtn, TGtkWSBitBtn, TGtk2PrivateButton); // register it to fallback to default
{$endif}
// RegisterWSComponent(TCustomSpeedButton, TGtkWSSpeedButton);
////////////////////////////////////////////////////
end.

View File

@ -228,6 +228,10 @@ var
CS: PChar;
Handle: HWND;
begin
Result := False;
if not WSCheckHandleAllocated(AWinControl, 'GetText')
then Exit;
Result := true;
Handle := AWinControl.Handle;
case AWinControl.fCompStyle of
@ -252,6 +256,9 @@ end;
class procedure TGtkWSWinControl.Invalidate(const AWinControl: TWinControl);
begin
if not WSCheckHandleAllocated(AWinControl, 'Invalidate')
then Exit;
Assert(false, 'Trace:Trying to invalidate window... !!!');
//THIS DOESN'T WORK YET....
{
@ -276,6 +283,9 @@ end;
class procedure TGtkWSWinControl.SetBounds(const AWinControl: TWinControl; const ALeft, ATop, AWidth, AHeight: Integer);
begin
if not WSCheckHandleAllocated(AWinControl, 'SetBounds')
then Exit;
TGtkWidgetSet(WidgetSet).SetResizeRequest(PGtkWidget(AWinControl.Handle));
end;
@ -285,6 +295,9 @@ var
Widget: PGtkWidget;
APIWidget: PGTKAPIWidget;
begin
if not WSCheckHandleAllocated(AWinControl, 'SetBorderStyle')
then Exit;
Widget := PGtkWidget(AWinControl.Handle);
if GtkWidgetIsA(Widget,GTKAPIWidget_GetType) then begin
//DebugLn('TGtkWSWinControl.SetBorderStyle ',AWinControl.Name,':',AWinControl.ClassName,' ',ord(ABorderStyle));
@ -352,12 +365,17 @@ begin
end;
end;
class procedure TGtkWSWinControl.SetCursor(const AWinControl: TWinControl;
const ACursor: HCursor);
class procedure TGtkWSWinControl.SetCursor(const AWinControl: TWinControl; const ACursor: HCursor);
var
WidgetInfo: PWidgetInfo;
begin
//DebugLn(['TGtkWSWinControl.SetCursor ',DbgSName(AWinControl)]);
if (not AWinControl.HandleAllocated) then exit;
GtkProc.SetCursor(AWinControl, ACursor);
if not WSCheckHandleAllocated(AWinControl, 'SetCursor')
then Exit;
WidgetInfo := GetWidgetInfo(Pointer(AWinControl.Handle));
if WidgetInfo^.ControlCursor = ACursor then Exit;
WidgetInfo^.ControlCursor := ACursor;
TGtkPrivateWidgetClass(AWinControl.WidgetSetClass.WSPrivate).UpdateCursor(WidgetInfo);
end;
class procedure TGtkWSWinControl.SetFont(const AWinControl: TWinControl;
@ -365,7 +383,9 @@ class procedure TGtkWSWinControl.SetFont(const AWinControl: TWinControl;
var
Widget: PGtkWidget;
begin
if not AWinControl.HandleAllocated then exit;
if not WSCheckHandleAllocated(AWinControl, 'SetFont')
then Exit;
Widget:=pGtkWidget(AWinControl.handle);
if GtkWidgetIsA(Widget,GTKAPIWidget_GetType) then
exit;
@ -385,6 +405,9 @@ var
Widget: PGtkWidget;
Allocation: TGTKAllocation;
begin
if not WSCheckHandleAllocated(AWinControl, 'SetPos')
then Exit;
Widget := PGtkWidget(AWinControl.Handle);
Allocation.X := gint16(ALeft);
Allocation.Y := gint16(ATop);
@ -399,7 +422,9 @@ var
Widget: PGtkWidget;
Allocation: TGTKAllocation;
begin
if not AWinControl.HandleAllocated then exit;
if not WSCheckHandleAllocated(AWinControl, 'SetSize')
then Exit;
Widget := PGtkWidget(AWinControl.Handle);
Allocation.X := Widget^.Allocation.X;
Allocation.Y := Widget^.Allocation.Y;
@ -410,7 +435,9 @@ end;
class procedure TGtkWSWinControl.SetColor(const AWinControl: TWinControl);
begin
if not AWinControl.HandleAllocated then exit;
if not WSCheckHandleAllocated(AWinControl, 'SetColor')
then Exit;
if ((csOpaque in AWinControl.ControlStyle)
and GtkWidgetIsA(pGtkWidget(AWinControl.handle),GTKAPIWidget_GetType)) then
exit;
@ -467,7 +494,9 @@ var
aLabel, pLabel: pchar;
AccelKey : integer;
begin
if not AWinControl.HandleAllocated then exit;
if not WSCheckHandleAllocated(AWinControl, 'SetText')
then Exit;
//TODO: create classprocedures for this in the corresponding classes
P := Pointer(AWinControl.Handle);

View File

@ -50,5 +50,15 @@ function gdk_screen_get_default: PGdkScreen; cdecl; external gdklib;
procedure laz_gdk_gc_set_dashes(gc:PGdkGC; dash_offset:gint;
dashlist:Pgint8; n:gint); cdecl; external gdkdll name 'gdk_gc_set_dashes';
// gtk 2.2
procedure gdk_display_get_pointer(display : PGdkDisplay; screen :PGdkScreen; x :Pgint; y : Pgint; mask : PGdkModifierType); cdecl; external gdklib;
function gdk_display_get_default:PGdkDisplay; cdecl; external gdklib;
procedure gdk_draw_pixbuf(drawable : PGdkDrawable; gc : PGdkGC; pixbuf : PGdkPixbuf; src_x, src_y, dest_x, dest_y, width, height : gint;
dither : TGdkRgbDither; x_dither, y_dither : gint); cdecl; external gdklib;
// gtk 2.4
function gdk_cursor_new_from_pixbuf(display: PGdkDisplay; pixbuf: PGdkPixbuf; x, y: gint): PGdkCursor; cdecl; external gdklib name 'gdk_cursor_new_from_pixbuf';

View File

@ -46,7 +46,7 @@ uses
GTKWinApiWindow, StdCtrls, ComCtrls,
Dialogs, ExtDlgs, LResources, Math, GTKGlobals,
{Buttons, CListBox, Calendar, Arrow, Spin, FileCtrl, CommCtrl, ExtCtrls, }
gtkDef, gtkFontCache, gtkInt;
gtkDef, gtkFontCache, gtkInt, GtkExtra;
type
@ -119,19 +119,6 @@ type
property Owner: TWinControl read FOwner;
end;
{$IfDef GTK2_2}
procedure gdk_display_get_pointer(display : PGdkDisplay; screen :PGdkScreen; x :Pgint; y : Pgint; mask : PGdkModifierType); cdecl; external gdklib;
function gdk_display_get_default:PGdkDisplay; cdecl; external gdklib;
procedure gdk_draw_pixbuf(drawable : PGdkDrawable; gc : PGdkGC; pixbuf : PGdkPixbuf; src_x, src_y, dest_x, dest_y, width, height : gint;
dither : TGdkRgbDither; x_dither, y_dither : gint); cdecl; external gdklib;
{$Else}
{$IfNDef Win32}
Function gdk_x11_drawable_get_xdisplay(drawable : PGdkDrawable) : PDisplay; cdecl; external gdklib;
Function gdk_x11_drawable_get_xid(drawable : PGdkDrawable) : Integer; cdecl; external gdklib;
{$EndIf}
{$EndIf}
var
GTK2WidgetSet: TGTK2WidgetSet absolute GtkWidgetSet;

View File

@ -32,6 +32,7 @@ interface
uses
// libs
Gtk2, Glib2, Gdk2,
// LCL
LCLType, LMessages, LCLProc, Controls, Classes, SysUtils, Forms,
// widgetset
@ -102,6 +103,6 @@ type
end;
implementation
{$I Gtk2PrivateWidget.inc}
end.

View File

@ -1,4 +1,4 @@
{%mainunit gtkprivate.pp}
{%mainunit gtk2private.pp}
{
*****************************************************************************
@ -16,7 +16,13 @@
}
class procedure TGtk2PrivateWidget.UpdateCursor(AInfo: PWidgetInfo);
class procedure TGtk2PrivateButton.UpdateCursor(AInfo: PWidgetInfo);
var
Widget: PGtkWidget;
Window: PGdkWindow;
begin
//specific button code here
end;
Widget := AInfo^.CoreWidget;
Window := PGTkButton(Widget)^.event_window;
if Window = nil then Exit;
SetWindowCursor(Window, AInfo^.ControlCursor, False);
end;

View File

@ -410,46 +410,9 @@ end;
------------------------------------------------------------------------------}
function TGtk2WidgetSet.GetCursorPos(var lpPoint: TPoint ): Boolean;
{$IfnDef GTK2_2} //we need a GTK2_2 FLAG somehow
{$IfNDef Win32}
var
root, child: TWindow;
winx, winy: Integer;
xmask: Cardinal;
TopList, List: PGList;
{$EndIf}
{$EndIf}
begin
Result := False;
{$IfDef GTK2_2} //we need a GTK2_2 FLAG somehow
gdk_display_get_pointer(gdk_display_get_default(), nil, @lpPoint.X, @lpPoint.Y, nil);
Result := True;
{$Else}
{$IfNDef Win32}
TopList := gdk_window_get_toplevels;
List := TopList;
while List <> nil do
begin
if (List^.Data <> nil)
and gdk_window_is_visible(List^.Data)
then begin
XQueryPointer(gdk_x11_drawable_get_xdisplay (List^.Data),
gdk_x11_drawable_get_xid(List^.Data),
@root, @child, @lpPoint.X, @lpPoint.Y, @winx, @winy, @xmask);
Result := True;
Break;
end;
List := g_list_next(List);
end;
if TopList <> nil
then g_list_free(TopList);
{$Else}
// Win32 Todo
DebugLn('ToDo(Win32): TGtk2WidgetSet.GetCursorPos');
{$EndIf}
{$EndIf}
end;
{------------------------------------------------------------------------------