View Issue Details

IDProjectCategoryView StatusLast Update
0034106LazarusWidgetsetpublic2018-10-23 07:52
ReporterAnton Kavalenka Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Platformx86_64OSLinux 
Product Version1.9 (SVN) 
Summary0034106: gtk3: Splitter idnores design settings and always 46pix width
DescriptionRun the attached demo
TagsNo tags attached.
Fixed in Revisionr59339, r59341
LazTarget-
WidgetsetGTK 3
Attached Files

Activities

Anton Kavalenka

2018-08-09 18:26

reporter  

laztest105.zip (66,611 bytes)

Anton Kavalenka

2018-08-09 18:26

reporter  

Anton Kavalenka

2018-10-20 16:30

reporter  

laztest105_1.zip (4,960 bytes)

Anton Kavalenka

2018-10-20 16:31

reporter  

laztest114.zip (129,092 bytes)

Anton Kavalenka

2018-10-20 16:34

reporter   ~0111489

Last edited: 2018-10-20 16:46

View 2 revisions

updated tests and proposed patches

laztest105_1 - test for splitter and docking of TForm into TPageControl

Currently rsLine and rsPattern resize style not working because current "rubber band" implementation knows nothing about parent window - so GTK3 magic with offset translation is not possible in that case.

laztest114 - GTK3 Paned object wrapped as TPairSplitter implementation

Anton Kavalenka

2018-10-20 16:35

reporter  

splitters_and_forms.diff (14,596 bytes)   
Index: gtk3bindings/lazgtk3.pas
===================================================================
--- gtk3bindings/lazgtk3.pas	(revision 59328)
+++ gtk3bindings/lazgtk3.pas	(working copy)
@@ -283,8 +283,8 @@
   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;
Index: gtk3lclintf.inc
===================================================================
--- gtk3lclintf.inc	(revision 59328)
+++ gtk3lclintf.inc	(working copy)
@@ -29,17 +29,25 @@
   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);
+  //gdk_window_move(PGtkWIndow(Result)^.window,ARect.Left,ARect.Top);
+  //gtk_widget_set_uposition(Widget, ARect.Left, ARect.Top);
+  //gtk_widget_set_app_paintable(Widget, True);
+
   gtk_widget_realize(Widget);
+
+
+
+//  gdk_window_move(PGtkWIndow(Result)^.window,ARect.Left,ARect.Top);
   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
+  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
@@ -60,14 +68,13 @@
     gdk_window_set_back_pixmap(Widget^.window, Pixmap, False);
     g_object_unref(Pixmap);
   end;
-
+  *)
   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;
Index: gtk3widgets.pas
===================================================================
--- gtk3widgets.pas	(revision 59328)
+++ gtk3widgets.pas	(working copy)
@@ -25,7 +25,7 @@
   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,25 @@
 
   end;
 
+
+  { TGtk3Paned }
+
+  TGtk3Paned = class(TGtk3Container)
+  protected
+    function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
+  public
+    procedure InitializeWidget; override;
+  end;
+
+  { TGtk3SplitterSide }
+
+  TGtk3SplitterSide = class(TGtk3Container)
+  public
+    function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
+    procedure InitializeWidget; override;
+  end;
+
+
   { TGtk3MenuShell }
 
   TGtk3MenuShell = class(TGtk3Container)
@@ -711,6 +730,14 @@
       function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
   end;
 
