diff --git a/lcl/interfaces/gtk/gtkwsspin.pp b/lcl/interfaces/gtk/gtkwsspin.pp index 1bf0abac76..05f7493eb1 100644 --- a/lcl/interfaces/gtk/gtkwsspin.pp +++ b/lcl/interfaces/gtk/gtkwsspin.pp @@ -27,15 +27,17 @@ unit GtkWSSpin; interface uses + // Bindings {$IFDEF gtk2} glib2, gdk2pixbuf, gdk2, gtk2, Pango, {$ELSE} glib, gdk, gtk, {$ENDIF} - GtkInt, - LCLProc, Spin, StdCtrls, GtkProc, GtkExtra, GtkDef, - GtkWSControls, GtkWSStdCtrls, - WSLCLClasses, WSSpin, Controls, LCLType; + // RTL, FCL, LCL + Controls, LCLType, LCLProc, Spin, StdCtrls, + // Widgetset + GtkProc, GtkExtra, GtkDef, GtkInt, GtkWSControls, GtkWSStdCtrls, + WSLCLClasses, WSSpin; type diff --git a/lcl/interfaces/gtk2/gtk2int.pas b/lcl/interfaces/gtk2/gtk2int.pas index c0834ba3e7..ca4f7491f3 100644 --- a/lcl/interfaces/gtk2/gtk2int.pas +++ b/lcl/interfaces/gtk2/gtk2int.pas @@ -162,7 +162,7 @@ uses // Gtk2WSMaskEdit, Gtk2WSMenus, // Gtk2WSPairSplitter, -// Gtk2WSSpin, + Gtk2WSSpin, Gtk2WSStdCtrls, // Gtk2WSToolwin, Gtk2Themes, diff --git a/lcl/interfaces/gtk2/gtk2proc.pp b/lcl/interfaces/gtk2/gtk2proc.pp index 11b6eec296..43c4efd442 100644 --- a/lcl/interfaces/gtk2/gtk2proc.pp +++ b/lcl/interfaces/gtk2/gtk2proc.pp @@ -68,11 +68,44 @@ function GTKWindowStateEventCB(widget: PGtkWidget; function gtkMouseWheelCB(widget: PGtkWidget; event: PGdkEventScroll; data: gPointer): GBoolean; cdecl; +{ Miscelaneus Widget functions } + +function WidgetGetSelStart(const Widget: PGtkWidget): integer; +procedure WidgetSetSelLength(const Widget: PGtkWidget; NewLength: integer); + implementation uses gtkproc; // Remove when separation is complete +{ Callbacks for events } + {$include gtk2callback.inc} +{ Miscelaneus Widget functions } + +function WidgetGetSelStart(const Widget: PGtkWidget): integer; +begin + if Widget <> nil then + begin + if PGtkOldEditable(Widget)^.selection_start_pos + < PGtkOldEditable(Widget)^.selection_end_pos + then + Result:= PGtkOldEditable(Widget)^.selection_start_pos + else + Result:= PGtkOldEditable(Widget)^.current_pos;// selection_end_pos + end else + Result:= 0; +end; + +procedure WidgetSetSelLength(const Widget: PGtkWidget; NewLength: integer); +begin + if Widget<>nil then + begin + gtk_editable_select_region(PGtkOldEditable(Widget), + gtk_editable_get_position(PGtkOldEditable(Widget)), + gtk_editable_get_position(PGtkOldEditable(Widget)) + NewLength); + end; +end; + end. diff --git a/lcl/interfaces/gtk2/gtk2wsspin.pp b/lcl/interfaces/gtk2/gtk2wsspin.pp index bf19395cc0..9a8eabc29e 100644 --- a/lcl/interfaces/gtk2/gtk2wsspin.pp +++ b/lcl/interfaces/gtk2/gtk2wsspin.pp @@ -27,17 +27,13 @@ unit Gtk2WSSpin; interface uses -//////////////////////////////////////////////////// -// I M P O R T A N T -//////////////////////////////////////////////////// -// To get as little as posible circles, -// uncomment only when needed for registration -//////////////////////////////////////////////////// -// Spin, -//////////////////////////////////////////////////// - WSSpin, WSLCLClasses, Controls, Spin, - Gtk2Int, - gtk2; + // Bindings + glib2, gdk2pixbuf, gdk2, gtk2, Pango, + // RTL, FCL, LCL + Controls, LCLType, LCLProc, Spin, StdCtrls, + // Widgetset + GtkProc, GtkExtra, GtkDef, Gtk2Int, Gtk2WSControls, Gtk2WSStdCtrls, + Gtk2Proc, WSLCLClasses, WSSpin; type @@ -46,20 +42,145 @@ type TGtk2WSCustomFloatSpinEdit = class(TWSCustomFloatSpinEdit) private protected + class procedure SetCallbacks(const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; public + class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override; + class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override; + class function GetValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): single; override; + + class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override; + class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; + + class procedure UpdateControl(const ACustomFloatSpinEdit: TCustomFloatSpinEdit); override; + class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; end; - { TGtk2WSFloatSpinEdit } - - TGtk2WSFloatSpinEdit = class(TWSFloatSpinEdit) - private - protected - public - end; - +function GetGtkSpinEntry(Spin: PGtkSpinButton): PGtkEntry; +function GetSpinGtkEntry(const Spin: TWinControl): PGtkEntry; +function GetGtkFloatSpinEditable(Spin: PGtkSpinButton): PGtkOldEditable; +function GetSpinGtkEditable(const Spin: TWinControl): PGtkOldEditable; implementation +function GetGtkSpinEntry(Spin: PGtkSpinButton): PGtkEntry; +begin + Result:=PGtkEntry(@(Spin^.entry)); +end; + +function GetSpinGtkEntry(const Spin: TWinControl): PGtkEntry; +begin + Result:=GetGtkSpinEntry(PGtkSpinButton(Spin.Handle)); +end; + +function GetGtkFloatSpinEditable(Spin: PGtkSpinButton): PGtkOldEditable; +begin + Result:=PGtkOldEditable(@(Spin^.entry)); +end; + +function GetSpinGtkEditable(const Spin: TWinControl): PGtkOldEditable; +begin + Result:=GetGtkFloatSpinEditable(PGtkSpinButton(Spin.Handle)); +end; + +{ TGtkWSCustomFloatSpinEdit } + +class procedure TGtk2WSCustomFloatSpinEdit.SetCallbacks( + const AWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); +begin + TGtk2WSCustomEdit.SetCallbacks(AWidget, AWidgetInfo); +end; + +class function TGtk2WSCustomFloatSpinEdit.GetSelStart(const ACustomEdit: TCustomEdit): integer; +begin + Result :=WidgetGetSelStart(PGtkWidget(GetSpinGtkEntry(ACustomEdit))); +end; + +class function TGtk2WSCustomFloatSpinEdit.GetSelLength(const ACustomEdit: TCustomEdit): integer; +begin + with GetSpinGtkEditable(ACustomEdit)^ do + Result := Abs(integer(selection_end_pos)-integer(selection_start_pos)); +end; + +class function TGtk2WSCustomFloatSpinEdit.GetValue( + const ACustomFloatSpinEdit: TCustomFloatSpinEdit): single; +begin + // developer.gnome.org/doc/API/2.2/gtk/GtkSpinButton.html: + // "function gtk_spin_button_get_value_as_float is deprecated, use gtk_spin_button_get_value() instead" + Result:=Single(gtk_spin_button_get_value(PGtkSpinButton(ACustomFloatSpinEdit.Handle))); +end; + +class procedure TGtk2WSCustomFloatSpinEdit.SetSelStart(const ACustomEdit: TCustomEdit; + NewStart: integer); +begin + gtk_editable_set_position(GetSpinGtkEditable(ACustomEdit), NewStart); +end; + +class procedure TGtk2WSCustomFloatSpinEdit.SetSelLength(const ACustomEdit: TCustomEdit; + NewLength: integer); +begin + WidgetSetSelLength(PGtkWidget(GetSpinGtkEntry(ACustomEdit)), + NewLength); +end; + +class procedure TGtk2WSCustomFloatSpinEdit.UpdateControl( + const ACustomFloatSpinEdit: TCustomFloatSpinEdit); +var + AnAdjustment: PGtkAdjustment; + wHandle: HWND; + SpinWidget: PGtkSpinButton; + AMin, AMax: Single; +begin + //DebugLn(['TGtkWSCustomFloatSpinEdit.UpdateControl ',dbgsName(ACustomFloatSpinEdit)]); + wHandle := ACustomFloatSpinEdit.Handle; + SpinWidget:=GTK_SPIN_BUTTON(Pointer(wHandle)); + + if ACustomFloatSpinEdit.MaxValue > ACustomFloatSpinEdit.MinValue then + begin + AMin := ACustomFloatSpinEdit.MinValue; + AMax := ACustomFloatSpinEdit.MaxValue; + end + else + begin + AMin := -3.4E38; // min single + AMax := 3.4E38; // max single + end; + + AnAdjustment:=gtk_spin_button_get_adjustment(SpinWidget); + if (AnAdjustment^.lower <> AMin) + or (AnAdjustment^.upper <> AMax) then + begin + AnAdjustment^.lower := AMin; + AnAdjustment^.upper := AMax; + gtk_adjustment_changed(AnAdjustment); + end; + + gtk_spin_button_set_digits(SpinWidget, ACustomFloatSpinEdit.DecimalPlaces); + gtk_spin_button_set_value(SpinWidget,ACustomFloatSpinEdit.Value); + AnAdjustment^.step_increment := ACustomFloatSpinEdit.Increment; +end; + +class function TGtk2WSCustomFloatSpinEdit.CreateHandle( + const AWinControl: TWinControl; const AParams: TCreateParams + ): TLCLIntfHandle; +var + Adjustment: PGtkAdjustment; + Widget: PGtkWidget; + WidgetInfo: PWidgetInfo; +begin + Adjustment := PGtkAdjustment(gtk_adjustment_new(1, 1, 100, 1, 1, 1)); + Widget := gtk_spin_button_new(Adjustment, 1, 0); + gtk_widget_show_all(Widget); + + {$IFDEF DebugLCLComponents} + DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); + {$ENDIF} + Result := TLCLIntfHandle(PtrUInt(Widget)); + + WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams); + Set_RC_Name(AWinControl, Widget); + SetCallbacks(Widget, WidgetInfo); +end; + initialization //////////////////////////////////////////////////// @@ -68,7 +189,7 @@ initialization // To improve speed, register only classes // which actually implement something //////////////////////////////////////////////////// -// RegisterWSComponent(TCustomFloatSpinEdit, TGtk2WSCustomFloatSpinEdit); + RegisterWSComponent(TCustomFloatSpinEdit, TGtk2WSCustomFloatSpinEdit); // RegisterWSComponent(TFloatSpinEdit, TGtk2WSFloatSpinEdit); //////////////////////////////////////////////////// end.