diff --git a/lcl/interfaces/gtk/gtkwscontrols.pp b/lcl/interfaces/gtk/gtkwscontrols.pp index 720e6c2035..68b4c74343 100644 --- a/lcl/interfaces/gtk/gtkwscontrols.pp +++ b/lcl/interfaces/gtk/gtkwscontrols.pp @@ -70,13 +70,16 @@ type TGtkWSWinControl = class(TWSWinControl) private protected + {$IFDEF GTK1} class procedure SetCCCallbacks(const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); + {$ENDIF} public // Internal public class procedure SetCallbacks(const AGTKObject: PGTKObject; const AComponent: TComponent); public + {$IFDEF GTK1} class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): HWND; override; - + {$ENDIF} class procedure AddControl(const AControl: TControl); override; class function CanFocus(const AWinControl: TWinControl): Boolean; override; class procedure ConstraintsChange(const AWinControl: TWinControl); override; @@ -318,6 +321,7 @@ begin gtk_frame_set_shadow_type(PGtkFrame(Widget), BorderStyleShadowMap[ABorderStyle]); end; +{$IFDEF GTK1} class procedure TGtkWSWinControl.SetCCCallbacks(const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); begin @@ -328,6 +332,7 @@ begin SetCallback(LM_VSCROLL, PGtkObject(AWidget), AWidgetInfo^.LCLObject); end; end; +{$ENDIF} class procedure TGtkWSWinControl.SetCallbacks(const AGTKObject: PGTKObject; const AComponent: TComponent); @@ -351,6 +356,7 @@ begin GtkWidgetSet.SetCallback(LM_DROPFILES, AGTKObject, AComponent); end; +{$IFDEF GTK1} class function TGtkWSWinControl.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): HWND; var @@ -381,6 +387,7 @@ begin Set_RC_Name(AWinControl, Widget); SetCCCallbacks(Widget, WidgetInfo); end; +{$ENDIF} class procedure TGtkWSWinControl.SetChildZPosition( const AWinControl, AChild: TWinControl; diff --git a/lcl/interfaces/gtk2/gtk2wscontrols.pp b/lcl/interfaces/gtk2/gtk2wscontrols.pp index 69dbeac03f..a3f3ac3d77 100644 --- a/lcl/interfaces/gtk2/gtk2wscontrols.pp +++ b/lcl/interfaces/gtk2/gtk2wscontrols.pp @@ -35,7 +35,8 @@ uses //////////////////////////////////////////////////// Controls, //////////////////////////////////////////////////// - Gtk2, Gdk2, Glib2, GtkGlobals, + Classes, + Gtk2, Gdk2, Glib2, GtkGlobals, GtkDef, GtkWsControls, gtkProc, LCLType, WSControls, WSLCLClasses, WSProc; @@ -65,6 +66,8 @@ type private protected public + class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): HWND; override; + class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override; class procedure SetText(const AWinControl: TWinControl; const AText: string); override; class procedure SetBorderStyle(const AWinControl: TWinControl; const ABorderStyle: TBorderStyle); override; @@ -94,11 +97,141 @@ type public end; +function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType; + AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl; + implementation +uses Gtk2Int, LMessages, Math; { TGtk2WSWinControl } +function GtkScrollTypeToScrollCode(ScrollType: TGtkScrollType): LongWord; +begin + case ScrollType of + GTK_SCROLL_NONE : Result := SB_ENDSCROLL; + GTK_SCROLL_JUMP : Result := SB_THUMBPOSITION; + GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT; + GTK_SCROLL_STEP_FORWARD : Result := SB_LINERIGHT; + GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT; + GTK_SCROLL_PAGE_FORWARD : Result := SB_PAGERIGHT; + GTK_SCROLL_STEP_UP : Result := SB_LINEUP; + GTK_SCROLL_STEP_DOWN : Result := SB_LINEDOWN; + GTK_SCROLL_PAGE_UP : Result := SB_PAGEUP; + GTK_SCROLL_PAGE_DOWN : Result := SB_PAGEDOWN; + GTK_SCROLL_STEP_LEFT : Result := SB_LINELEFT; + GTK_SCROLL_STEP_RIGHT : Result := SB_LINERIGHT; + GTK_SCROLL_PAGE_LEFT : Result := SB_PAGELEFT; + GTK_SCROLL_PAGE_RIGHT : Result := SB_PAGERIGHT; + GTK_SCROLL_START : Result := SB_TOP; + GTK_SCROLL_END : Result := SB_BOTTOM; + end; +end; + +function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType; + AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl; +var + Msg: TLMVScroll; +begin + Result := CallBackDefaultReturn; + //Assert(False, Format('Trace:[Gtk2RangeScrollCB] Value: %d', [RoundToInt(AValue)])); + if G_OBJECT_TYPE(ARange) = gtk_hscrollbar_get_type then + Msg.Msg := LM_HSCROLL + else + Msg.Msg := LM_VSCROLL; + + with Msg do begin + Pos := Round(AValue); + if Pos < High(SmallPos) then + SmallPos := Pos + else + SmallPos := High(SmallPos); + + ScrollBar := HWND(PtrUInt(ARange)); + ScrollCode := GtkScrollTypeToScrollCode(AScrollType); + end; + Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0; +end; + +function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl; +var + Msg: TLMVScroll; + AValue: Double; + Range: PGtkRange; +begin + case AEvent^.direction of + GDK_SCROLL_UP, + GDK_SCROLL_DOWN: Msg.Msg := LM_VSCROLL; + GDK_SCROLL_LEFT, + GDK_SCROLL_RIGHT: Msg.Msg := LM_HSCROLL; + end; + + case Msg.Msg of + LM_VSCROLL: Range := GTK_RANGE(AScrollWindow^.vscrollbar); + LM_HSCROLL: Range := GTK_RANGE(AScrollWindow^.hscrollbar); + end; + + AValue := power(Range^.adjustment^.page_size, 2 / 3); + + if AEvent^.direction = GDK_SCROLL_UP then + AValue := -AValue; + + AValue := gtk_range_get_value(Range) + AValue; + + AValue := Max(AValue, Range^.adjustment^.lower); + AValue := Min(AValue, Range^.adjustment^.upper - Range^.adjustment^.page_size); + + with Msg do begin + Pos := Round(AValue); + if Pos < High(SmallPos) then + SmallPos := Pos + else + SmallPos := High(SmallPos); + + ScrollBar := HWND(PtrUInt(Range)); + ScrollCode := SB_THUMBPOSITION; + end; + Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0; +end; + + +class function TGtk2WSWinControl.CreateHandle(const AWinControl: TWinControl; + const AParams: TCreateParams): HWND; +var + Widget: PGtkWidget; + WidgetInfo: PWidgetInfo; + Allocation: TGTKAllocation; +begin + Widget := GTK2WidgetSet.CreateAPIWidget(AWinControl); + {$IFDEF DebugLCLComponents} + DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); + {$ENDIF} + + Result := THandle(PtrUInt(Widget)); + if Result = 0 then Exit; + + WidgetInfo := GetWidgetInfo(Widget); // Widget info already created in CreateAPIWidget + WidgetInfo^.Style := AParams.Style; + WidgetInfo^.ExStyle := AParams.ExStyle; + WidgetInfo^.WndProc := PtrUInt(AParams.WindowClass.lpfnWndProc); + + // set allocation + Allocation.X := AParams.X; + Allocation.Y := AParams.Y; + Allocation.Width := AParams.Width; + Allocation.Height := AParams.Height; + gtk_widget_size_allocate(Widget, @Allocation); + + Set_RC_Name(AWinControl, Widget); + + TGtkWSWinControl.SetCallbacks(GTK_OBJECT(Widget), AWinControl); + + g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'change-value', TGCallback(@Gtk2RangeScrollCB), WidgetInfo); + g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value', TGCallback(@Gtk2RangeScrollCB), WidgetInfo); + + g_signal_connect(Widget, 'scroll-event', TGCallback(@Gtk2ScrolledWindowScrollCB), WidgetInfo); +end; + class function TGtk2WSWinControl.GetText(const AWinControl: TWinControl; var AText: String): Boolean; var diff --git a/lcl/interfaces/gtk2/gtk2wsstdctrls.pp b/lcl/interfaces/gtk2/gtk2wsstdctrls.pp index 927e391c7b..675c794e61 100644 --- a/lcl/interfaces/gtk2/gtk2wsstdctrls.pp +++ b/lcl/interfaces/gtk2/gtk2wsstdctrls.pp @@ -71,10 +71,13 @@ type { TGtk2WSScrollBar } - TGtk2WSScrollBar = class(TGtkWSScrollBar) + TGtk2WSScrollBar = class(TWSScrollBar) private protected + class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; public + class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; + class procedure SetParams(const AScrollBar: TCustomScrollBar); override; end; { TGtk2WSCustomGroupBox } @@ -344,7 +347,7 @@ function GetComboBoxEntry(Widget: PGtkWidget): PGtkEntry; implementation -uses GtkWSControls, LCLMessageGlue; +uses GtkWSControls, Gtk2WSControls, LCLMessageGlue, Forms; function GetComboBoxEntry(Widget: PGtkWidget): PGtkEntry; begin @@ -1723,6 +1726,59 @@ begin //debugln('TGtkWSButton.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight)); end; +{ TGtk2WSScrollBar } + +class procedure TGtk2WSScrollBar.SetCallbacks(const AGtkWidget: PGtkWidget; + const AWidgetInfo: PWidgetInfo); +begin + TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); + + g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo); +end; + +class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl; + const AParams: TCreateParams): TLCLIntfHandle; +var + Adjustment: PGtkAdjustment = nil; + Widget: PGtkWidget; + WidgetInfo: PWidgetInfo; +begin + with TScrollBar(AWinControl) do + begin +{ Adjustment := GTK_ADJPgtkAdjustment( + gtk_adjustment_new(1, Min, Max, SmallChange, LargeChange, + Pagesize)); + + } if (Kind = sbHorizontal) then + Widget := gtk_hscrollbar_new(Adjustment) + else + Widget := gtk_vscrollbar_new(Adjustment); + end; + + Result := TLCLIntfHandle(PtrUInt(Widget)); + {$IFDEF DebugLCLComponents} + DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); + {$ENDIF} + WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams); + Set_RC_Name(AWinControl, Widget); + SetCallbacks(Widget, WidgetInfo); +end; + +class procedure TGtk2WSScrollBar.SetParams(const AScrollBar: TCustomScrollBar); +var + Adjustment: PGtkAdjustment; + Range: PGtkRange; +begin + with AScrollBar do + begin + Range := GTK_RANGE(Pointer(Handle)); + //set properties for the range + gtk_range_set_range (Range, Min, Max); + gtk_range_set_increments(Range, SmallChange, LargeChange); + gtk_range_set_value (Range, Position); + end; +end; + initialization //////////////////////////////////////////////////// @@ -1731,7 +1787,7 @@ initialization // To improve speed, register only classes // which actually implement something //////////////////////////////////////////////////// -// RegisterWSComponent(TScrollBar, TGtk2WSScrollBar); + RegisterWSComponent(TScrollBar, TGtk2WSScrollBar); RegisterWSComponent(TCustomGroupBox, TGtk2WSCustomGroupBox); // RegisterWSComponent(TGroupBox, TGtk2WSGroupBox); RegisterWSComponent(TCustomComboBox, TGtk2WSCustomComboBox);