diff --git a/.gitattributes b/.gitattributes index 24eb9a2f79..0fae6e3b8f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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/gtk3wsmenus.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/interfaces.pp svneol=native#text/plain lcl/interfaces/gtk3/issues.xml svneol=native#text/plain diff --git a/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas b/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas index f13677e420..a5fde35ded 100644 --- a/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas +++ b/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas @@ -283,8 +283,8 @@ type TGtkOrientation = Integer; const { GtkOrientation } - GTK_ORIENTATION_HORIZONTAL: TGtkOrientation = 0; - GTK_ORIENTATION_VERTICAL: TGtkOrientation = 1; + GTK_ORIENTATION_HORIZONTAL = TGtkOrientation(0); + GTK_ORIENTATION_VERTICAL = TGtkOrientation(1); type TGtkDestDefaults = Integer; diff --git a/lcl/interfaces/gtk3/gtk3lclintf.inc b/lcl/interfaces/gtk3/gtk3lclintf.inc index cb3ecf27c5..8308e041f7 100644 --- a/lcl/interfaces/gtk3/gtk3lclintf.inc +++ b/lcl/interfaces/gtk3/gtk3lclintf.inc @@ -29,45 +29,22 @@ begin if dy < 0 then dy := 0; - (* // 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_widget_set_uposition(Widget, ARect.Left, ARect.Top); - gtk_widget_set_app_paintable(Widget, True); + gtk_widget_realize(Widget); + gdk_window_set_decorations(Widget^.window, 0); gdk_window_set_functions(Widget^.window, GDK_FUNC_RESIZE or GDK_FUNC_CLOSE); - gtk_window_set_opacity({%H-}PGtkWindow(Result), 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_set_opacity(Widget, 0.25); gtk_widget_show(Widget); - *) end; procedure TGtk3WidgetSet.DestroyRubberBand(ARubberBand: HWND); begin - // TODO: gtk_widget_destroy({%H-}PGtkWidget(ARubberBand)); + gtk_widget_destroy({%H-}PGtkWidget(ARubberBand)); end; procedure TGtk3WidgetSet.DrawDefaultDockImage(AOldRect, ANewRect: TRect; diff --git a/lcl/interfaces/gtk3/gtk3widgets.pas b/lcl/interfaces/gtk3/gtk3widgets.pas index bbfd68a4fa..660fe10e6e 100644 --- a/lcl/interfaces/gtk3/gtk3widgets.pas +++ b/lcl/interfaces/gtk3/gtk3widgets.pas @@ -25,7 +25,7 @@ uses Classes, SysUtils, types, math, // LCL 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 LazGtk3, LazGdk3, LazGObject2, LazGLib2, LazCairo1, LazPango1, LazGdkPixbuf2, gtk3objects, gtk3procs, gtk3private, Gtk3CellRenderer; @@ -383,6 +383,22 @@ type 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 = class(TGtk3Container) @@ -711,6 +727,13 @@ type function CreateWidget(const Params: TCreateParams):PGtkWidget; override; end; + { TGtk3Splitter } + + TGtk3Splitter = class(TGtk3Panel) + public + end; + + { TGtk3Window } 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)); 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 } function TGtk3Widget.GtkEventMouseEnterLeave(Sender: PGtkWidget; Event: PGdkEvent): Boolean; @@ -1598,23 +1640,22 @@ function TGtk3Widget.GtkEventMouseEnterLeave(Sender: PGtkWidget; Event: PGdkEven var Msg: TLMessage; // MouseMsg: TLMMouseMove absolute Msg; + {$IFDEF GTK3DEBUGCORE} MousePos: TPoint; + {$ENDIF} begin Result := False; FillChar(Msg, SizeOf(Msg), #0); if Event^.type_ = GDK_ENTER_NOTIFY then - begin - Msg.Msg := LM_MOUSEENTER; - end else - begin + Msg.Msg := LM_MOUSEENTER + else Msg.Msg := LM_MOUSELEAVE; - end; - MousePos.X := Round(Event^.crossing.x); - MousePos.Y := Round(Event^.crossing.y); NotifyApplicationUserInput(LCLObject, Msg.Msg); Result := DeliverMessage(Msg, True) <> 0; {$IFDEF GTK3DEBUGCORE} + MousePos.X := Round(Event^.crossing.x); + MousePos.Y := Round(Event^.crossing.y); DebugLn('GtkEventMouseEnterLeave: mousePos ',dbgs(MousePos),' Object ',dbgsName(LCLObject), ' IsEnter ',dbgs(Event^.type_ = GDK_ENTER_NOTIFY),' Result=',dbgs(Result)); {$ENDIF} @@ -3881,10 +3922,7 @@ begin AToolBar := TToolBar(LCLObject); FHasPaint := False; FWidgetType := [wtWidget, wtContainer]; - Result := PGtkWidget(TGtkHBox.new(GTK_ORIENTATION_HORIZONTAL, 0)); - FCentralWidget := PGtkWidget(TGtkFixed.new); - PGtkHBox(Result)^.add(FCentralWidget); - PGtkFixed(FCentralWidget)^.set_has_window(True); + Result:=PGtkWidget(TGtkToolbar.new); end; { TGtk3Page } @@ -6457,7 +6495,7 @@ end; function TGtk3Window.GetTitle: String; begin - Result := ''; + Result:=PGtkWindow(FWidget)^.get_title(); end; procedure TGtk3Window.SetIcon(AValue: PGdkPixBuf); @@ -6561,9 +6599,15 @@ begin FHasPaint := True; AForm := TCustomForm(LCLObject); - FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtWindow]; - - Result := TGtkWindow.new(GTK_WINDOW_TOPLEVEL); + if not Assigned(LCLObject.Parent) then + begin + 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); diff --git a/lcl/interfaces/gtk3/gtk3winapi.inc b/lcl/interfaces/gtk3/gtk3winapi.inc index e8b2cb0943..01d0e09bd2 100644 --- a/lcl/interfaces/gtk3/gtk3winapi.inc +++ b/lcl/interfaces/gtk3/gtk3winapi.inc @@ -3677,10 +3677,8 @@ end; function TGtk3WidgetSet.SetParent(hWndChild: HWND; hWndParent: HWND): HWND; begin - {$IFDEF GTK3DEBUGNOTIMPLEMENTED} - DebugLn('WARNING: TGtk3WidgetSet.SetParent not implemented ...'); - {$ENDIF} - Result:=inherited SetParent(hWndChild, hWndParent); + Result := HWND(TGtk3Widget(hWndChild).getParent); + TGtk3Widget(hWndChild).SetParent(TGtk3Widget(hWndParent),0,0) end; function TGtk3WidgetSet.SetProp(Handle: hwnd; Str: PChar; Data: Pointer diff --git a/lcl/interfaces/gtk3/gtk3wsextctrls.pp b/lcl/interfaces/gtk3/gtk3wsextctrls.pp index 2b654d6114..b3ccfb3c19 100644 --- a/lcl/interfaces/gtk3/gtk3wsextctrls.pp +++ b/lcl/interfaces/gtk3/gtk3wsextctrls.pp @@ -50,6 +50,8 @@ type TGtk3WSCustomSplitter = class(TWSCustomSplitter) published + class function CreateHandle(const AWinControl: TWinControl; + const AParams: TCreateParams): TLCLIntfHandle; override; end; { TGtk3WSSplitter } @@ -146,6 +148,17 @@ implementation uses 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 } class function TGtk3WSCustomPanel.CreateHandle(const AWinControl: TWinControl; diff --git a/lcl/interfaces/gtk3/gtk3wsfactory.pas b/lcl/interfaces/gtk3/gtk3wsfactory.pas index 425d62d8e3..fdbd2e4435 100644 --- a/lcl/interfaces/gtk3/gtk3wsfactory.pas +++ b/lcl/interfaces/gtk3/gtk3wsfactory.pas @@ -21,7 +21,7 @@ interface uses Classes, Controls, ComCtrls, Calendar, StdCtrls, Arrow, Spin, Dialogs, ExtCtrls, ExtDlgs, Buttons, CheckLst, Forms, Grids, Menus, - PairSplitter, ImgList, WSLCLClasses; + ImgList, PairSplitter, WSLCLClasses; // imglist @@ -137,7 +137,7 @@ uses uses Gtk3WSImgList, Gtk3WSControls, Gtk3WSForms, Gtk3WSButtons, Gtk3WSStdCtrls, Gtk3WSComCtrls, Gtk3WSExtCtrls, Gtk3WSSpin, Gtk3WSMenus, Gtk3WSCalendar, - Gtk3WSDialogs, Gtk3WSCheckLst, Gtk3WSExtDlgs; + Gtk3WSDialogs, Gtk3WSCheckLst, Gtk3WSExtDlgs, gtk3wssplitter; // imglist function RegisterCustomImageListResolution: Boolean; alias : 'WSRegisterCustomImageListResolution'; @@ -402,9 +402,8 @@ end; function RegisterCustomSplitter: Boolean; alias : 'WSRegisterCustomSplitter'; begin -// RegisterWSComponent(TCustomSplitter, TGtk2WSCustomSplitter); -// RegisterWSComponent(TSplitter, TGtk2WSSplitter); - Result := False; + RegisterWSComponent(TCustomSplitter, TGtk3WSCustomSplitter); + Result := true; end; function RegisterPaintBox: Boolean; alias : 'WSRegisterPaintBox'; @@ -597,16 +596,14 @@ end; function RegisterPairSplitterSide: Boolean; alias : 'WSRegisterPairSplitterSide'; begin -// RegisterWSComponent(TPairSplitterSide, TGtk2WSPairSplitterSide); { GTK1 } -// RegisterWSComponent(TPairSplitterSide, TGtk2WSPairSplitterSide); - Result := False; + RegisterWSComponent(TPairSplitterSide, TGtk3WSPairSplitterSide); + Result := true; end; function RegisterCustomPairSplitter: Boolean; alias : 'WSRegisterCustomPairSplitter'; begin - // RegisterWSComponent(TCustomPairSplitter, TGtk2WSCustomPairSplitter, TGtkPrivatePaned); { GTK1 } - // RegisterWSComponent(TCustomPairSplitter, TGtk2WSCustomPairSplitter); - Result := False; + RegisterWSComponent(TCustomPairSplitter, TGtk3WSCustomPairSplitter); + Result := true; end; function RegisterCustomFloatSpinEdit: Boolean; alias : 'WSRegisterCustomFloatSpinEdit'; diff --git a/lcl/interfaces/gtk3/gtk3wssplitter.pas b/lcl/interfaces/gtk3/gtk3wssplitter.pas new file mode 100644 index 0000000000..d38b66c94e --- /dev/null +++ b/lcl/interfaces/gtk3/gtk3wssplitter.pas @@ -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. +