+  { TGtk3Splitter }
+
+  TGtk3Splitter = class(TGtk3Panel)
+  public
+    procedure InitializeWidget; override;
+  end;
+
+
   { TGtk3Window }
 
   TGtk3Window = class(TGtk3ScrollableWin) {we are TGtk3Bin actually, but it won't hurt since we need scroll}
@@ -1591,6 +1618,53 @@
   // DebugLn('Gtk3ScrollEvent for ', dbgsName(TGtk3Widget(AData).LCLObject),' Result ',dbgs(Result));
 end;
 
+{ TGtk3Splitter }
+
+procedure TGtk3Splitter.InitializeWidget;
+begin
+  inherited InitializeWidget;
+  //TCustomSplitter(Self.LCLObject).;
+end;
+
+{ TGtk3SplitterSide }
+
+function TGtk3SplitterSide.CreateWidget(const Params: TCreateParams
+  ): PGtkWidget;
+begin
+  Result:=TGtkScrolledWindow.new(nil, nil);
+end;
+
+procedure TGtk3SplitterSide.InitializeWidget;
+var
+  spl:TCustomPairSplitter;
+  ctl:TWinControl;
+begin
+  inherited InitializeWidget;
+ (* spl := TCustomPairSplitter(Self.LCLObject.Parent);
+  ctl:=Self.LCLObject;
+  if spl.Sides[0] = ctl then
+  	PGtkPaned(Self.Widget)^.pack1(TGtk3Widget(ctl.Handle).Widget,true,true)
+  else
+    PGtkPaned(Self.Widget)^.pack2(TGtk3Widget(ctl.Handle).Widget,true,true);*)
+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;
+
+procedure TGtk3Paned.InitializeWidget;
+begin
+  inherited InitializeWidget;
+end;
+
 { TGtk3Widget }
 
 function TGtk3Widget.GtkEventMouseEnterLeave(Sender: PGtkWidget; Event: PGdkEvent): Boolean;
@@ -3881,10 +3955,11 @@
   AToolBar := TToolBar(LCLObject);
   FHasPaint := False;
   FWidgetType := [wtWidget, wtContainer];
-  Result := PGtkWidget(TGtkHBox.new(GTK_ORIENTATION_HORIZONTAL, 0));
-  FCentralWidget := PGtkWidget(TGtkFixed.new);
+  //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);
+  PGtkFixed(FCentralWidget)^.set_has_window(True); }
 end;
 
 { TGtk3Page }
@@ -6453,7 +6528,8 @@
 
 function TGtk3Window.GetTitle: String;
 begin
-  Result := '';
+  //Result := '';
+  Result:=PGtkWindow(FWidget)^.get_title();
 end;
 
 procedure TGtk3Window.SetIcon(AValue: PGdkPixBuf);
@@ -6549,6 +6625,7 @@
 function TGtk3Window.CreateWidget(const Params: TCreateParams): PGtkWidget;
 var
   AForm: TCustomForm;
+  fUseLayout:boolean;
 begin
   FIcon := nil;
   FScrollX := 0;
@@ -6557,9 +6634,25 @@
   FHasPaint := True;
   AForm := TCustomForm(LCLObject);
 
+  if not Assigned(LCLObject.Parent) then
+  begin
+  Result := TGtkWindow.new(GTK_WINDOW_TOPLEVEL);
   FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtWindow];
+  end else
+  begin
+    fUseLayout:=true;
+    if FUseLayout then
+      FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtCustomControl]
+    else
+      FWidgetType := [wtWidget, wtContainer, wtTabControl, wtScrollingWin, wtCustomControl];
+    Result := PGtkScrolledWindow(TGtkScrolledWindow.new(nil, nil));
+    //Result:=PGtkWIndow(TGtkBin.newv(32,0,nil));
+   { if FUseLayout then
+      FCentralWidget := TGtkLayout.new(nil, nil)
+    else
+      FCentralWidget := TGtkFixed.new; }
 
-  Result := TGtkWindow.new(GTK_WINDOW_TOPLEVEL);
+  end;
 
   FBox := TGtkVBox.new(GTK_ORIENTATION_VERTICAL, 0);
 
Index: gtk3winapi.inc
===================================================================
--- gtk3winapi.inc	(revision 59328)
+++ gtk3winapi.inc	(working copy)
@@ -3677,10 +3677,8 @@
 
 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
Index: gtk3wsextctrls.pp
===================================================================
--- gtk3wsextctrls.pp	(revision 59328)
+++ gtk3wsextctrls.pp	(working copy)
@@ -50,6 +50,8 @@
 
   TGtk3WSCustomSplitter = class(TWSCustomSplitter)
   published
+    class function CreateHandle(const AWinControl: TWinControl;
+      	const AParams: TCreateParams): TLCLIntfHandle;override;
   end;
 
   { TGtk3WSSplitter }
@@ -146,6 +148,17 @@
 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;
Index: gtk3wsfactory.pas
===================================================================
--- gtk3wsfactory.pas	(revision 59328)
+++ gtk3wsfactory.pas	(working copy)
@@ -21,7 +21,7 @@
 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
   Gtk3WSImgList, Gtk3WSControls, Gtk3WSForms, Gtk3WSButtons, Gtk3WSStdCtrls,
   Gtk3WSComCtrls, Gtk3WSExtCtrls, Gtk3WSSpin, Gtk3WSMenus, Gtk3WSCalendar,
