mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 21:38:27 +02:00
1407 lines
49 KiB
ObjectPascal
1407 lines
49 KiB
ObjectPascal
unit QtThemes;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
{$I qtdefines.inc}
|
|
|
|
uses
|
|
// rtl
|
|
Types, Classes, SysUtils,
|
|
// qt bindings
|
|
qt5,
|
|
// LazUtils
|
|
LazLoggerBase,
|
|
// lcl
|
|
LCLType, LCLIntf, Graphics, Themes, TmSchema,
|
|
// widgetset
|
|
InterfaceBase, QtObjects
|
|
;
|
|
|
|
type
|
|
TQtDrawVariant =
|
|
(
|
|
qdvNone,
|
|
qdvPrimitive,
|
|
qdvControl,
|
|
qdvComplexControl,
|
|
qdvStandardPixmap
|
|
);
|
|
TQtDrawElement = record
|
|
case DrawVariant: TQtDrawVariant of
|
|
qdvPrimitive:
|
|
(PrimitiveElement: QStylePrimitiveElement);
|
|
qdvControl:
|
|
(ControlElement: QStyleControlElement);
|
|
qdvComplexControl:
|
|
(ComplexControl: QStyleComplexControl;
|
|
SubControls: QStyleSubControls;
|
|
Features: Cardinal);
|
|
qdvStandardPixmap:
|
|
(StandardPixmap: QStyleStandardPixmap);
|
|
end;
|
|
|
|
{ TQtThemeServices }
|
|
|
|
TQtThemeServices = class(TThemeServices)
|
|
private
|
|
FStyle: QStyleH;
|
|
function GetStyle: QStyleH;
|
|
function GetStyleName: WideString;
|
|
protected
|
|
function InitThemes: Boolean; override;
|
|
function UseThemes: Boolean; override;
|
|
function ThemedControlsEnabled: Boolean; override;
|
|
procedure InternalDrawParentBackground(Window: HWND; Target: HDC; Bounds: PRect); override;
|
|
|
|
function GetControlState(Details: TThemedElementDetails): QStyleState;
|
|
function GetDrawElement(Details: TThemedElementDetails): TQtDrawElement;
|
|
property Style: QStyleH read GetStyle;
|
|
property StyleName: WideString read GetStyleName;
|
|
public
|
|
procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; ClipRect: PRect); override;
|
|
procedure DrawEdge(DC: HDC; Details: TThemedElementDetails; const R: TRect; Edge, Flags: Cardinal; AContentRect: PRect); override;
|
|
procedure DrawIcon(DC: HDC; Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST; Index: Integer); override;
|
|
procedure DrawText(ACanvas: TPersistent; Details: TThemedElementDetails; const S: String; R: TRect; Flags, Flags2: Cardinal); overload; override;
|
|
procedure DrawText(DC: HDC; Details: TThemedElementDetails; const S: String; R: TRect; Flags, Flags2: Cardinal); overload; override;
|
|
function GetDetailSize(Details: TThemedElementDetails): TSize; override;
|
|
function GetDetailSizeForPPI(Details: TThemedElementDetails; PPI: Integer): TSize; override;
|
|
function GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; override;
|
|
|
|
function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; override;
|
|
function HasTransparentParts(Details: TThemedElementDetails): Boolean; override;
|
|
end;
|
|
|
|
implementation
|
|
uses qtint, qtproc;
|
|
|
|
{ TQtThemeServices }
|
|
|
|
function TQtThemeServices.GetStyle: QStyleH;
|
|
begin
|
|
FStyle := QApplication_style();
|
|
Result := FStyle;
|
|
end;
|
|
|
|
function TQtThemeServices.GetStyleName: WideString;
|
|
begin
|
|
QObject_objectName(Style, @Result);
|
|
end;
|
|
|
|
function TQtThemeServices.InitThemes: Boolean;
|
|
begin
|
|
FStyle := nil;
|
|
Result := True;
|
|
end;
|
|
|
|
function TQtThemeServices.UseThemes: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TQtThemeServices.ThemedControlsEnabled: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TQtThemeServices.ContentRect(DC: HDC;
|
|
Details: TThemedElementDetails; BoundingRect: TRect): TRect;
|
|
begin
|
|
Result := BoundingRect;
|
|
InflateRect(Result, -1, -1);
|
|
end;
|
|
|
|
procedure TQtThemeServices.DrawEdge(DC: HDC;
|
|
Details: TThemedElementDetails; const R: TRect; Edge, Flags: Cardinal;
|
|
AContentRect: PRect);
|
|
begin
|
|
//DebugLn('WARNING: TQtThemeServices.DrawEdge is not implemented.');
|
|
end;
|
|
|
|
procedure TQtThemeServices.DrawElement(DC: HDC;
|
|
Details: TThemedElementDetails; const R: TRect; ClipRect: PRect);
|
|
var
|
|
Context: TQtDeviceContext absolute DC;
|
|
opt: QStyleOptionH;
|
|
ARect: TRect;
|
|
AIcon: QIconH;
|
|
Element: TQtDrawElement;
|
|
Features: QStyleOptionButtonButtonFeatures;
|
|
Position: QStyleOptionHeaderSectionPosition;
|
|
Palette: QPaletteH;
|
|
ABrush: QBrushH;
|
|
Widget: QWidgetH;
|
|
AViewportPaint: Boolean;
|
|
StyleState: QStyleState;
|
|
{$IFDEF DARWIN}
|
|
ClipR: TRect; // fix branch indicators (treeviews)
|
|
{$ENDIF}
|
|
dx, dy: integer;
|
|
APalette: QPaletteH;
|
|
W: WideString;
|
|
ABgColor: TQColor;
|
|
Alpha: Word;
|
|
|
|
procedure DrawSplitterInternal;
|
|
var
|
|
lx, ly, d, lt, i: Integer;
|
|
r1: TRect;
|
|
AQtColor: QColorH;
|
|
ADarkColor, ALightColor: TQColor;
|
|
APalette: QPaletteH;
|
|
NumDots: integer;
|
|
APen: QPenH;
|
|
begin
|
|
r1 := ARect;
|
|
NumDots := 10;
|
|
APalette := QPalette_create;
|
|
try
|
|
QStyleOption_palette(opt, APalette);
|
|
AQtColor := QColor_create(QBrush_color(QPalette_background(APalette)));
|
|
|
|
QColor_darker(AQtColor, @ADarkColor);
|
|
QColor_lighter(AQtColor, @ALightColor);
|
|
|
|
if StyleState and QStyleState_Horizontal = 0 then
|
|
begin
|
|
if (r1.Right - r1.Left) <= (NumDots * 2) then
|
|
NumDots := (r1.Right - r1.Left) div 2;
|
|
lx := ((r1.Right - r1.Left) div 2) - (NumDots * 2);
|
|
d := (r1.Bottom - r1.Top - 2) div 2;
|
|
lt := r1.Top + d + 1;
|
|
APen := QPen_create(QPainter_pen(Context.Widget));
|
|
for i := 0 to NumDots - 1 do
|
|
begin
|
|
QPen_setColor(APen, PQColor(@ALightColor));
|
|
QPainter_setPen(Context.Widget, APen);
|
|
QPainter_drawPoint(Context.Widget, lx, lt);
|
|
QPen_setColor(APen, PQColor(@ADarkColor));
|
|
QPainter_setPen(Context.Widget, APen);
|
|
QPainter_drawPoint(Context.Widget, lx + 1, lt);
|
|
QPainter_drawPoint(Context.Widget, lx, lt + 1);
|
|
QPainter_drawPoint(Context.Widget, lx + 1, lt + 1);
|
|
lx := lx + 4;
|
|
end;
|
|
QPen_destroy(APen);
|
|
end else
|
|
begin
|
|
if (r1.Bottom - r1.Top) <= (NumDots * 2) then
|
|
NumDots := (r1.Bottom - r1.Top) div 2;
|
|
ly := ((r1.Bottom - r1.Top) div 2) + (NumDots * 2);
|
|
d := (r1.Right - r1.Left - 2) div 2;
|
|
lt := r1.Left + d + 1;
|
|
APen := QPen_create(QPainter_pen(Context.Widget));
|
|
for i := 0 to NumDots - 1 do
|
|
begin
|
|
QPen_setColor(APen, PQColor(@ALightColor));
|
|
QPainter_setPen(Context.Widget, APen);
|
|
QPainter_drawPoint(Context.Widget, lt, ly);
|
|
QPen_setColor(APen, PQColor(@ADarkColor));
|
|
QPainter_setPen(Context.Widget, APen);
|
|
QPainter_drawPoint(Context.Widget, lt + 1, ly);
|
|
QPainter_drawPoint(Context.Widget, lt, ly + 1);
|
|
QPainter_drawPoint(Context.Widget, lt + 1, ly + 1);
|
|
ly := ly - 4;
|
|
end;
|
|
QPen_destroy(APen);
|
|
end;
|
|
finally
|
|
QPalette_destroy(APalette);
|
|
QColor_destroy(AQtColor);
|
|
end;
|
|
end;
|
|
begin
|
|
if (Context <> nil) and not IsRectEmpty(R) then
|
|
begin
|
|
AViewportPaint := False;
|
|
Context.save;
|
|
try
|
|
if Context.Parent <> nil then
|
|
begin
|
|
Widget := QWidget_parentWidget(Context.Parent);
|
|
if (Widget <> nil) and QObject_inherits(Widget,'QAbstractScrollArea') then
|
|
begin
|
|
{do not set any palette on QAbstractScrollArea viewport ! }
|
|
AViewportPaint := True;
|
|
end else
|
|
begin
|
|
Palette := QWidget_palette(Context.Parent);
|
|
QPainter_setBackground(Context.Widget, QPalette_background(Palette));
|
|
end;
|
|
end else
|
|
begin
|
|
Palette := QPalette_create();
|
|
QGUIApplication_palette(Palette);
|
|
QPainter_setBackground(Context.Widget, QPalette_background(Palette));
|
|
QPalette_destroy(Palette);
|
|
end;
|
|
|
|
if HasTransparentParts(Details) then
|
|
QPainter_setBackgroundMode(Context.Widget, QtTransparentMode);
|
|
|
|
ARect := R;
|
|
Element := GetDrawElement(Details);
|
|
StyleState := GetControlState(Details);
|
|
case Element.DrawVariant of
|
|
qdvNone:
|
|
inherited DrawElement(DC, Details, R, ClipRect);
|
|
qdvControl:
|
|
begin
|
|
if (Element.ControlElement in [QStyleCE_ProgressBar, QStyleCE_ProgressBarContents,
|
|
QStyleCE_ProgressBarGroove]) then
|
|
begin
|
|
opt := QStyleOptionProgressBar_create;
|
|
|
|
if Element.ControlElement <> QStyleCE_ProgressBarContents then
|
|
begin
|
|
QStyleOptionProgressBar_setMinimum(QStyleOptionProgressBarH(opt), 0);
|
|
QStyleOptionProgressBar_setMaximum(QStyleOptionProgressBarH(opt), 100);
|
|
end;
|
|
|
|
if Element.Features = QtVertical then
|
|
begin
|
|
QStyleOptionProgressBar_setOrientation(QStyleOptionProgressBarH(opt), QtVertical);
|
|
QStyleOptionProgressBar_setInvertedAppearance(QStyleOptionProgressBarH(opt), True);
|
|
QStyleOptionProgressBar_setBottomToTop(QStyleOptionProgressBarH(opt), True);
|
|
end else
|
|
QStyleOptionProgressBar_setOrientation(QStyleOptionProgressBarH(opt), QtHorizontal);
|
|
end else
|
|
if (Element.ControlElement = QStyleCE_TabBarTabShape) then
|
|
begin
|
|
opt := QStyleOptionTab_create();
|
|
QStyleOptionTab_setShape(QStyleOptionTabH(opt), QTabBarShape(Element.Features));
|
|
end else
|
|
if (Element.ControlElement in [QStyleCE_PushButton, QStyleCE_RadioButton, QStyleCE_CheckBox]) then
|
|
begin
|
|
opt := QStyleOptionButton_create();
|
|
Features := QStyleOptionButtonNone;
|
|
if Details.Element = teToolBar then
|
|
Features := Features or QStyleOptionButtonFlat;
|
|
QStyleOptionButton_setFeatures(QStyleOptionButtonH(opt), Features);
|
|
|
|
// workaround for qt QStyle bug. QStyle does not set disable flag (palette).
|
|
// see issue #24413,#26586
|
|
if Details.State in [CBS_UNCHECKEDDISABLED,CBS_CHECKEDDISABLED,CBS_MIXEDDISABLED] then
|
|
begin
|
|
APalette := QPalette_create();
|
|
try
|
|
QStyleOption_palette(opt, APalette);
|
|
QPalette_setCurrentColorGroup(APalette, QPaletteDisabled);
|
|
QStyleOption_setPalette(opt, APalette);
|
|
finally
|
|
QPalette_destroy(APalette);
|
|
end;
|
|
end;
|
|
end else
|
|
if (Element.ControlElement = QStyleCE_HeaderSection) then
|
|
begin
|
|
opt := QStyleOptionHeader_create();
|
|
case Details.Part of
|
|
HP_HEADERITEM: Position := QStyleOptionHeaderMiddle;
|
|
HP_HEADERITEMLEFT: Position := QStyleOptionHeaderBeginning;
|
|
HP_HEADERITEMRIGHT: Position := QStyleOptionHeaderEnd;
|
|
end;
|
|
|
|
W := GetStyleName;
|
|
// fix for oxygen and breeze weird drawing of header sections. issue #23143
|
|
if ((W = 'oxygen') or (W = 'breeze')) and (Position = QStyleOptionHeaderMiddle) then
|
|
begin
|
|
// see if this is needed (in case of fixedRows in grids)
|
|
// if (ARect.Left > 0) or ((ARect.Left = 0) and (ARect.Top = 0)) then
|
|
Position := QStyleOptionHeaderBeginning;
|
|
end;
|
|
|
|
QStyleOptionHeader_setPosition(QStyleOptionHeaderH(opt), Position);
|
|
QStyleOptionHeader_setOrientation(QStyleOptionHeaderH(opt), QtHorizontal);
|
|
end
|
|
else
|
|
if (Element.ControlElement = QStyleCE_ItemViewItem) then
|
|
begin
|
|
opt := QStyleOptionViewItem_create();
|
|
QStyleOptionViewItem_setShowDecorationSelected(QStyleOptionViewItemH(opt), True);
|
|
end
|
|
else
|
|
if (Element.ControlElement = QStyleCE_SizeGrip) then
|
|
begin
|
|
opt := QStyleOptionSizeGrip_create();
|
|
QStyleOptionSizeGrip_setCorner(QStyleOptionSizeGripH(opt), QtBottomRightCorner);
|
|
QStyleOption_setDirection(QStyleOptionH(opt), QtLeftToRight);
|
|
end
|
|
else
|
|
opt := QStyleOptionComplex_create(LongInt(QStyleOptionVersion), LongInt(QStyleOptionSO_Default));
|
|
|
|
QStyleOption_setState(opt, StyleState);
|
|
dx := ARect.Left;
|
|
dy := ARect.Top;
|
|
Context.translate(dx, dy);
|
|
Types.OffsetRect(ARect, -dx, -dy);
|
|
QStyleOption_setRect(opt, @ARect);
|
|
|
|
// issue #27182 qt5 does not implement splitter grabber in some themes.
|
|
if (Element.ControlElement = QStyleCE_Splitter) and
|
|
( (GetStyleName = 'windows') or (GetStyleName = 'breeze')
|
|
{$IFDEF MSWINDOWS} or true {$ENDIF}) then
|
|
drawSplitterInternal
|
|
else
|
|
QStyle_drawControl(Style, Element.ControlElement, opt, Context.Widget, Context.Parent);
|
|
|
|
Context.translate(-dx, -dy);
|
|
QStyleOption_Destroy(opt);
|
|
end;
|
|
qdvComplexControl:
|
|
begin
|
|
case Element.ComplexControl of
|
|
QStyleCC_GroupBox:
|
|
begin
|
|
opt := QStyleOptionGroupBox_create();
|
|
Context.translate(ARect.Left, ARect.Top);
|
|
Types.OffsetRect(ARect, -ARect.Left, -ARect.Top);
|
|
end;
|
|
QStyleCC_ToolButton:
|
|
begin
|
|
opt := QStyleOptionToolButton_create();
|
|
QStyleOptionToolButton_setFeatures(QStyleOptionToolButtonH(opt),
|
|
Element.Features);
|
|
end;
|
|
QStyleCC_ComboBox:
|
|
begin
|
|
opt := QStyleOptionComboBox_create();
|
|
if Element.Features = Ord(QtRightToLeft) then
|
|
QStyleOption_setDirection(opt, QtRightToLeft);
|
|
if Details.State in [CBXS_DISABLED] then
|
|
begin
|
|
APalette := QPalette_create();
|
|
try
|
|
QStyleOption_palette(opt, APalette);
|
|
QPalette_setCurrentColorGroup(APalette, QPaletteDisabled);
|
|
QStyleOption_setPalette(opt, APalette);
|
|
finally
|
|
QPalette_destroy(APalette);
|
|
end;
|
|
end;
|
|
end;
|
|
QStyleCC_SpinBox:
|
|
begin
|
|
opt := QStyleOptionSpinBox_create;
|
|
end;
|
|
QStyleCC_TitleBar, QStyleCC_MdiControls:
|
|
begin
|
|
opt := QStyleOptionTitleBar_create();
|
|
if Element.SubControls = QStyleSC_TitleBarLabel then
|
|
QStyleOptionTitleBar_setTitleBarFlags(QStyleOptionTitleBarH(opt),
|
|
QtWindow or QtWindowTitleHint)
|
|
else
|
|
QStyleOptionTitleBar_setTitleBarFlags(QStyleOptionTitleBarH(opt),
|
|
QtWindow or QtWindowSystemMenuHint);
|
|
// workaround: qt has own minds about position of requested part -
|
|
// but we need a way to draw it at our position
|
|
Context.translate(ARect.Left, ARect.Top);
|
|
Types.OffsetRect(ARect, -ARect.Left, -ARect.Top);
|
|
end;
|
|
QStyleCC_Slider, QStyleCC_ScrollBar:
|
|
begin
|
|
opt := QStyleOptionSlider_create();
|
|
QStyleOptionSlider_setMinimum(QStyleOptionSliderH(opt), 0);
|
|
QStyleOptionSlider_setMaximum(QStyleOptionSliderH(opt), 100);
|
|
if Element.ComplexControl = QStyleCC_Slider then
|
|
begin
|
|
if Element.Features = QtVertical then
|
|
QStyleOptionSlider_setOrientation(QStyleOptionSliderH(opt), QtVertical)
|
|
else
|
|
QStyleOptionSlider_setOrientation(QStyleOptionSliderH(opt), QtHorizontal);
|
|
end;
|
|
end;
|
|
else
|
|
opt := QStyleOptionComplex_create(LongInt(QStyleOptionVersion),
|
|
LongInt(QStyleOptionSO_Default));
|
|
end;
|
|
|
|
if Element.SubControls > QStyleSC_None then
|
|
QStyleOptionComplex_setSubControls(QStyleOptionComplexH(opt),
|
|
Element.SubControls);
|
|
|
|
QStyleOption_setState(opt, StyleState);
|
|
QStyleOption_setRect(opt, @ARect);
|
|
QStyle_drawComplexControl(Style, Element.ComplexControl,
|
|
QStyleOptionComplexH(opt), Context.Widget, Context.Parent);
|
|
QStyleOption_Destroy(opt);
|
|
end;
|
|
qdvPrimitive:
|
|
begin
|
|
case Element.PrimitiveElement of
|
|
QStylePE_FrameTabWidget:
|
|
begin
|
|
opt := QStyleOptionTabWidgetFrame_create();
|
|
// need widget to draw gradient
|
|
end;
|
|
QStylePE_FrameTabBarBase:
|
|
begin
|
|
opt := QStyleOptionTabBarBase_Create();
|
|
end;
|
|
QStylePE_FrameFocusRect:
|
|
begin
|
|
opt := QStyleOptionFocusRect_create();
|
|
end;
|
|
QStylePE_PanelTipLabel:
|
|
begin
|
|
opt := QStyleOptionFrame_create();
|
|
end;
|
|
QStylePE_FrameLineEdit:
|
|
begin
|
|
opt := QStyleOptionFrame_create();
|
|
end;
|
|
|
|
QStylePE_PanelButtonTool:
|
|
begin
|
|
opt := QStyleOption_create(Ord(QStyleOptionVersion), Ord(QStyleOptionSO_Default));
|
|
|
|
//issue #38356 - when button is in hot state bg color should be same as parent color.
|
|
if Assigned(Context.Parent) and
|
|
(StyleState and QStyleState_MouseOver <> 0) and (StyleState and QStyleState_AutoRaise = 0) then
|
|
begin
|
|
ABgColor := QBrush_color(QPainter_brush(Context.Widget))^;
|
|
Alpha := ABgColor.Alpha;
|
|
APalette := QPalette_Create(QWidget_palette(Context.Parent));
|
|
ColorRefToTQColor(ColorToRGB(Context.GetBkColor), ABgColor);
|
|
|
|
//issue #38356 additional fix for non initialized brush color in QPainter
|
|
if (ABGColor.r = MAXWORD) and (ABGColor.g = MAXWORD) and (ABGColor.b = MAXWORD) and
|
|
(ABGColor.Alpha = MAXWORD) and (QPainter_backgroundMode(Context.Widget) = QtTransparentMode) then
|
|
begin
|
|
QPalette_destroy(APalette);
|
|
APalette := QPalette_Create();
|
|
QStyleOption_palette(opt, APalette);
|
|
ABgColor := QBrush_color(QPalette_button(APalette))^;
|
|
end;
|
|
|
|
ABgColor.Alpha := Alpha;
|
|
ABrush := QBrush_create(PQColor(@ABgColor));
|
|
QPalette_setBrush(APalette, QPaletteAll, QPaletteButton, ABrush);
|
|
QStyleOption_setPalette(opt, APalette);
|
|
QBrush_destroy(ABrush);
|
|
QPalette_destroy(APalette);
|
|
end;
|
|
end;
|
|
|
|
QStylePE_IndicatorBranch:
|
|
begin
|
|
|
|
opt := QStyleOption_create(Ord(QStyleOptionVersion), Ord(QStyleOptionSO_Default));
|
|
|
|
QStyleOption_setState(opt, StyleState);
|
|
if AViewPortPaint then
|
|
begin
|
|
{$IFDEF DARWIN}
|
|
if (AnsiPos('macintosh', StyleName) > 0) and
|
|
Context.getClipping then
|
|
begin
|
|
ClipR := Context.getClipRegion.getBoundingRect;
|
|
if (ClipR.Left = 0) and (ClipR.Top = 0) and (ARect.Left > 0)
|
|
and (ARect.Top > 0) then
|
|
begin
|
|
ClipR.Left := (ARect.Right - ARect.Left + 1) div 3;
|
|
Types.OffsetRect(ARect, -ClipR.Left, -1);
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
Context.translate(-1, -1);
|
|
ABrush := QBrush_create(QPainter_brush(Context.Widget));
|
|
QBrush_setStyle(ABrush, QtNoBrush);
|
|
QPainter_setBrush(Context.Widget, ABrush);
|
|
QBrush_destroy(ABrush);
|
|
end;
|
|
end;
|
|
else
|
|
opt := QStyleOption_create(Ord(QStyleOptionVersion), Ord(QStyleOptionSO_Default));
|
|
end;
|
|
|
|
QStyleOption_setState(opt, StyleState);
|
|
QStyleOption_setRect(opt, @ARect);
|
|
QStyle_drawPrimitive(Style, Element.PrimitiveElement, opt, Context.Widget,
|
|
Context.Parent);
|
|
QStyleOption_Destroy(opt);
|
|
end;
|
|
qdvStandardPixmap:
|
|
begin
|
|
AIcon := QIcon_create();
|
|
if Element.StandardPixmap = QStyleSP_TitleBarCloseButton then
|
|
begin
|
|
opt := QStyleOptionDockWidget_create();
|
|
QStyle_standardIcon(Style, AIcon, Element.StandardPixmap, opt, Context.Parent);
|
|
end
|
|
else
|
|
begin
|
|
opt := QStyleOption_create(Ord(QStyleOptionVersion), Ord(QStyleOptionSO_Default));
|
|
QStyle_standardIcon(Style, AIcon, Element.StandardPixmap, opt);
|
|
end;
|
|
QIcon_paint(AIcon, Context.Widget, ARect.Left, ARect.Top,
|
|
ARect.Right - ARect.Left, ARect.Bottom - ARect.Top);
|
|
QIcon_destroy(AIcon);
|
|
QStyleOption_Destroy(opt);
|
|
end;
|
|
end;
|
|
finally
|
|
Context.restore;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TQtThemeServices.DrawIcon(DC: HDC;
|
|
Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST;
|
|
Index: Integer);
|
|
begin
|
|
DebugLn('WARNING: TQtThemeServices.DrawIcon is not implemented.');
|
|
end;
|
|
|
|
procedure TQtThemeServices.DrawText(ACanvas: TPersistent;
|
|
Details: TThemedElementDetails; const S: String; R: TRect; Flags,
|
|
Flags2: Cardinal);
|
|
var
|
|
AQColor, AOldColor: TQColor;
|
|
B: Boolean;
|
|
OldCanvasFontColor: TColor;
|
|
APalette: QPaletteH;
|
|
begin
|
|
B := False;
|
|
|
|
// issue #25253
|
|
if (Details.Element in [teButton, teComboBox]) then
|
|
begin
|
|
B := True;
|
|
AOldColor := TQtDeviceContext(TCanvas(ACanvas).Handle).pen.getColor;
|
|
OldCanvasFontColor := TCanvas(ACanvas).Font.Color;
|
|
|
|
// issue #25922
|
|
if IsDisabled(Details) then
|
|
begin
|
|
APalette := QPalette_create;
|
|
try
|
|
QApplication_palette(APalette,'QPushButton');
|
|
AQColor := QPalette_color(APalette, QPaletteDisabled, QPaletteButtonText)^;
|
|
TQtDeviceContext(TCanvas(ACanvas).Handle).pen.setColor(AQColor);
|
|
finally
|
|
QPalette_destroy(APalette);
|
|
end;
|
|
end else
|
|
begin
|
|
if TCanvas(ACanvas).Font.Color = clDefault then
|
|
TCanvas(ACanvas).Font.Color := clBtnText;
|
|
ColorRefToTQColor(ColorToRGB(TCanvas(ACanvas).Font.Color), AQColor);
|
|
TQtDeviceContext(TCanvas(ACanvas).Handle).pen.setColor(AQColor);
|
|
end;
|
|
end;
|
|
|
|
DrawText(TCanvas(ACanvas).Handle, Details, S, R, Flags, Flags2);
|
|
|
|
if B then
|
|
begin
|
|
TQtDeviceContext(TCanvas(ACanvas).Handle).pen.setColor(AOldColor);
|
|
TCanvas(ACanvas).Font.Color := OldCanvasFontColor;
|
|
end;
|
|
end;
|
|
|
|
procedure TQtThemeServices.DrawText(DC: HDC; Details: TThemedElementDetails;
|
|
const S: String; R: TRect; Flags, Flags2: Cardinal);
|
|
var
|
|
Palette: QPaletteH;
|
|
Context: TQtDeviceContext;
|
|
Widget: QWidgetH;
|
|
W: WideString;
|
|
TextRect, SelRect: TRect;
|
|
AOldMode: Integer;
|
|
ATextPalette: Cardinal;
|
|
AQColor: TQColor;
|
|
begin
|
|
// DebugLn('TQtThemeServices.DrawText ');
|
|
Context := TQtDeviceContext(DC);
|
|
case Details.Element of
|
|
teToolTip:
|
|
begin
|
|
W := {%H-}S;
|
|
Context.save;
|
|
AOldMode := Context.SetBkMode(TRANSPARENT);
|
|
try
|
|
if Context.Parent <> nil then
|
|
Palette := QPalette_create(QWidget_palette(Context.Parent))
|
|
else
|
|
Palette := nil;
|
|
|
|
if Palette = nil then
|
|
begin
|
|
inherited;
|
|
exit;
|
|
end;
|
|
QStyle_drawItemText(Style, Context.Widget, @R,
|
|
DTFlagsToQtFlags(Flags), Palette,
|
|
not IsDisabled(Details), @W, QPaletteToolTipText);
|
|
QPalette_destroy(Palette);
|
|
finally
|
|
Context.SetBkMode(AOldMode);
|
|
Context.restore;
|
|
end;
|
|
|
|
end;
|
|
teTreeView, teListView:
|
|
begin
|
|
if Details.Part = TVP_TREEITEM then
|
|
begin
|
|
Palette := nil;
|
|
if Context.Parent <> nil then
|
|
begin
|
|
Widget := QWidget_parentWidget(Context.Parent);
|
|
if (Widget <> nil) and QObject_inherits(Widget,'QAbstractScrollArea') then
|
|
Palette := QPalette_create(QWidget_palette(Widget))
|
|
else
|
|
Palette := QPalette_create(QWidget_palette(Context.Parent));
|
|
end;
|
|
|
|
if Palette = nil then
|
|
begin
|
|
inherited;
|
|
exit;
|
|
end;
|
|
|
|
W := {%H-}S;
|
|
Context.save;
|
|
try
|
|
Context.SetBkMode(TRANSPARENT);
|
|
if Details.State = TREIS_DISABLED then
|
|
QPalette_setCurrentColorGroup(Palette, QPaletteDisabled)
|
|
else
|
|
if Details.State = TREIS_SELECTEDNOTFOCUS then
|
|
QPalette_setCurrentColorGroup(Palette, QPaletteInactive)
|
|
else
|
|
QPalette_setCurrentColorGroup(Palette, QPaletteActive);
|
|
|
|
if Details.State in
|
|
[TREIS_SELECTED, TREIS_HOTSELECTED, TREIS_SELECTEDNOTFOCUS] then
|
|
begin
|
|
// fix qt motif style behaviour which does not fillrect
|
|
// when drawing itemview if it doesn't have text
|
|
// assigned via QStyleViewItemViewV4_setText()
|
|
if Details.State = TREIS_SELECTED then
|
|
begin
|
|
if StyleName = 'motif' then
|
|
begin
|
|
TextRect := R;
|
|
with TextRect do
|
|
begin
|
|
Left := Left + 2;
|
|
Top := Top + 2;
|
|
Right := Right - 2;
|
|
Bottom := Bottom - 2;
|
|
end;
|
|
QPainter_fillRect(Context.Widget, @TextRect, QtSolidPattern);
|
|
end;
|
|
end;
|
|
{$IFDEF MSWINDOWS}
|
|
if StyleName = 'windowsvista' then // fix for text of selected treeitem.
|
|
begin
|
|
if (Palette <> nil) and (QPalette_currentColorGroup(Palette) = QPaletteActive) then
|
|
begin
|
|
AQColor := Default(TQColor);
|
|
ColorRefToTQColor(ColorToRGB(clWindowText), AQColor);
|
|
QPalette_setColor(Palette, QPaletteHighlightedText, PQColor(@AQColor));
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
QStyle_drawItemText(Style, Context.Widget, @R,
|
|
DTFlagsToQtFlags(Flags), Palette,
|
|
not IsDisabled(Details), @W, QPaletteHighlightedText)
|
|
end else
|
|
QStyle_drawItemText(Style, Context.Widget, @R,
|
|
DTFlagsToQtFlags(Flags), Palette,
|
|
not IsDisabled(Details), @W, QPaletteText);
|
|
finally
|
|
Context.restore;
|
|
end;
|
|
QPalette_destroy(Palette);
|
|
end else
|
|
inherited;
|
|
end;
|
|
|
|
else
|
|
begin // default text drawing for all !
|
|
W := {%H-}S;
|
|
Context.save;
|
|
AOldMode := Context.SetBkMode(TRANSPARENT);
|
|
if Context.Parent <> nil then
|
|
Palette := QPalette_create(QWidget_palette(Context.Parent))
|
|
else
|
|
begin
|
|
Palette := QPalette_create;
|
|
QGUIApplication_palette(Palette);
|
|
end;
|
|
try
|
|
if Details.Element in [teButton, teComboBox] then
|
|
AQColor := TQtDeviceContext(DC).pen.getColor; // issue #25253
|
|
|
|
if Details.Element in [teEdit, teListView, teTreeView, teWindow] then
|
|
ATextPalette := QPaletteWindowText
|
|
else
|
|
if Details.Element in [teButton, teComboBox] then
|
|
ATextPalette := QPaletteButtonText
|
|
else
|
|
ATextPalette := QPaletteText;
|
|
|
|
if Details.Element in [teButton, teComboBox] then
|
|
QPalette_setColor(Palette, ATextPalette, @AQColor); // issue #25253
|
|
|
|
if Context.font.Angle <> 0 then
|
|
begin
|
|
Context.Translate(R.Left, R.Top);
|
|
Context.Rotate(-0.1 * Context.Font.Angle);
|
|
Types.OffsetRect(R, -R.Left, -R.Top);
|
|
end;
|
|
|
|
if (Details.Element = teEdit) then
|
|
begin
|
|
if IsDisabled(Details) then
|
|
QPalette_setCurrentColorGroup(Palette, QPaletteDisabled);
|
|
if GetControlState(Details) and QStyleState_Selected <> 0 then
|
|
begin
|
|
Context.font.Metrics.boundingRect(@SelRect, @R, DTFlagsToQtFlags(Flags), @W);
|
|
ColorRefToTQColor(ColorToRGB(clHighlight), AQColor);
|
|
QPainter_fillRect(Context.Widget, @SelRect, PQColor(@AQColor));
|
|
ATextPalette := QPaletteHighlightedText;
|
|
end;
|
|
end;
|
|
|
|
QStyle_drawItemText(Style, Context.Widget, @R,
|
|
DTFlagsToQtFlags(Flags), Palette,
|
|
not IsDisabled(Details), @W, ATextPalette);
|
|
|
|
if Context.font.Angle <> 0 then
|
|
begin
|
|
Context.Translate(-R.Left, -R.Top);
|
|
Context.Rotate(0.1 * Context.Font.Angle);
|
|
end;
|
|
Context.SetBkMode(AOldMode);
|
|
finally
|
|
QPalette_destroy(Palette);
|
|
Context.restore;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TQtThemeServices.HasTransparentParts(Details: TThemedElementDetails): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TQtThemeServices.InternalDrawParentBackground(Window: HWND;
|
|
Target: HDC; Bounds: PRect);
|
|
begin
|
|
// ?
|
|
end;
|
|
|
|
function TQtThemeServices.GetControlState(Details: TThemedElementDetails): QStyleState;
|
|
begin
|
|
{
|
|
QStyleState_None
|
|
QStyleState_Enabled
|
|
QStyleState_Raised
|
|
QStyleState_Sunken
|
|
QStyleState_Off
|
|
QStyleState_NoChange
|
|
QStyleState_On
|
|
QStyleState_DownArrow
|
|
QStyleState_Horizontal
|
|
QStyleState_HasFocus
|
|
QStyleState_Top
|
|
QStyleState_Bottom
|
|
QStyleState_FocusAtBorder
|
|
QStyleState_AutoRaise
|
|
QStyleState_MouseOver
|
|
QStyleState_UpArrow
|
|
QStyleState_Selected
|
|
QStyleState_Active
|
|
QStyleState_Open
|
|
QStyleState_Children
|
|
QStyleState_Item
|
|
QStyleState_Sibling
|
|
QStyleState_Editing
|
|
QStyleState_KeyboardFocusChange
|
|
QStyleState_ReadOnly
|
|
}
|
|
Result := QStyleState_None;
|
|
|
|
if not IsDisabled(Details) then
|
|
Result := Result or QStyleState_Enabled;
|
|
|
|
if IsHot(Details) then
|
|
Result := Result or QStyleState_MouseOver;
|
|
|
|
if IsPushed(Details) then
|
|
Result := Result or QStyleState_Sunken;
|
|
|
|
if IsMixed(Details) then
|
|
Result := Result or QStyleState_NoChange
|
|
else
|
|
if IsChecked(Details) then
|
|
Result := Result or QStyleState_On
|
|
else
|
|
Result := Result or QStyleState_Off;
|
|
|
|
|
|
if (Details.Element = teHeader) then
|
|
begin
|
|
if not IsPushed(Details) then
|
|
Result := Result or QStyleState_Raised;
|
|
if not IsDisabled(Details) and (Result and QStyleState_Off <> 0) then
|
|
Result := Result and not QStyleState_Off;
|
|
end;
|
|
|
|
// specific states
|
|
{when toolbar = flat, toolbar buttons should be flat too.}
|
|
if (Details.Element = teToolBar) and
|
|
(Details.State in [TS_NORMAL, TS_DISABLED]) then
|
|
Result := QStyleState_AutoRaise;
|
|
|
|
// define orientations
|
|
if ((Details.Element = teRebar) and (Details.Part = RP_GRIPPER)) or
|
|
((Details.Element = teToolBar) and (Details.Part = TP_SEPARATOR)) or
|
|
((Details.Element = teScrollBar) and (Details.Part in
|
|
[SBP_UPPERTRACKHORZ, SBP_LOWERTRACKHORZ, SBP_THUMBBTNHORZ, SBP_GRIPPERHORZ])) or
|
|
((Details.Element = teTrackbar) and not (Details.Part in
|
|
[TKP_TRACKVERT, TKP_THUMBVERT])) then
|
|
Result := Result or QStyleState_Horizontal;
|
|
|
|
if (Details.Element in [teTreeview, teListView]) then
|
|
begin
|
|
if (Details.Element = teTreeView) and
|
|
(Details.Part in [TVP_GLYPH, TVP_HOTGLYPH]) then
|
|
begin
|
|
Result := Result or QStyleState_Children;
|
|
if Details.State = GLPS_OPENED then
|
|
Result := Result or QStyleState_Open;
|
|
end else
|
|
if Details.Part in [TVP_TREEITEM] then
|
|
begin
|
|
Result := Result or QStyleState_Item;
|
|
case Details.State of
|
|
TREIS_SELECTED:
|
|
Result := Result or QStyleState_Selected or QStyleState_HasFocus or QStyleState_Active;
|
|
TREIS_SELECTEDNOTFOCUS:
|
|
Result := Result or QStyleState_Selected;
|
|
TREIS_HOTSELECTED:
|
|
Result := Result or QStyleState_Selected or QStyleState_MouseOver;
|
|
TREIS_HOT:
|
|
Result := Result or QStyleState_MouseOver;
|
|
end;
|
|
end;
|
|
end;
|
|
if (Details.Element = teTrackBar) then
|
|
begin
|
|
if Details.Part in [TKP_THUMB, TKP_THUMBVERT] then
|
|
begin
|
|
if Details.State in [TUS_PRESSED, TUS_HOT] then
|
|
Result := Result or QStyleState_Active or QStyleState_HasFocus or QStyleState_MouseOver;
|
|
end;
|
|
end;
|
|
if (Details.Element = teEdit) and (Details.Part in [EP_EDITTEXT, EP_BACKGROUND, EP_BACKGROUNDWITHBORDER]) then
|
|
begin
|
|
if Details.State = ETS_FOCUSED then
|
|
Result := Result or QStyleState_Active or QStyleState_Enabled or QStyleState_HasFocus;
|
|
|
|
if Details.State = ETS_HOT then
|
|
Result := Result or QStyleState_MouseOver
|
|
else
|
|
if Details.State = ETS_READONLY then
|
|
Result := Result or QStyleState_ReadOnly
|
|
else
|
|
if Details.State = ETS_SELECTED then
|
|
Result := Result or QStyleState_Selected;
|
|
end;
|
|
if (Details.Element = teWindow) then
|
|
begin
|
|
if Details.Part in [WP_SMALLCAPTION,
|
|
WP_FRAMELEFT,
|
|
WP_FRAMERIGHT,
|
|
WP_FRAMEBOTTOM,
|
|
WP_SMALLFRAMELEFT,
|
|
WP_SMALLFRAMERIGHT,
|
|
WP_SMALLFRAMEBOTTOM] then
|
|
begin
|
|
if Details.State = FS_ACTIVE then
|
|
Result := Result or QStyleState_Active or QStyleState_HasFocus;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TQtThemeServices.GetDetailSize(Details: TThemedElementDetails): TSize;
|
|
begin
|
|
Result := inherited;
|
|
end;
|
|
|
|
function TQtThemeServices.GetDetailSizeForPPI(Details: TThemedElementDetails;
|
|
PPI: Integer): TSize;
|
|
begin
|
|
case Details.Element of
|
|
teButton:
|
|
begin
|
|
if Details.Part = BP_CHECKBOX then
|
|
begin
|
|
Result.cy := QStyle_pixelMetric(Style, QStylePM_IndicatorHeight, nil, nil);
|
|
Result.cx := QStyle_pixelMetric(Style, QStylePM_IndicatorWidth, nil, nil);
|
|
if (Result.cx>0) then
|
|
Result.cx := MulDiv(Result.cx, PPI, ScreenInfo.PixelsPerInchX);
|
|
if (Result.cy>0) then
|
|
Result.cy := MulDiv(Result.cy, PPI, ScreenInfo.PixelsPerInchY);
|
|
end else
|
|
if Details.Part = BP_RADIOBUTTON then
|
|
begin
|
|
Result.cy := QStyle_pixelMetric(Style, QStylePM_ExclusiveIndicatorHeight, nil, nil);
|
|
Result.cx := QStyle_pixelMetric(Style, QStylePM_ExclusiveIndicatorWidth, nil, nil);
|
|
if (Result.cx>0) then
|
|
Result.cx := MulDiv(Result.cx, PPI, ScreenInfo.PixelsPerInchX);
|
|
if (Result.cy>0) then
|
|
Result.cy := MulDiv(Result.cy, PPI, ScreenInfo.PixelsPerInchY);
|
|
end else
|
|
Result := inherited;
|
|
end;
|
|
teRebar :
|
|
if Details.Part in [RP_GRIPPER, RP_GRIPPERVERT] then
|
|
Result := Size(-1, -1)
|
|
else
|
|
Result := inherited;
|
|
teTreeView:
|
|
begin
|
|
Result := inherited;
|
|
if Details.Part in [TVP_GLYPH, TVP_HOTGLYPH] then
|
|
begin
|
|
inc(Result.cx);
|
|
inc(Result.cy);
|
|
end;
|
|
end;
|
|
teToolBar:
|
|
if (Details.Part = TP_DROPDOWNBUTTON) or (Details.Part = TP_SPLITBUTTONDROPDOWN) then
|
|
begin
|
|
Result.cy := -1;
|
|
Result.cx := QStyle_pixelMetric(Style, QStylePM_MenuButtonIndicator, nil, nil);
|
|
if (Result.cx>0) then
|
|
Result.cx := MulDiv(Result.cx, PPI, ScreenInfo.PixelsPerInchX);
|
|
end else
|
|
Result := inherited;
|
|
else
|
|
Result := inherited;
|
|
end;
|
|
end;
|
|
|
|
function TQtThemeServices.GetStockImage(StockID: LongInt; out Image,
|
|
Mask: HBitmap): Boolean;
|
|
var
|
|
APixmap: QPixmapH;
|
|
AImage: QImageH;
|
|
AScaledImage: QImageH;
|
|
AStdPixmap: QStyleStandardPixmap;
|
|
opt: QStyleOptionH;
|
|
IconSize: Integer;
|
|
AIcon: QIconH;
|
|
ASize: TSize;
|
|
begin
|
|
case StockID of
|
|
idButtonOk: AStdPixmap := QStyleSP_DialogOkButton;
|
|
idButtonCancel: AStdPixmap := QStyleSP_DialogCancelButton;
|
|
idButtonYes: AStdPixmap := QStyleSP_DialogYesButton;
|
|
idButtonYesToAll: AStdPixmap := QStyleSP_DialogYesButton;
|
|
idButtonNo: AStdPixmap := QStyleSP_DialogNoButton;
|
|
idButtonNoToAll: AStdPixmap := QStyleSP_DialogNoButton;
|
|
idButtonHelp: AStdPixmap := QStyleSP_DialogHelpButton;
|
|
idButtonClose: AStdPixmap := QStyleSP_DialogCloseButton;
|
|
idButtonAbort: AStdPixmap := QStyleSP_DialogResetButton;
|
|
idButtonAll: AStdPixmap := QStyleSP_DialogApplyButton;
|
|
idButtonIgnore: AStdPixmap := QStyleSP_DialogDiscardButton;
|
|
idButtonRetry: AStdPixmap := QStyleSP_BrowserReload; // ?
|
|
idButtonOpen: AStdPixmap := QStyleSP_DialogOpenButton;
|
|
idButtonSave: AStdPixmap := QStyleSP_DialogSaveButton;
|
|
idButtonShield: AStdPixmap := QStyleSP_VistaShield;
|
|
|
|
idDialogWarning : AStdPixmap := QStyleSP_MessageBoxWarning;
|
|
idDialogError: AStdPixmap := QStyleSP_MessageBoxCritical;
|
|
idDialogInfo: AStdPixmap := QStyleSP_MessageBoxInformation;
|
|
idDialogConfirm: AStdPixmap := QStyleSP_MessageBoxQuestion;
|
|
else
|
|
begin
|
|
Result := inherited GetStockImage(StockID, Image, Mask);
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
opt := QStyleOption_create(Ord(QStyleOptionVersion), Ord(QStyleOptionSO_Default));
|
|
AIcon := QIcon_create();
|
|
if StockID in [idButtonOk..idButtonShield] then
|
|
IconSize := GetPixelMetric(QStylePM_ButtonIconSize, opt, nil)
|
|
else
|
|
if (StockID >= idDialogWarning) and (StockID <= idDialogShield) then
|
|
IconSize := GetPixelMetric(QStylePM_MessageBoxIconSize, opt, nil)
|
|
else
|
|
IconSize := 0;
|
|
QStyle_standardIcon(QApplication_style(), AIcon, AStdPixmap, opt);
|
|
QStyleOption_Destroy(opt);
|
|
|
|
if QIcon_isNull(AIcon) then
|
|
begin
|
|
QIcon_destroy(AIcon);
|
|
Result := inherited GetStockImage(StockID, Image, Mask);
|
|
Exit;
|
|
end;
|
|
|
|
// convert from what we have to QImageH
|
|
APixmap := QPixmap_create();
|
|
if IconSize > 0 then
|
|
begin
|
|
ASize.cx := IconSize;
|
|
ASize.cy := IconSize;
|
|
end else
|
|
QIcon_actualSize(AIcon, @ASize, @ASize);
|
|
QIcon_pixmap(AIcon, APixmap, PSize(@ASize));
|
|
QIcon_destroy(AIcon);
|
|
AImage := QImage_create();
|
|
QPixmap_toImage(APixmap, AImage);
|
|
QPixmap_destroy(APixmap);
|
|
|
|
// we must respect theme size , qt is buggy somehow, some icons are 22 some 16px.
|
|
if IconSize > 0 then
|
|
begin
|
|
if (QImage_width(AImage) > IconSize) and (QImage_height(AImage) > IconSize) then
|
|
begin
|
|
AScaledImage := QImage_create();
|
|
QImage_scaled(AImage, AScaledImage, IconSize, IconSize, QtKeepAspectRatio, QtSmoothTransformation);
|
|
QImage_destroy(AImage);
|
|
AImage := QImage_create(AScaledImage);
|
|
QImage_destroy(AScaledImage);
|
|
end;
|
|
end;
|
|
|
|
Image := HBitmap(TQtImage.Create(AImage));
|
|
Mask := 0;
|
|
Result := True;
|
|
end;
|
|
|
|
function TQtThemeServices.GetDrawElement(Details: TThemedElementDetails): TQtDrawElement;
|
|
const
|
|
ButtonMap: array[BP_PUSHBUTTON..BP_USERBUTTON] of QStyleControlElement =
|
|
(
|
|
{BP_PUSHBUTTON } QStyleCE_PushButton,
|
|
{BP_RADIOBUTTON} QStyleCE_RadioButton,
|
|
{BP_CHECKBOX } QStyleCE_CheckBox,
|
|
{BP_GROUPBOX } QStyleCE_PushButton,
|
|
{BP_USERBUTTON } QStyleCE_PushButton
|
|
);
|
|
begin
|
|
Result.DrawVariant := qdvNone;
|
|
case Details.Element of
|
|
teButton:
|
|
begin
|
|
if Details.Part <> BP_GROUPBOX then
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
Result.ControlElement := ButtonMap[Details.Part]
|
|
end
|
|
else
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_GroupBox;
|
|
Result.SubControls := QStyleSC_GroupBoxFrame;
|
|
end;
|
|
end;
|
|
teComboBox:
|
|
begin
|
|
if Byte(Details.Part) in [CP_DROPDOWNBUTTON, CP_DROPDOWNBUTTONRIGHT, CP_DROPDOWNBUTTONLEFT] then
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_ComboBox;
|
|
Result.SubControls := QStyleSC_ComboBoxArrow;
|
|
if Details.Part = CP_DROPDOWNBUTTONLEFT then
|
|
Result.Features := Ord(QtRightToLeft)
|
|
else
|
|
Result.Features := 0;
|
|
end else
|
|
if not (Details.Part = CP_READONLY) then
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_ComboBox;
|
|
Result.SubControls := QStyleSC_ComboBoxEditField;
|
|
end else
|
|
if Byte(Details.Part) in [0, CP_BORDER] then
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_ComboBox;
|
|
Result.SubControls := QStyleSC_ComboBoxFrame;
|
|
end;
|
|
end;
|
|
teHeader:
|
|
begin
|
|
case Details.Part of
|
|
HP_HEADERITEM,
|
|
HP_HEADERITEMLEFT,
|
|
HP_HEADERITEMRIGHT:
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
Result.ControlElement := QStyleCE_HeaderSection;
|
|
end;
|
|
HP_HEADERSORTARROW:
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_IndicatorHeaderArrow;
|
|
end;
|
|
end;
|
|
end;
|
|
teToolBar:
|
|
begin
|
|
case Details.Part of
|
|
TP_BUTTON,
|
|
TP_DROPDOWNBUTTON,
|
|
TP_SPLITBUTTON: // there is another positibility to draw TP_SPLITBUTTON by CC_ToolButton
|
|
begin
|
|
{$IFDEF DARWIN}
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_ToolButton;
|
|
Result.SubControls := QStyleSC_ToolButton;
|
|
Result.Features := QStyleOptionToolButtonNone;
|
|
{$ELSE}
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_PanelButtonTool;
|
|
{$ENDIF}
|
|
end;
|
|
TP_SPLITBUTTONDROPDOWN:
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_ToolButton;
|
|
Result.SubControls := QStyleSC_None;
|
|
{$IFDEF DARWIN}
|
|
Result.Features := QStyleOptionToolButtonHasMenu;
|
|
{$ELSE}
|
|
Result.Features := QStyleOptionToolButtonMenuButtonPopup;
|
|
{$ENDIF}
|
|
end;
|
|
TP_SEPARATOR,
|
|
TP_SEPARATORVERT:
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_IndicatorToolBarSeparator;
|
|
end;
|
|
end;
|
|
end;
|
|
teRebar:
|
|
begin
|
|
case Details.Part of
|
|
RP_GRIPPER, RP_GRIPPERVERT: // used in splitter
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
Result.ControlElement := QStyleCE_Splitter;
|
|
end;
|
|
end;
|
|
end;
|
|
teEdit:
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
if Details.Part in [0, EP_EDITTEXT, EP_CARET, EP_BACKGROUND, EP_BACKGROUNDWITHBORDER] then
|
|
Result.PrimitiveElement := QStylePE_FrameLineEdit;
|
|
end;
|
|
teSpin:
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_SpinBox;
|
|
if Details.Part = 0 then
|
|
Result.SubControls := QStyleSC_SpinBoxFrame
|
|
else
|
|
if Byte(Details.Part) in [SPNP_UP, SPNP_UPHORZ] then
|
|
Result.SubControls := QStyleSC_SpinBoxUp
|
|
else
|
|
if Byte(Details.Part) in [SPNP_DOWN, SPNP_DOWNHORZ] then
|
|
Result.SubControls := QStyleSC_SpinBoxDown;
|
|
if Byte(Details.Part) in [SPNP_UPHORZ, SPNP_DOWNHORZ] then
|
|
Result.Features := QtVertical;
|
|
end;
|
|
teWindow:
|
|
begin
|
|
case Details.Part of
|
|
WP_FRAMELEFT,
|
|
WP_FRAMERIGHT,
|
|
WP_FRAMEBOTTOM,
|
|
WP_SMALLFRAMELEFT,
|
|
WP_SMALLFRAMERIGHT,
|
|
WP_SMALLFRAMEBOTTOM:
|
|
begin
|
|
Result.PrimitiveElement := QStylePE_FrameWindow;
|
|
Result.DrawVariant := qdvPrimitive;
|
|
exit;
|
|
end;
|
|
WP_SMALLCLOSEBUTTON:
|
|
begin
|
|
Result.DrawVariant := qdvStandardPixmap;
|
|
Result.StandardPixmap := QStyleSP_TitleBarCloseButton;
|
|
exit;
|
|
end;
|
|
WP_SMALLCAPTION: Result.SubControls := QStyleSC_TitleBarLabel;
|
|
WP_SYSBUTTON: Result.SubControls := QStyleSC_TitleBarSysMenu;
|
|
WP_MINBUTTON: Result.SubControls := QStyleSC_TitleBarMinButton;
|
|
WP_MAXBUTTON: Result.SubControls := QStyleSC_TitleBarMaxButton;
|
|
WP_CLOSEBUTTON: Result.SubControls := QStyleSC_TitleBarCloseButton;
|
|
WP_RESTOREBUTTON: Result.SubControls := QStyleSC_TitleBarNormalButton;
|
|
WP_HELPBUTTON: Result.SubControls := QStyleSC_TitleBarContextHelpButton;
|
|
WP_MDIHELPBUTTON: Result.SubControls := QStyleSC_TitleBarContextHelpButton;
|
|
WP_MDIMINBUTTON: Result.SubControls := QStyleSC_MdiMinButton;
|
|
WP_MDICLOSEBUTTON: Result.SubControls := QStyleSC_MdiCloseButton;
|
|
WP_MDIRESTOREBUTTON: Result.SubControls := QStyleSC_MdiNormalButton;
|
|
else
|
|
Result.SubControls := QStyleSC_None;
|
|
end;
|
|
|
|
if Result.SubControls <= QStyleSC_MdiCloseButton then
|
|
Result.ComplexControl := QStyleCC_MdiControls
|
|
else
|
|
Result.ComplexControl := QStyleCC_TitleBar;
|
|
|
|
Result.DrawVariant := qdvComplexControl;
|
|
{
|
|
// maybe through icon
|
|
Result.DrawVariant := qdvStandardPixmap;
|
|
case Details.Part of
|
|
WP_MINBUTTON: Result.StandardPixmap := QStyleSP_TitleBarMinButton;
|
|
WP_MDIMINBUTTON: Result.StandardPixmap := QStyleSP_TitleBarMinButton;
|
|
WP_MAXBUTTON: Result.StandardPixmap := QStyleSP_TitleBarMaxButton;
|
|
WP_CLOSEBUTTON: Result.StandardPixmap := QStyleSP_TitleBarCloseButton;
|
|
WP_SMALLCLOSEBUTTON: Result.StandardPixmap := QStyleSP_TitleBarCloseButton;
|
|
WP_MDICLOSEBUTTON: Result.StandardPixmap := QStyleSP_TitleBarCloseButton;
|
|
WP_RESTOREBUTTON: Result.StandardPixmap := QStyleSP_TitleBarNormalButton;
|
|
WP_MDIRESTOREBUTTON: Result.StandardPixmap := QStyleSP_TitleBarNormalButton;
|
|
WP_HELPBUTTON: Result.StandardPixmap := QStyleSP_TitleBarContextHelpButton;
|
|
WP_MDIHELPBUTTON: Result.StandardPixmap := QStyleSP_TitleBarContextHelpButton;
|
|
else
|
|
Result.StandardPixmap := QStyleSP_TitleBarCloseButton;
|
|
end;
|
|
}
|
|
end;
|
|
teTab:
|
|
begin
|
|
if Byte(Details.Part) in [TABP_TABITEM, TABP_TABITEMLEFTEDGE, TABP_TABITEMRIGHTEDGE, TABP_TOPTABITEM] then
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
Result.ControlElement := QStyleCE_TabBarTabShape;
|
|
if Details.Part = TABP_TABITEM then
|
|
Result.Features := Ord(QTabBarRoundedNorth)
|
|
else
|
|
if Details.Part = TABP_TABITEMLEFTEDGE then
|
|
Result.Features := Ord(QTabBarRoundedWest)
|
|
else
|
|
if Details.Part = TABP_TABITEMRIGHTEDGE then
|
|
Result.Features := Ord(QTabBarRoundedEast)
|
|
else
|
|
Result.Features := Ord(QTabBarRoundedNorth);
|
|
end else
|
|
if Details.Part = TABP_PANE then
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_FrameTabWidget;
|
|
end else
|
|
if Details.Part = TABP_BODY then
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_FrameTabBarBase;
|
|
end;
|
|
end;
|
|
teProgress:
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
case Details.Part of
|
|
PP_CHUNK,PP_CHUNKVERT: Result.ControlElement := QStyleCE_ProgressBarContents;
|
|
PP_FILL,PP_FILLVERT: Result.ControlElement := QStyleCE_ProgressBarGroove;
|
|
else
|
|
Result.ControlElement := QStyleCE_ProgressBar;
|
|
end;
|
|
if Byte(Details.Part) in [PP_BARVERT, PP_FILLVERT, PP_CHUNKVERT] then
|
|
Result.Features := QtVertical;
|
|
end;
|
|
teScrollBar:
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_ScrollBar;
|
|
case Details.Part of
|
|
SBP_ARROWBTN: Result.SubControls := QStyleSC_ScrollBarAddLine;
|
|
SBP_THUMBBTNHORZ,
|
|
SBP_THUMBBTNVERT,
|
|
SBP_GRIPPERHORZ,
|
|
SBP_GRIPPERVERT: Result.SubControls := QStyleSC_ScrollBarSlider;
|
|
SBP_LOWERTRACKHORZ,
|
|
SBP_LOWERTRACKVERT: Result.SubControls := QStyleSC_ScrollBarAddPage;
|
|
SBP_UPPERTRACKHORZ,
|
|
SBP_UPPERTRACKVERT: Result.SubControls := QStyleSC_ScrollBarSubPage;
|
|
else
|
|
Result.SubControls := QStyleSC_None;
|
|
end;
|
|
end;
|
|
teTrackBar:
|
|
begin
|
|
Result.DrawVariant := qdvComplexControl;
|
|
Result.ComplexControl := QStyleCC_Slider;
|
|
if Details.Part in [TKP_TRACKVERT, TKP_THUMBVERT, TKP_TICSVERT] then
|
|
Result.Features := QtVertical
|
|
else
|
|
Result.Features := QtHorizontal;
|
|
case Details.Part of
|
|
TKP_TRACK,
|
|
TKP_TRACKVERT: Result.SubControls := QStyleSC_SliderGroove;
|
|
TKP_THUMB,
|
|
TKP_THUMBBOTTOM,
|
|
TKP_THUMBTOP,
|
|
TKP_THUMBVERT,
|
|
TKP_THUMBLEFT,
|
|
TKP_THUMBRIGHT: Result.SubControls := QStyleSC_SliderHandle;
|
|
TKP_TICS,
|
|
TKP_TICSVERT: Result.SubControls := QStyleSC_SliderTickmarks;
|
|
end;
|
|
end;
|
|
teStatus:
|
|
begin
|
|
case Details.Part of
|
|
SP_PANE:
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_FrameStatusBar;
|
|
end;
|
|
SP_GRIPPER:
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
Result.ControlElement := QStyleCE_SizeGrip;
|
|
end;
|
|
SP_GRIPPERPANE:
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_FrameStatusBarItem;
|
|
end;
|
|
end;
|
|
end;
|
|
teTreeView, teListView:
|
|
begin
|
|
if (Details.Element = teTreeView) and
|
|
(Details.Part in [TVP_GLYPH, TVP_HOTGLYPH]) then
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_IndicatorBranch;
|
|
end else
|
|
if Details.Part in [TVP_TREEITEM] then
|
|
begin
|
|
Result.DrawVariant := qdvControl;
|
|
Result.ControlElement := QStyleCE_ItemViewItem;
|
|
end;
|
|
end;
|
|
teToolTip:
|
|
begin
|
|
if Details.Part = TTP_STANDARD then
|
|
begin
|
|
Result.DrawVariant := qdvPrimitive;
|
|
Result.PrimitiveElement := QStylePE_PanelTipLabel;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|
|
|