LCL-GTK3: Fix Splitter and its related code. Issue #34106

git-svn-id: branches/fixes_2_0@59366 -
This commit is contained in:
mattias 2018-10-27 09:44:01 +00:00
parent 4ae5a2c2ad
commit 04ac9df67c
8 changed files with 218 additions and 61 deletions

1
.gitattributes vendored
View File

@ -9466,6 +9466,7 @@ lcl/interfaces/gtk3/gtk3wsforms.pp svneol=native#text/plain
lcl/interfaces/gtk3/gtk3wsimglist.pp svneol=native#text/plain lcl/interfaces/gtk3/gtk3wsimglist.pp svneol=native#text/plain
lcl/interfaces/gtk3/gtk3wsmenus.pp svneol=native#text/plain lcl/interfaces/gtk3/gtk3wsmenus.pp svneol=native#text/plain
lcl/interfaces/gtk3/gtk3wsspin.pp svneol=native#text/plain lcl/interfaces/gtk3/gtk3wsspin.pp svneol=native#text/plain
lcl/interfaces/gtk3/gtk3wssplitter.pas svneol=native#text/pascal
lcl/interfaces/gtk3/gtk3wsstdctrls.pp svneol=native#text/plain lcl/interfaces/gtk3/gtk3wsstdctrls.pp svneol=native#text/plain
lcl/interfaces/gtk3/interfaces.pp svneol=native#text/plain lcl/interfaces/gtk3/interfaces.pp svneol=native#text/plain
lcl/interfaces/gtk3/issues.xml svneol=native#text/plain lcl/interfaces/gtk3/issues.xml svneol=native#text/plain

View File

@ -283,8 +283,8 @@ type
TGtkOrientation = Integer; TGtkOrientation = Integer;
const const
{ GtkOrientation } { GtkOrientation }
GTK_ORIENTATION_HORIZONTAL: TGtkOrientation = 0; GTK_ORIENTATION_HORIZONTAL = TGtkOrientation(0);
GTK_ORIENTATION_VERTICAL: TGtkOrientation = 1; GTK_ORIENTATION_VERTICAL = TGtkOrientation(1);
type type
TGtkDestDefaults = Integer; TGtkDestDefaults = Integer;

View File