-  Gtk3WSDialogs, Gtk3WSCheckLst, Gtk3WSExtDlgs;
+  Gtk3WSDialogs, Gtk3WSCheckLst, Gtk3WSExtDlgs, gtk3wssplitter;
 
 // imglist
 function RegisterCustomImageListResolution: Boolean; alias : 'WSRegisterCustomImageListResolution';
@@ -402,11 +402,12 @@
 
 function RegisterCustomSplitter: Boolean; alias : 'WSRegisterCustomSplitter';
 begin
-//  RegisterWSComponent(TCustomSplitter, TGtk2WSCustomSplitter);
+  RegisterWSComponent(TCustomSplitter, TGtk3WSCustomSplitter);
 //  RegisterWSComponent(TSplitter, TGtk2WSSplitter);
-  Result := False;
+  Result := true;
 end;
 
+
 function RegisterPaintBox: Boolean; alias : 'WSRegisterPaintBox';
 begin
 //  RegisterWSComponent(TPaintBox, TGtk2WSPaintBox);
@@ -598,15 +599,15 @@
 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, TGtk3WSCustomPairSplitter);//, TGtkPrivatePaned); { GTK1 }
   // RegisterWSComponent(TCustomPairSplitter, TGtk2WSCustomPairSplitter);
-  Result := False;
+  Result := true;
 end;
 
 function RegisterCustomFloatSpinEdit: Boolean; alias : 'WSRegisterCustomFloatSpinEdit';
Index: gtk3wssplitter.pas
===================================================================
--- gtk3wssplitter.pas	(nonexistent)
+++ gtk3wssplitter.pas	(working copy)
@@ -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.
+
splitters_and_forms.diff (14,596 bytes)   

Anton Kavalenka

2018-10-20 16:36

reporter  

Anton Kavalenka

2018-10-20 16:36

reporter  

Juha Manninen

2018-10-21 11:07

developer   ~0111495

The patch adds many commented code blocks and empty lines. They are not needed. Removed lines will show in revision history.

Anton Kavalenka

2018-10-21 19:30

reporter  

splitters_and_forms_cleaned.diff (13,481 bytes)   
Index: gtk3bindings/lazgtk3.pas
===================================================================
--- gtk3bindings/lazgtk3.pas	(revision 59331)
+++ gtk3bindings/lazgtk3.pas	(working copy)
@@ -283,8 +283,8 @@
   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;
Index: gtk3lclintf.inc
===================================================================
--- gtk3lclintf.inc	(revision 59331)
+++ gtk3lclintf.inc	(working copy)
@@ -29,45 +29,22 @@
   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;
Index: gtk3widgets.pas
===================================================================
--- gtk3widgets.pas	(revision 59331)
+++ gtk3widgets.pas	(working copy)
@@ -25,7 +25,7 @@
   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 @@
 
   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 @@
       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,26 @@
   // 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;
@@ -3881,10 +3924,7 @@
   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 }
@@ -6453,7 +6493,7 @@
 
 function TGtk3Window.GetTitle: String;
 begin
-  Result := '';
+  Result:=PGtkWindow(FWidget)^.get_title();
 end;
 
 procedure TGtk3Window.SetIcon(AValue: PGdkPixBuf);
@@ -6557,10 +6597,16 @@
   FHasPaint := True;
   AForm := TCustomForm(LCLObject);
 
-  FWidgetType := [wtWidget, wtLayout, wtScrollingWin, wtWindow];
+  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;
 
-  Result := TGtkWindow.new(GTK_WINDOW_TOPLEVEL);
-
   FBox := TGtkVBox.new(GTK_ORIENTATION_VERTICAL, 0);
 
   //TODO: when menu is added dynamically to the form create FMenuBar
Index: gtk3winapi.inc
===================================================================
--- gtk3winapi.inc	(revision 59331)
+++ gtk3winapi.inc	(working copy)
@@ -3677,10 +3677,8 @@
 
 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
