mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-31 11:40:33 +02:00
Patch from zeljko for the qt interface. Implements SpinEdit and other improvements
git-svn-id: trunk@11238 -
This commit is contained in:
parent
7cee27e7d9
commit
16e603c725
@ -261,8 +261,8 @@ type
|
||||
protected
|
||||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||||
public
|
||||
procedure SetTickPosition(Value: QSliderTickPosition);
|
||||
procedure SetTickInterval(Value: Integer);
|
||||
procedure SetTickPosition(Value: QSliderTickPosition);
|
||||
procedure SetTickInterval(Value: Integer);
|
||||
procedure SlotSliderMoved(p1: Integer); cdecl; override;
|
||||
procedure SlotValueChanged(p1: Integer); cdecl; override;
|
||||
procedure SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl; override;
|
||||
@ -278,6 +278,7 @@ type
|
||||
destructor Destroy; override;
|
||||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||||
procedure SetColor(const Value: PQColor); override;
|
||||
procedure SignalTextChanged(p1: PWideString); cdecl;
|
||||
end;
|
||||
|
||||
{ TQtTextEdit }
|
||||
@ -290,6 +291,7 @@ type
|
||||
destructor Destroy; override;
|
||||
procedure SetColor(const Value: PQColor); override;
|
||||
procedure SetAlignment(const AAlignment: TAlignment);
|
||||
procedure SignalTextChanged; cdecl;
|
||||
end;
|
||||
|
||||
{ TQtTabWidget }
|
||||
@ -323,14 +325,37 @@ type
|
||||
procedure SlotSelect(index: Integer); cdecl;
|
||||
end;
|
||||
|
||||
{ TQtSpinBox }
|
||||
|
||||
TQtSpinBox = class(TQtWidget)
|
||||
{ TQtAbstractSpinBox}
|
||||
|
||||
TQtAbstractSpinBox = class(TQtWidget)
|
||||
private
|
||||
protected
|
||||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||||
public
|
||||
destructor Destroy; override;
|
||||
function IsReadOnly: Boolean;
|
||||
procedure SetReadOnly(r: Boolean);
|
||||
procedure SignalEditingFinished; cdecl;
|
||||
end;
|
||||
|
||||
{ TQtFloatSpinBox }
|
||||
|
||||
TQtFloatSpinBox = class(TQtAbstractSpinBox)
|
||||
private
|
||||
protected
|
||||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||||
public
|
||||
procedure SignalValueChanged(p1: Double); cdecl;
|
||||
end;
|
||||
|
||||
{ TQtSpinBox }
|
||||
|
||||
TQtSpinBox = class(TQtAbstractSpinBox)
|
||||
private
|
||||
protected
|
||||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||||
public
|
||||
procedure SignalValueChanged(p1: Integer); cdecl;
|
||||
end;
|
||||
|
||||
{ TQtAbstractItemView }
|
||||
@ -2630,6 +2655,22 @@ begin
|
||||
QPalette_destroy(Palette);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Function: TQtLineEdit.SignalTextChanged
|
||||
Params: PWideString
|
||||
Returns: Nothing
|
||||
|
||||
Fires OnChange() event of TCustomEdit
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TQtLineEdit.SignalTextChanged(p1: PWideString); cdecl;
|
||||
var
|
||||
Msg: TLMessage;
|
||||
begin
|
||||
FillChar(Msg, SizeOf(Msg), #0);
|
||||
Msg.Msg := CM_TEXTCHANGED;
|
||||
DeliverMessage(Msg);
|
||||
end;
|
||||
|
||||
{ TQtTextEdit }
|
||||
|
||||
function TQtTextEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||||
@ -2715,6 +2756,22 @@ begin
|
||||
QTextCursor_destroy(TextCursor);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Function: TQtTextEdit.SignalTextChanged
|
||||
Params: none
|
||||
Returns: Nothing
|
||||
|
||||
Fires OnChange() event of TCustomMemo
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TQtTextEdit.SignalTextChanged; cdecl;
|
||||
var
|
||||
Msg: TLMessage;
|
||||
begin
|
||||
FillChar(Msg, SizeOf(Msg), #0);
|
||||
Msg.Msg := CM_TEXTCHANGED;
|
||||
DeliverMessage(Msg);
|
||||
end;
|
||||
|
||||
{ TQtTabWidget }
|
||||
|
||||
function TQtTabWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||||
@ -2914,6 +2971,95 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TQtAbstractSpinBox }
|
||||
|
||||
function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||||
var
|
||||
Parent: QWidgetH;
|
||||
begin
|
||||
// Creates the widget
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtAbstractSpinBox.Create');
|
||||
{$endif}
|
||||
Parent := TQtWidget(LCLObject.Parent.Handle).Widget;
|
||||
Result := QAbstractSpinBox_create(Parent);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Function: TQtAbstractSpinBox.Destroy
|
||||
Params: None
|
||||
Returns: Nothing
|
||||
------------------------------------------------------------------------------}
|
||||
destructor TQtAbstractSpinBox.Destroy;
|
||||
begin
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtAbstractSpinBox.Destroy');
|
||||
{$endif}
|
||||
|
||||
QAbstractSpinBox_destroy(QAbstractSpinBoxH(Widget));
|
||||
Widget:=nil;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TQtAbstractSpinBox.IsReadOnly: Boolean;
|
||||
begin
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtAbstractSpinBox.IsReadOnly');
|
||||
{$endif}
|
||||
Result := QAbstractSpinBox_isReadOnly(QAbstractSpinBoxH(Widget));
|
||||
end;
|
||||
|
||||
procedure TQtAbstractSpinBox.SetReadOnly(r: Boolean);
|
||||
begin
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtAbstractSpinBox.SetReadOnly');
|
||||
{$endif}
|
||||
QAbstractSpinBox_setReadOnly(QAbstractSpinBoxH(Widget), r);
|
||||
end;
|
||||
|
||||
procedure TQtAbstractSpinBox.SignalEditingFinished; cdecl;
|
||||
var
|
||||
Msg: TLMessage;
|
||||
s: WideString;
|
||||
begin
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtAbstractSpinBox.SignalEditingFinished');
|
||||
{$endif}
|
||||
FillChar(Msg, SizeOf(Msg), #0);
|
||||
{TODO: What message should be sended here ?!?
|
||||
problem:
|
||||
everything is fine when we work with mouse,or
|
||||
press TabKey to select next control, but if we
|
||||
connect OnKeyDown and say eg. VK_RETURN:SelectNext(ActiveControl, true, true)
|
||||
then spinedit text is always selected, nothing important but looks ugly.}
|
||||
// Msg.Msg := LM_EXIT;
|
||||
// DeliverMessage(Msg);
|
||||
end;
|
||||
|
||||
{ TQtFloatSpinBox }
|
||||
|
||||
function TQtFloatSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||||
var
|
||||
Parent: QWidgetH;
|
||||
begin
|
||||
// Creates the widget
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtFloatSpinBox.Create');
|
||||
{$endif}
|
||||
Parent := TQtWidget(LCLObject.Parent.Handle).Widget;
|
||||
Result := QDoubleSpinBox_create(Parent);
|
||||
end;
|
||||
|
||||
procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
|
||||
var
|
||||
Msg: TLMessage;
|
||||
begin
|
||||
FillChar(Msg, SizeOf(Msg), #0);
|
||||
Msg.Msg := CM_TEXTCHANGED;
|
||||
DeliverMessage(Msg);
|
||||
end;
|
||||
|
||||
{ TQtSpinBox }
|
||||
|
||||
function TQtSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||||
@ -2928,21 +3074,13 @@ begin
|
||||
Result := QSpinBox_create(Parent);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Function: TQtSpinBox.Destroy
|
||||
Params: None
|
||||
Returns: Nothing
|
||||
------------------------------------------------------------------------------}
|
||||
destructor TQtSpinBox.Destroy;
|
||||
procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
|
||||
var
|
||||
Msg: TLMessage;
|
||||
begin
|
||||
{$ifdef VerboseQt}
|
||||
WriteLn('TQtSpinBox.Destroy');
|
||||
{$endif}
|
||||
|
||||
QSpinBox_destroy(QSpinBoxH(Widget));
|
||||
Widget:=nil;
|
||||
|
||||
inherited Destroy;
|
||||
FillChar(Msg, SizeOf(Msg), #0);
|
||||
Msg.Msg := CM_TEXTCHANGED;
|
||||
DeliverMessage(Msg);
|
||||
end;
|
||||
|
||||
function TQtListWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||||
|
@ -2376,6 +2376,23 @@ begin
|
||||
{$Endif}
|
||||
end;
|
||||
|
||||
function TQtWidgetSet.RoundRect(DC : hDC; X1, Y1, X2, Y2: Integer; RX,RY : Integer): Boolean;
|
||||
var
|
||||
Painter: QPainterH;
|
||||
begin
|
||||
Result := False;
|
||||
if not IsValidDC(DC) then
|
||||
begin
|
||||
{$ifdef VerboseQTWinAPI}
|
||||
WriteLn('Trace:< [WinAPI RoundRect] DC Invalid, result=', result);
|
||||
{$Endif}
|
||||
exit;
|
||||
end;
|
||||
|
||||
Painter := TQtDeviceContext(Dc).Widget;
|
||||
QPainter_drawRoundRect(Painter, X1, Y1, X2, Y2, RX, RY);
|
||||
Result := True;
|
||||
end;
|
||||
{------------------------------------------------------------------------------
|
||||
Function: SaveDC: save DC state information to a stack
|
||||
Params: DC
|
||||
|
@ -92,6 +92,7 @@ function MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean; override;
|
||||
function Rectangle(DC: HDC; X1, Y1, X2, Y2: Integer): Boolean; override;
|
||||
function ReleaseDC(hWnd: HWND; DC: HDC): Integer; override;
|
||||
function RestoreDC(DC: HDC; SavedDC: Integer): Boolean; override;
|
||||
function RoundRect(DC : hDC; X1, Y1, X2, Y2: Integer; RX,RY : Integer): Boolean; override;
|
||||
|
||||
function SaveDC(DC: HDC): Integer; override;
|
||||
function SelectClipRGN(DC : hDC; RGN : HRGN) : Longint; override;
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
unit QtWSSpin;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$mode delphi}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
@ -30,7 +30,7 @@ uses
|
||||
// Bindings
|
||||
qt4, qtwidgets,
|
||||
// LCL
|
||||
Spin, SysUtils, Controls, LCLType, Forms,
|
||||
Spin, SysUtils, Controls, Classes, LCLType, LCLProc, LCLIntf, Forms,
|
||||
// Widgetset
|
||||
WSSpin, WSLCLClasses;
|
||||
|
||||
@ -45,6 +45,22 @@ type
|
||||
class function CreateHandle(const AWinControl: TWinControl;
|
||||
const AParams: TCreateParams): HWND; override;
|
||||
class procedure DestroyHandle(const AWinControl: TWinControl); override;
|
||||
class function GetValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): single; override;
|
||||
class procedure UpdateControl(const ACustomFloatSpinEdit: TCustomFloatSpinEdit); override;
|
||||
(*
|
||||
class function GetSelStart(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): integer; virtual;
|
||||
class function GetSelLength(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): integer; virtual;
|
||||
|
||||
class procedure SetSelStart(const ACustomFloatSpinEdit: TCustomFloatSpinEdit; NewStart: integer); virtual;
|
||||
class procedure SetSelLength(const ACustomFloatSpinEdit: TCustomFloatSpinEdit; NewLength: integer); virtual;
|
||||
|
||||
TODO: seperation into properties instead of bulk update
|
||||
class procedure SetIncrement(const ACustomFloatSpinEdit: TCustomFloatSpinEdit; NewIncrement: single); virtual;
|
||||
class procedure SetMinValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit; NewValue: single); virtual;
|
||||
class procedure SetMaxValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit; NewValue: single); virtual;
|
||||
class procedure SetValueEmpty(const ACustomFloatSpinEdit: TCustomFloatSpinEdit; NewEmpty: boolean); virtual;
|
||||
*)
|
||||
|
||||
end;
|
||||
|
||||
{ TQtWSFloatSpinEdit }
|
||||
@ -69,11 +85,50 @@ class function TQtWSCustomFloatSpinEdit.CreateHandle(const AWinControl: TWinCont
|
||||
const AParams: TCreateParams): HWND;
|
||||
var
|
||||
QtSpinBox: TQtSpinBox;
|
||||
QtFloatSpinBox: TQtFloatSpinBox;
|
||||
Hook: QAbstractSpinBox_hookH;
|
||||
Method: TMethod;
|
||||
FIsFloat: Boolean;
|
||||
begin
|
||||
QtSpinBox := TQtSpinBox.Create(AWinControl, AParams);
|
||||
|
||||
// SetSlots(QtSpinBox);
|
||||
{qt4 have two different QSpinBoxes, one is QSpinBox (integer), another is QDoubleSpinBox (double) }
|
||||
|
||||
FIsFloat := TCustomFloatSpinEdit(AWinControl).DecimalPlaces > 0;
|
||||
|
||||
if FIsFloat then
|
||||
QtFloatSpinBox := TQtFloatSpinBox.Create(AWinControl, AParams)
|
||||
else
|
||||
QtSpinBox := TQtSpinBox.Create(AWinControl, AParams);
|
||||
|
||||
if FIsFloat then
|
||||
begin
|
||||
Hook := QAbstractSpinBox_hook_create(QtFloatSpinBox.Widget);
|
||||
TEventFilterMethod(Method) := QtFloatSpinBox.EventFilter;
|
||||
QObject_hook_hook_events(Hook, Method);
|
||||
{TODO: what TLMessage should be sended ? }
|
||||
QAbstractSpinBox_editingFinished_Event(Method) := QtFloatSpinBox.SignalEditingFinished;
|
||||
QAbstractSpinBox_hook_hook_editingFinished(QAbstractSpinBox_hook_create(QtFloatSpinBox.Widget), Method);
|
||||
|
||||
QDoubleSpinBox_valueChanged_Event(Method) := QtFloatSpinBox.SignalValueChanged;
|
||||
QDoubleSpinBox_hook_hook_valueChanged(QDoubleSpinBox_hook_create(QtFloatSpinBox.Widget), Method);
|
||||
|
||||
end else
|
||||
begin
|
||||
Hook := QAbstractSpinBox_hook_create(QtSpinBox.Widget);
|
||||
TEventFilterMethod(Method) := QtSpinBox.EventFilter;
|
||||
QObject_hook_hook_events(Hook, Method);
|
||||
{TODO: what TLMessage should be sended ? }
|
||||
QAbstractSpinBox_editingFinished_Event(Method) := QtSpinBox.SignalEditingFinished;
|
||||
QAbstractSpinBox_hook_hook_editingFinished(QAbstractSpinBox_hook_create(QtSpinBox.Widget), Method);
|
||||
|
||||
QSpinBox_valueChanged_Event(Method) := QtSpinBox.SignalValueChanged;
|
||||
QSpinBox_hook_hook_valueChanged(QSpinBox_hook_create(QtSpinBox.Widget), Method);
|
||||
end;
|
||||
|
||||
|
||||
if FIsFloat then
|
||||
Result := THandle(QtFloatSpinBox)
|
||||
else
|
||||
Result := THandle(QtSpinBox);
|
||||
end;
|
||||
|
||||
@ -84,11 +139,48 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
class procedure TQtWSCustomFloatSpinEdit.DestroyHandle(const AWinControl: TWinControl);
|
||||
begin
|
||||
|
||||
if TCustomFloatSpinEdit(AWinControl).DecimalPlaces > 0 then
|
||||
TQtFloatSpinBox(AWinControl.Handle).Free
|
||||
else
|
||||
TQtSpinBox(AWinControl.Handle).Free;
|
||||
|
||||
AWinControl.Handle := 0;
|
||||
end;
|
||||
|
||||
class function TQtWSCustomFloatSpinEdit.GetValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): single;
|
||||
begin
|
||||
if ACustomFloatSpinEdit.DecimalPlaces > 0 then
|
||||
Result := QDoubleSpinBox_value(QDoubleSpinBoxH(TQtFloatSpinBox(ACustomFloatSpinEdit.Handle).Widget))
|
||||
else
|
||||
Result := QSpinBox_value(QSpinBoxH(TQtFloatSpinBox(ACustomFloatSpinEdit.Handle).Widget));
|
||||
end;
|
||||
|
||||
class procedure TQtWSCustomFloatSpinEdit.UpdateControl(const ACustomFloatSpinEdit: TCustomFloatSpinEdit);
|
||||
var
|
||||
QtSpinEdit: TQtSpinBox;
|
||||
QtFloatSpinEdit: TQtFloatSpinBox;
|
||||
begin
|
||||
|
||||
if ACustomFloatSpinEdit.DecimalPlaces > 0 then
|
||||
begin
|
||||
QtFloatSpinEdit := TQtFloatSpinBox(ACustomFloatSpinEdit.Handle);
|
||||
QDoubleSpinBox_setDecimals(QDoubleSpinBoxH(QtFloatSpinEdit.Widget), ACustomFloatSpinEdit.DecimalPlaces);
|
||||
QDoubleSpinBox_setValue(QDoubleSpinBoxH(QtFloatSpinEdit.Widget), ACustomFloatSpinEdit.Value);
|
||||
QDoubleSpinBox_setMinimum(QDoubleSpinBoxH(QtFloatSpinEdit.Widget), ACustomFloatSpinEdit.MinValue);
|
||||
QDoubleSpinBox_setMaximum(QDoubleSpinBoxH(QtFloatSpinEdit.Widget), ACustomFloatSpinEdit.MaxValue);
|
||||
QDoubleSpinBox_setSingleStep(QDoubleSpinBoxH(QtFloatSpinEdit.Widget), ACustomFloatSpinEdit.Increment);
|
||||
end else
|
||||
begin
|
||||
QtSpinEdit := TQtSpinBox(ACustomFloatSpinEdit.Handle);
|
||||
QSpinBox_setValue(QSpinBoxH(QtSpinEdit.Widget), Round(ACustomFloatSpinEdit.Value));
|
||||
QSpinBox_setMinimum(QSpinBoxH(QtSpinEdit.Widget), Round(ACustomFloatSpinEdit.MinValue));
|
||||
QSpinBox_setMaximum(QSpinBoxH(QtSpinEdit.Widget), Round(ACustomFloatSpinEdit.MaxValue));
|
||||
QSpinBox_setSingleStep(QSpinBoxH(QtSpinEdit.Widget), Round(ACustomFloatSpinEdit.Increment));
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -461,6 +461,7 @@ end;
|
||||
class procedure TQtWSCustomListBox.DestroyHandle(const AWinControl: TWinControl);
|
||||
begin
|
||||
TQtListWidget(AWinControl.Handle).Free;
|
||||
AWinControl.Handle := 0;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -591,8 +592,22 @@ class function TQtWSCustomMemo.CreateHandle(const AWinControl: TWinControl;
|
||||
const AParams: TCreateParams): HWND;
|
||||
var
|
||||
QtTextEdit: TQtTextEdit;
|
||||
Method: TMethod;
|
||||
Hook : QTextEdit_hookH;
|
||||
begin
|
||||
QtTextEdit := TQtTextEdit.Create(AWinControl, AParams);
|
||||
|
||||
Hook := QTextEdit_hook_create(QtTextEdit.Widget);
|
||||
|
||||
TEventFilterMethod(Method) := QtTextEdit.EventFilter;
|
||||
|
||||
QObject_hook_hook_events(Hook, Method);
|
||||
|
||||
{TODO: BUG CopyUnicodeToPWideString() segfaults while calling SetLength()
|
||||
workaround: add try..except around SetLength() }
|
||||
QTextEdit_textChanged_Event(Method) := QtTextEdit.SignalTextChanged;
|
||||
QTextEdit_hook_hook_textChanged(QTextEdit_hook_create(QtTextEdit.Widget), Method);
|
||||
|
||||
Result := THandle(QtTextEdit);
|
||||
end;
|
||||
|
||||
@ -728,6 +743,11 @@ begin
|
||||
TEventFilterMethod(Method) := QtLineEdit.EventFilter;
|
||||
|
||||
QObject_hook_hook_events(Hook, Method);
|
||||
|
||||
{TODO: BUG CopyUnicodeToPWideString() segfaults while calling SetLength()
|
||||
workaround: add try..except around SetLength() }
|
||||
QLineEdit_textChanged_Event(Method) := QtLineEdit.SignalTextChanged;
|
||||
QLineEdit_hook_hook_textChanged(QLineEdit_hook_create(QtLineEdit.Widget), Method);
|
||||
|
||||
Result := THandle(QtLineEdit);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user