@ -29,45 +29,22 @@ begin
if dy < 0 then if dy < 0 then
dy := 0; dy := 0;
(*
// rubber band is just a window without a title // rubber band is just a window without a title
Result := {%H-}HWND(gtk_window_new(GTK_WINDOW_POPUP)); Result := {%H-}HWND(gtk_window_new(GTK_WINDOW_TOPLEVEL));
gtk_window_set_default_size({%H-}PGtkWindow(Result), dx, dy); gtk_window_set_default_size({%H-}PGtkWindow(Result), dx, dy);
gtk_widget_set_uposition(Widget, ARect.Left, ARect.Top);
gtk_widget_set_app_paintable(Widget, True);
gtk_widget_realize(Widget); gtk_widget_realize(Widget);
gdk_window_set_decorations(Widget^.window, 0); gdk_window_set_decorations(Widget^.window, 0);
gdk_window_set_functions(Widget^.window, GDK_FUNC_RESIZE or GDK_FUNC_CLOSE); gdk_window_set_functions(Widget^.window, GDK_FUNC_RESIZE or GDK_FUNC_CLOSE);
gtk_window_set_opacity({%H-}PGtkWindow(Result), 0.25); gtk_widget_set_opacity(Widget, 0.25);
if ABrush = 0 then
SetWidgetColor(Widget, clNone, clGradientActiveCaption, [GTK_STATE_NORMAL])
else
if {%H-}PGDIObject(ABrush)^.GDIBrushFill = GDK_SOLID then
SetWidgetColor(Widget, clNone, {%H-}PGDIObject(ABrush)^.GDIBrushColor.ColorRef, [GTK_STATE_NORMAL])
else
begin
Pixmap := gdk_pixmap_new(Widget^.window, dx, dy, -1);
gc := gdk_gc_new(Pixmap);
AColor := AllocGDKColor(clWhite);
gdk_gc_set_foreground(gc, @AColor);
gdk_gc_set_fill(gc, {%H-}PGDIObject(ABrush)^.GDIBrushFill);
case {%H-}PGDIObject(ABrush)^.GDIBrushFill of
GDK_TILED: gdk_gc_set_tile(gc, {%H-}PGDIObject(ABrush)^.GDIBrushPixMap);
GDK_STIPPLED: gdk_gc_set_stipple(gc, {%H-}PGDIObject(ABrush)^.GDIBrushPixMap);
end;
gdk_draw_rectangle(Pixmap, gc, -1, 0, 0, dx, dy);
gdk_gc_unref(gc);
gdk_window_set_back_pixmap(Widget^.window, Pixmap, False);
g_object_unref(Pixmap);
end;
gtk_widget_show(Widget); gtk_widget_show(Widget);
*)
end; end;
procedure TGtk3WidgetSet.DestroyRubberBand(ARubberBand: HWND); procedure TGtk3WidgetSet.DestroyRubberBand(ARubberBand: HWND);
begin begin
// TODO: gtk_widget_destroy({%H-}PGtkWidget(ARubberBand)); gtk_widget_destroy({%H-}PGtkWidget(ARubberBand));
end; end;
procedure TGtk3WidgetSet.DrawDefaultDockImage(AOldRect, ANewRect: TRect; procedure TGtk3WidgetSet.DrawDefaultDockImage(AOldRect, ANewRect: TRect;

View File

@ -25,7 +25,7 @@ uses
Classes, SysUtils, types, math, Classes, SysUtils, types, math,
// LCL // LCL
Controls, StdCtrls, ExtCtrls, ComCtrls, Graphics, Dialogs, Forms, Menus, ExtDlgs, Controls, StdCtrls, ExtCtrls, ComCtrls, Graphics, Dialogs, Forms, Menus, ExtDlgs,
Spin, CheckLst, LCLType, LCLProc, LMessages, LCLMessageGlue, LCLIntf, Spin, CheckLst, PairSplitter, LCLType, LCLProc, LMessages, LCLMessageGlue, LCLIntf,
// GTK3 // GTK3
LazGtk3, LazGdk3, LazGObject2, LazGLib2, LazCairo1, LazPango1, LazGdkPixbuf2, LazGtk3, LazGdk3, LazGObject2, LazGLib2, LazCairo1, LazPango1, LazGdkPixbuf2,
gtk3objects, gtk3procs, gtk3private, Gtk3CellRenderer; gtk3objects, gtk3procs, gtk3private, Gtk3CellRenderer;
@ -383,6 +383,22 @@ type
end; end;
{ TGtk3Paned }
TGtk3Paned = class(TGtk3Container)
protected
function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
end;
{ TGtk3SplitterSide }
TGtk3SplitterSide = class(TGtk3Container)
protected
function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
end;
{ TGtk3MenuShell } { TGtk3MenuShell }
TGtk3MenuShell = class(TGtk3Container) TGtk3MenuShell = class(TGtk3Container)
@ -711,6 +727,13 @@ type
function CreateWidget(const Params: TCreateParams):PGtkWidget; override; function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
end; end;
{ TGtk3Splitter }
TGtk3Splitter = class(TGtk3Panel)
public
end;
{ TGtk3Window } { TGtk3Window }
TGtk3Window = class(TGtk3ScrollableWin) {we are TGtk3Bin actually, but it won't hurt since we need scroll} TGtk3Window = class(TGtk3ScrollableWin) {we are TGtk3Bin actually, but it won't hurt since we need scroll}
@ -1591,6 +1614,25 @@ begin
// DebugLn('Gtk3ScrollEvent for ', dbgsName(TGtk3Widget(AData).LCLObject),' Result ',dbgs(Result)); // DebugLn('Gtk3ScrollEvent for ', dbgsName(TGtk3Widget(AData).LCLObject),' Result ',dbgs(Result));
end; end;
{ TGtk3SplitterSide }
function TGtk3SplitterSide.CreateWidget(const Params: TCreateParams): PGtkWidget;
begin
Result:=TGtkScrolledWindow.new(nil, nil);
end;
{ TGtk3Paned }
function TGtk3Paned.CreateWidget(const Params: TCreateParams): PGtkWidget;
const
ornt:array[TPairSplitterType] of TGtkOrientation=(
GTK_ORIENTATION_HORIZONTAL,
GTK_ORIENTATION_VERTICAL
);
begin
Result:=TGtkPaned.new(ornt[TPairSplitter(Self.LCLObject).SplitterType]);
end;
{ TGtk3Widget } { TGtk3Widget }
function TGtk3Widget.GtkEventMouseEnterLeave(Sender: PGtkWidget; Event: PGdkEvent): Boolean; function TGtk3Widget.GtkEventMouseEnterLeave(Sender: PGtkWidget; Event: PGdkEvent): Boolean;
@ -1598,23 +1640,22 @@ function TGtk3Widget.GtkEventMouseEnterLeave(Sender: PGtkWidget; Event: PGdkEven
var var
Msg: TLMessage; Msg: TLMessage;
// MouseMsg: TLMMouseMove absolute Msg; // MouseMsg: TLMMouseMove absolute Msg;
{$IFDEF GTK3DEBUGCORE}
MousePos: TPoint; MousePos: TPoint;
{$ENDIF}
begin begin
Result := False; Result := False;
FillChar(Msg, SizeOf(Msg), #0); FillChar(Msg, SizeOf(Msg), #0);
if Event^.type_ = GDK_ENTER_NOTIFY then if Event^.type_ = GDK_ENTER_NOTIFY then
begin Msg.Msg := LM_MOUSEENTER
Msg.Msg := LM_MOUSEENTER; else
end else
begin
Msg.Msg := LM_MOUSELEAVE; Msg.Msg := LM_MOUSELEAVE;
end;
MousePos.X := Round(Event^.crossing.x);
MousePos.Y := Round(Event^.crossing.y);
NotifyApplicationUserInput(LCLObject, Msg.Msg); NotifyApplicationUserInput(LCLObject, Msg.Msg);
Result := DeliverMessage(Msg, True) <> 0; Result := DeliverMessage(Msg, True) <> 0;
{$IFDEF GTK3DEBUGCORE} {$IFDEF GTK3DEBUGCORE}
MousePos.X := Round(Event^.crossing.x);
MousePos.Y := Round(Event^.crossing.y);
DebugLn('GtkEventMouseEnterLeave: mousePos ',dbgs(MousePos),' Object ',dbgsName(LCLObject), DebugLn('GtkEventMouseEnterLeave: mousePos ',dbgs(MousePos),' Object ',dbgsName(LCLObject),
' IsEnter ',dbgs(Event^.type_ = GDK_ENTER_NOTIFY),' Result=',dbgs(Result)); ' IsEnter ',dbgs(Event^.type_ = GDK_ENTER_NOTIFY),' Result=',dbgs(Result));
{$ENDIF} {$ENDIF}
@ -3881,10 +3922,7 @@ begin
AToolBar := TToolBar(LCLObject); AToolBar := TToolBar(LCLObject);
FHasPaint := False; FHasPaint := False;
FWidgetType := [wtWidget, wtContainer]; FWidgetType := [wtWidget, wtContainer];
Result := PGtkWidget(TGtkHBox.new(GTK_ORIENTATION_HORIZONTAL, 0)); Result:=PGtkWidget(TGtkToolbar.new);
FCentralWidget := PGtkWidget(TGtkFixed.new);
PGtkHBox(Result)^.add(FCentralWidget);
PGtkFixed(FCentralWidget)^.set_has_window(True);
end; end;
{ TGtk3Page } { TGtk3Page }
@ -6457,7 +6495,7 @@ end;
function TGtk3Window.GetTitle: String; function TGtk3Window.GetTitle: String;
begin begin
Result := ''; Result:=PGtkWindow(FWidget)^.get_title();
end; end;
procedure TGtk3Window.SetIcon(AValue: PGdkPixBuf); procedure TGtk3Window.SetIcon(AValue: PGdkPixBuf);
@ -6561,9 +6599,15 @@ begin
FHasPaint := True; FHasPaint := True;
AForm := TCustomForm(LCLObject); AForm := TCustomForm(LCLObject);
FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtWindow]; if not Assigned(LCLObject.Parent) then
begin
Result := TGtkWindow.new(GTK_WINDOW_TOPLEVEL); Result := TGtkWindow.new(GTK_WINDOW_TOPLEVEL);
FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtWindow];
end else
begin
Result := PGtkScrolledWindow(TGtkScrolledWindow.new(nil, nil));
FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtCustomControl]
end;
FBox := TGtkVBox.new(GTK_ORIENTATION_VERTICAL, 0); FBox := TGtkVBox.new(GTK_ORIENTATION_VERTICAL, 0);

View File

@ -3677,10 +3677,8 @@ end;
function TGtk3WidgetSet.SetParent(hWndChild: HWND; hWndParent: HWND): HWND; function TGtk3WidgetSet.SetParent(hWndChild: HWND; hWndParent: HWND): HWND;
begin begin
{$IFDEF GTK3DEBUGNOTIMPLEMENTED} Result := HWND(TGtk3Widget(hWndChild).getParent);
DebugLn('WARNING: TGtk3WidgetSet.SetParent not implemented ...'); TGtk3Widget(hWndChild).SetParent(TGtk3Widget(hWndParent),0,0)
{$ENDIF}
Result:=inherited SetParent(hWndChild, hWndParent);
end; end;
function TGtk3WidgetSet.SetProp(Handle: hwnd; Str: PChar; Data: Pointer function TGtk3WidgetSet.SetProp(Handle: hwnd; Str: PChar; Data: Pointer

View File

@ -50,6 +50,8 @@ type
TGtk3WSCustomSplitter = class(TWSCustomSplitter) TGtk3WSCustomSplitter = class(TWSCustomSplitter)
published published
class function CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): TLCLIntfHandle; override;
end; end;
{ TGtk3WSSplitter } { TGtk3WSSplitter }
@ -146,6 +148,17 @@ implementation
uses uses
gtk3widgets; gtk3widgets;
{ TGtk3WSCustomSplitter }
class function TGtk3WSCustomSplitter.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
var
ASplitter: TGtk3Splitter;
begin
ASplitter := TGtk3Splitter.Create(AWinControl, AParams);
Result := TLCLIntfHandle(ASplitter);
end;
{ TGtk3WSCustomPanel } { TGtk3WSCustomPanel }
class function TGtk3WSCustomPanel.CreateHandle(const AWinControl: TWinControl; class function TGtk3WSCustomPanel.CreateHandle(const AWinControl: TWinControl;

View File

@ -21,7 +21,7 @@ interface
uses uses
Classes, Controls, ComCtrls, Calendar, StdCtrls, Arrow, Spin, Classes, Controls, ComCtrls, Calendar, StdCtrls, Arrow, Spin,
Dialogs, ExtCtrls, ExtDlgs, Buttons, CheckLst, Forms, Grids, Menus, Dialogs, ExtCtrls, ExtDlgs, Buttons, CheckLst, Forms, Grids, Menus,
PairSplitter, ImgList, WSLCLClasses; ImgList, PairSplitter, WSLCLClasses;
// imglist // imglist
@ -137,7 +137,7 @@ uses
uses uses
Gtk3WSImgList, Gtk3WSControls, Gtk3WSForms, Gtk3WSButtons, Gtk3WSStdCtrls, Gtk3WSImgList, Gtk3WSControls, Gtk3WSForms, Gtk3WSButtons, Gtk3WSStdCtrls,
Gtk3WSComCtrls, Gtk3WSExtCtrls, Gtk3WSSpin, Gtk3WSMenus, Gtk3WSCalendar, Gtk3WSComCtrls, Gtk3WSExtCtrls, Gtk3WSSpin, Gtk3WSMenus, Gtk3WSCalendar,
Gtk3WSDialogs, Gtk3WSCheckLst, Gtk3WSExtDlgs; Gtk3WSDialogs, Gtk3WSCheckLst, Gtk3WSExtDlgs, gtk3wssplitter;
// imglist // imglist
function RegisterCustomImageListResolution: Boolean; alias : 'WSRegisterCustomImageListResolution'; function RegisterCustomImageListResolution: Boolean; alias : 'WSRegisterCustomImageListResolution';
@ -402,9 +402,8 @@ end;
function RegisterCustomSplitter: Boolean; alias : 'WSRegisterCustomSplitter'; function RegisterCustomSplitter: Boolean; alias : 'WSRegisterCustomSplitter';
begin begin
// RegisterWSComponent(TCustomSplitter, TGtk2WSCustomSplitter); RegisterWSComponent(TCustomSplitter, TGtk3WSCustomSplitter);
// RegisterWSComponent(TSplitter, TGtk2WSSplitter); Result := true;
Result := False;
end; end;
function RegisterPaintBox: Boolean; alias : 'WSRegisterPaintBox'; function RegisterPaintBox: Boolean; alias : 'WSRegisterPaintBox';
@ -597,16 +596,14 @@ end;
function RegisterPairSplitterSide: Boolean; alias : 'WSRegisterPairSplitterSide'; function RegisterPairSplitterSide: Boolean; alias : 'WSRegisterPairSplitterSide';
begin begin
// RegisterWSComponent(TPairSplitterSide, TGtk2WSPairSplitterSide); { GTK1 } RegisterWSComponent(TPairSplitterSide, TGtk3WSPairSplitterSide);
// RegisterWSComponent(TPairSplitterSide, TGtk2WSPairSplitterSide); Result := true;
Result := False;
end; end;
function RegisterCustomPairSplitter: Boolean; alias : 'WSRegisterCustomPairSplitter'; function RegisterCustomPairSplitter: Boolean; alias : 'WSRegisterCustomPairSplitter';
begin begin
// RegisterWSComponent(TCustomPairSplitter, TGtk2WSCustomPairSplitter, TGtkPrivatePaned); { GTK1 } RegisterWSComponent(TCustomPairSplitter, TGtk3WSCustomPairSplitter);
// RegisterWSComponent(TCustomPairSplitter, TGtk2WSCustomPairSplitter); Result := true;
Result := False;
end; end;
function RegisterCustomFloatSpinEdit: Boolean; alias : 'WSRegisterCustomFloatSpinEdit'; function RegisterCustomFloatSpinEdit: Boolean; alias : 'WSRegisterCustomFloatSpinEdit';

View File

@ -0,0 +1,127 @@
unit gtk3wssplitter;
{$mode objfpc}{$H+}
{$I gtk3defines.inc}
interface
uses
// LCL
LCLProc, ExtCtrls, Classes, Controls, SysUtils, types, Graphics, LCLType,
// widgetset
WSExtCtrls, WSLCLClasses, WSPairSplitter,
Gtk3WSControls,
PairSplitter;
type
{ TGtk3WSPairSplitterSide }
TGtk3WSPairSplitterSide = class(TWSPairSplitterSide)
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
end;
{ TGtk3WSCustomPairSplitter }
TGtk3WSCustomPairSplitter = class(TWSCustomPairSplitter)
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
class function AddSide(ASplitter: TCustomPairSplitter; ASide: TPairSplitterSide; Side: integer): Boolean; override;
class function RemoveSide(ASplitter: TCustomPairSplitter; ASide: TPairSplitterSide; Side: integer): Boolean; override;
class function SetPosition(ASplitter: TCustomPairSplitter; var NewPosition: integer): Boolean; override;
// special cursor handling
class function GetSplitterCursor(ASplitter: TCustomPairSplitter; var ACursor: TCursor): Boolean; override;
class function SetSplitterCursor(ASplitter: TCustomPairSplitter; ACursor: TCursor): Boolean; override;
end;
implementation
uses
wsproc,gtk3widgets,lazgtk3;
{ TGtk3WSPairSplitterSide }
class function TGtk3WSPairSplitterSide.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
begin
Result:=TLclIntfHandle(TGtk3Window.Create(AWinControl, AParams));
end;
{ TGtk3WSSplitter }
{ TGtk3WSCustomPairSplitter }
class function TGtk3WSCustomPairSplitter.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
begin
Result:=TLclIntfHandle(TGtk3Paned.Create(AWinControl, AParams));
end;
class function TGtk3WSCustomPairSplitter.AddSide(ASplitter: TCustomPairSplitter;
ASide: TPairSplitterSide; Side: integer): Boolean;
var
paned: TGtk3Paned;
wside:TGtk3Widget;
begin
Result := False;
if not (WSCheckHandleAllocated(ASplitter, 'AddSide - splitter') and
WSCheckHandleAllocated(ASide, 'AddSide - side'))
then Exit;
if (Side < 0) or (Side > 1) then exit;
paned:=TGtk3Paned(ASplitter.Handle);
wside:=TGtk3Widget(ASide.Handle);
if Side=0 then
begin
PGtkWIdget(wside.Widget)^.set_parent(nil);
PGtkPaned(paned.Widget)^.add1(wside.Widget);
end
else
begin
PGtkWidget(wside.Widget)^.set_parent(nil);
PGtkPaned(paned.Widget)^.add2(wside.Widget);
end;
Result := True;
end;
class function TGtk3WSCustomPairSplitter.RemoveSide(ASplitter: TCustomPairSplitter;
ASide: TPairSplitterSide; Side: integer): Boolean;
begin
Result := False;
end;
class function TGtk3WSCustomPairSplitter.SetPosition(
ASplitter: TCustomPairSplitter; var NewPosition: integer): Boolean;
var
paned:PGtkPaned;
begin
Result:=false;
if not WSCheckHandleAllocated(ASplitter, ClassName+'.SetPosition') then
Exit;
paned:=PGtkPaned(TGtk3Paned(ASplitter.Handle).Widget);
paned^.set_position(NewPosition);
Result:=true;
///Result:=inherited SetPosition(ASplitter, NewPosition);
end;
class function TGtk3WSCustomPairSplitter.GetSplitterCursor(
ASplitter: TCustomPairSplitter; var ACursor: TCursor): Boolean;
begin
ACursor:=crHsplit;
Result:=true;
end;
class function TGtk3WSCustomPairSplitter.SetSplitterCursor(
ASplitter: TCustomPairSplitter; ACursor: TCursor): Boolean;
begin
//ASplitter.Cursor:=ACursor;
Result:=false;
end;
end.