Index: gtk3wsextctrls.pp
===================================================================
--- gtk3wsextctrls.pp	(revision 59331)
+++ gtk3wsextctrls.pp	(working copy)
@@ -50,6 +50,8 @@
 
   TGtk3WSCustomSplitter = class(TWSCustomSplitter)
   published
+    class function CreateHandle(const AWinControl: TWinControl;
+      	const AParams: TCreateParams): TLCLIntfHandle;override;
   end;
 
   { TGtk3WSSplitter }
@@ -146,6 +148,17 @@
 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;
Index: gtk3wsfactory.pas
===================================================================
--- gtk3wsfactory.pas	(revision 59331)
+++ gtk3wsfactory.pas	(working copy)
@@ -21,7 +21,7 @@
 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
   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 @@
 
 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 @@
 
 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';
Index: gtk3wssplitter.pas
===================================================================
--- gtk3wssplitter.pas	(nonexistent)
+++ gtk3wssplitter.pas	(working copy)
@@ -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.
+

Anton Kavalenka

2018-10-21 19:31

reporter   ~0111503

Uploaded cleaner patch

Juha Manninen

2018-10-22 20:27

developer   ~0111513

Applied the new patch. Thanks.
I tested with the demo apps and it improved things a lot.

In future please create patches in the Lazarus top directory. Will be easier to apply, too.

Anton Kavalenka

2018-10-22 21:20

reporter   ~0111515

Last edited: 2018-10-22 21:22

View 2 revisions

gtk3wssplitter.pas is lost in SVN commit r59339

Anton Kavalenka

2018-10-22 21:20

reporter  

gtk3wssplitter.pas (3,583 bytes)   
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.

gtk3wssplitter.pas (3,583 bytes)   

Juha Manninen

2018-10-22 23:55

developer   ~0111516

Yes, sorry. Added in r59341.

Issue History

Date Modified Username Field Change
2018-08-09 18:26 Anton Kavalenka New Issue
2018-08-09 18:26 Anton Kavalenka File Added: laztest105.zip
2018-08-09 18:26 Anton Kavalenka File Added: Здымак экрана, 2018-08-09 19-21-13.png
2018-10-20 16:30 Anton Kavalenka File Added: laztest105_1.zip
2018-10-20 16:31 Anton Kavalenka File Added: laztest114.zip
2018-10-20 16:34 Anton Kavalenka Note Added: 0111489
2018-10-20 16:35 Anton Kavalenka File Added: splitters_and_forms.diff
2018-10-20 16:36 Anton Kavalenka File Added: Здымак экрана, 2018-10-20 17-31-30.png
2018-10-20 16:36 Anton Kavalenka File Added: Здымак экрана, 2018-10-20 17-32-03.png
2018-10-20 16:46 Anton Kavalenka Note Edited: 0111489 View Revisions
2018-10-21 11:07 Juha Manninen Note Added: 0111495
2018-10-21 19:30 Anton Kavalenka File Added: splitters_and_forms_cleaned.diff
2018-10-21 19:31 Anton Kavalenka Note Added: 0111503
2018-10-22 20:24 Juha Manninen Assigned To => Juha Manninen
2018-10-22 20:24 Juha Manninen Status new => assigned
2018-10-22 20:27 Juha Manninen Fixed in Revision => r59339
2018-10-22 20:27 Juha Manninen LazTarget => -
2018-10-22 20:27 Juha Manninen Note Added: 0111513
2018-10-22 20:27 Juha Manninen Status assigned => resolved
2018-10-22 20:27 Juha Manninen Resolution open => fixed
2018-10-22 21:20 Anton Kavalenka Note Added: 0111515
2018-10-22 21:20 Anton Kavalenka File Added: gtk3wssplitter.pas
2018-10-22 21:22 Anton Kavalenka Note Edited: 0111515 View Revisions
2018-10-22 22:46 Anton Kavalenka Status resolved => assigned
2018-10-22 22:46 Anton Kavalenka Resolution fixed => reopened
2018-10-22 23:55 Juha Manninen Fixed in Revision r59339 => r59339, r59341
2018-10-22 23:55 Juha Manninen Note Added: 0111516
2018-10-22 23:55 Juha Manninen Status assigned => resolved
2018-10-22 23:55 Juha Manninen Resolution reopened => fixed
2018-10-23 07:52 Anton Kavalenka Status resolved => closed