mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Bug 1696: Dark theme
https://winscp.net/tracker/1696 Source commit: 5093ac8f9a61e0c632fbe5f2d3c55f03a3393dcf
This commit is contained in:
@@ -996,6 +996,8 @@ void __fastcall TCustomScpExplorerForm::UpdateSessionsPageControlHeight()
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::ConfigurationChanged()
|
||||
{
|
||||
Color = WinConfiguration->UseDarkTheme() ? TColor(RGB(43, 43, 43)) : clBtnFace;
|
||||
|
||||
DebugAssert(Configuration && RemoteDirView);
|
||||
RemoteDirView->DimmHiddenFiles = WinConfiguration->DimmHiddenFiles;
|
||||
RemoteDirView->ShowHiddenFiles = WinConfiguration->ShowHiddenFiles;
|
||||
@@ -8318,6 +8320,31 @@ UnicodeString __fastcall TCustomScpExplorerForm::PathForCaption()
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TColor __fastcall TCustomScpExplorerForm::DefaultPanelColor()
|
||||
{
|
||||
TColor Result = (WinConfiguration->UseDarkTheme() ? static_cast<TColor>(RGB(0x20, 0x20, 0x20)) : clWindow);
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TColor __fastcall TCustomScpExplorerForm::PanelColor()
|
||||
{
|
||||
TColor Result = (FSessionColor != 0 ? FSessionColor : DefaultPanelColor());
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TColor __fastcall TCustomScpExplorerForm::PanelFontColor(TColor BackgroundColor)
|
||||
{
|
||||
TColor Result = (IsDarkColor(BackgroundColor) ? clWhite : clWindowText);
|
||||
SetContrast(Result, BackgroundColor, 180);
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TColor __fastcall TCustomScpExplorerForm::DisabledPanelColor()
|
||||
{
|
||||
TColor Result = (WinConfiguration->UseDarkTheme() ? static_cast<TColor>(RGB(0x40, 0x40, 0x40)) : clBtnFace);
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::UpdateControls()
|
||||
{
|
||||
TTerminalManager::Instance()->UpdateAppTitle();
|
||||
@@ -8343,9 +8370,7 @@ void __fastcall TCustomScpExplorerForm::UpdateControls()
|
||||
ActiveControl = RemoteDirView;
|
||||
}
|
||||
}
|
||||
RemoteDriveView->Enabled = true;
|
||||
RemoteDirView->Color = (FSessionColor != 0 ? FSessionColor : clWindow);
|
||||
RemoteDriveView->Color = RemoteDirView->Color;
|
||||
RemoteDirView->Color = PanelColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8356,12 +8381,30 @@ void __fastcall TCustomScpExplorerForm::UpdateControls()
|
||||
// but the false is overriden in the constructor later.
|
||||
// An even later in TScpCommanderForm::DoShow()
|
||||
FRemoteDirViewWasFocused = (ActiveControl == RemoteDirView);
|
||||
EnableControl(RemoteDirView, false);
|
||||
RemoteDirView->Enabled = false;
|
||||
RemoteDirView->Color = DisabledPanelColor();
|
||||
}
|
||||
EnableControl(RemoteDriveView, false);
|
||||
}
|
||||
EnableControl(QueueView3, HasTerminal && Terminal->IsCapable[fsBackgroundTransfers]);
|
||||
|
||||
RemoteDirView->Font->Color = PanelFontColor(RemoteDirView->Color);
|
||||
|
||||
RemoteDriveView->Enabled = RemoteDirView->Enabled;
|
||||
RemoteDriveView->Color = RemoteDirView->Color;
|
||||
RemoteDriveView->Font->Color = RemoteDirView->Font->Color;
|
||||
|
||||
QueueView3->Enabled = HasTerminal && Terminal->IsCapable[fsBackgroundTransfers];
|
||||
QueueView3->Color = QueueView3->Enabled ? DefaultPanelColor() : DisabledPanelColor();
|
||||
QueueLabelUpdateStatus();
|
||||
|
||||
bool UseDarkTheme = WinConfiguration->UseDarkTheme();
|
||||
AllowDarkModeForWindow(RemoteDirView, UseDarkTheme);
|
||||
AllowDarkModeForWindow(RemoteDriveView, UseDarkTheme);
|
||||
AllowDarkModeForWindow(SessionsPageControl, UseDarkTheme);
|
||||
if (QueueView3->HandleAllocated())
|
||||
{
|
||||
AllowDarkModeForWindow(QueueView3, UseDarkTheme);
|
||||
}
|
||||
|
||||
reinterpret_cast<TTBCustomItem *>(GetComponent(fcRemotePathComboBox))->Enabled = HasTerminal;
|
||||
}
|
||||
}
|
||||
@@ -8689,6 +8732,14 @@ void __fastcall TCustomScpExplorerForm::QueueSplitterDblClick(TObject * /*Sender
|
||||
PostComponentHide(fcQueueView);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::WMWinIniChange(TMessage & Message)
|
||||
{
|
||||
WinConfiguration->ResetSysDarkTheme();
|
||||
ConfigurationChanged();
|
||||
ConfigureInterface();
|
||||
TForm::Dispatch(&Message);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::Dispatch(void * Message)
|
||||
{
|
||||
TMessage * M = static_cast<TMessage*>(Message);
|
||||
@@ -8773,6 +8824,10 @@ void __fastcall TCustomScpExplorerForm::Dispatch(void * Message)
|
||||
CMDpiChanged(*M);
|
||||
break;
|
||||
|
||||
case WM_WININICHANGE:
|
||||
WMWinIniChange(*M);
|
||||
break;
|
||||
|
||||
default:
|
||||
TForm::Dispatch(Message);
|
||||
break;
|
||||
|
||||
@@ -50,9 +50,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
|
||||
Height = 240
|
||||
Cursor = crSizeWE
|
||||
AutoSnap = False
|
||||
Color = clBtnFace
|
||||
MinSize = 70
|
||||
ParentColor = False
|
||||
ResizeStyle = rsUpdate
|
||||
end
|
||||
object RemoteStatusBar: TTBXStatusBar
|
||||
|
||||
@@ -651,6 +651,11 @@ protected:
|
||||
void __fastcall CloseSessionTab(int Index);
|
||||
void __fastcall DoFileColorsChanged(TCustomDirView * DirView);
|
||||
virtual void __fastcall FileColorsChanged();
|
||||
TColor __fastcall DefaultPanelColor();
|
||||
TColor __fastcall PanelColor();
|
||||
TColor __fastcall PanelFontColor(TColor BackgroundColor);
|
||||
TColor __fastcall DisabledPanelColor();
|
||||
void __fastcall WMWinIniChange(TMessage & Message);
|
||||
|
||||
public:
|
||||
virtual __fastcall ~TCustomScpExplorerForm();
|
||||
|
||||
@@ -569,6 +569,8 @@ void __fastcall TPreferencesDialog::LoadConfiguration()
|
||||
BOOLPROP(CopyParamAutoSelectNotice);
|
||||
|
||||
// interface
|
||||
ComboAutoSwitchLoad(ThemeCombo, WinConfiguration->DarkTheme);
|
||||
|
||||
switch (CustomWinConfiguration->Interface)
|
||||
{
|
||||
case ifCommander:
|
||||
@@ -877,6 +879,8 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
|
||||
BOOLPROP(CopyParamAutoSelectNotice);
|
||||
|
||||
// interface
|
||||
WinConfiguration->DarkTheme = ComboAutoSwitchSave(ThemeCombo);
|
||||
|
||||
if (GetInterface() != CustomWinConfiguration->Interface)
|
||||
{
|
||||
Configuration->Usage->Inc(L"InterfaceChanges");
|
||||
|
||||
@@ -503,19 +503,19 @@ object PreferencesDialog: TPreferencesDialog
|
||||
398)
|
||||
object InterfaceChangeLabel: TLabel
|
||||
Left = 8
|
||||
Top = 222
|
||||
Top = 280
|
||||
Width = 177
|
||||
Height = 13
|
||||
Caption = 'Changes will apply on the next start.'
|
||||
end
|
||||
object InterfaceGroup: TGroupBox
|
||||
Left = 8
|
||||
Top = 8
|
||||
Top = 66
|
||||
Width = 389
|
||||
Height = 208
|
||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||
Caption = 'User Interface'
|
||||
TabOrder = 0
|
||||
TabOrder = 1
|
||||
DesignSize = (
|
||||
389
|
||||
208)
|
||||
@@ -584,6 +584,39 @@ object PreferencesDialog: TPreferencesDialog
|
||||
OnClick = ControlChange
|
||||
end
|
||||
end
|
||||
object ThemeGroup: TGroupBox
|
||||
Left = 8
|
||||
Top = 8
|
||||
Width = 389
|
||||
Height = 52
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
Caption = 'Theme'
|
||||
TabOrder = 0
|
||||
DesignSize = (
|
||||
389
|
||||
52)
|
||||
object Label7: TLabel
|
||||
Left = 16
|
||||
Top = 23
|
||||
Width = 82
|
||||
Height = 13
|
||||
Caption = 'Interface &theme:'
|
||||
FocusControl = ThemeCombo
|
||||
end
|
||||
object ThemeCombo: TComboBox
|
||||
Left = 132
|
||||
Top = 18
|
||||
Width = 141
|
||||
Height = 21
|
||||
Style = csDropDownList
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
TabOrder = 0
|
||||
Items.Strings = (
|
||||
'Automatic'
|
||||
'Light'
|
||||
'Dark')
|
||||
end
|
||||
end
|
||||
end
|
||||
object PanelsSheet: TTabSheet
|
||||
Tag = 4
|
||||
|
||||
@@ -330,6 +330,9 @@ __published:
|
||||
TButton *UpFileColorButton;
|
||||
TButton *DownFileColorButton;
|
||||
TButton *EditFileColorButton;
|
||||
TGroupBox *ThemeGroup;
|
||||
TLabel *Label7;
|
||||
TComboBox *ThemeCombo;
|
||||
void __fastcall FormShow(TObject *Sender);
|
||||
void __fastcall ControlChange(TObject *Sender);
|
||||
void __fastcall EditorFontButtonClick(TObject *Sender);
|
||||
|
||||
@@ -806,8 +806,18 @@ void __fastcall TScpCommanderForm::UpdateControls()
|
||||
// command line combo width needs to be updated as caption width has probably changed
|
||||
ToolBarResize(CommandLineToolbar);
|
||||
}
|
||||
LocalDirView->Color = (SessionColor != 0 ? SessionColor : clWindow);
|
||||
if (LocalDirView->HandleAllocated())
|
||||
{
|
||||
AllowDarkModeForWindow(LocalDirView, WinConfiguration->UseDarkTheme());
|
||||
}
|
||||
if (LocalDriveView->HandleAllocated())
|
||||
{
|
||||
AllowDarkModeForWindow(LocalDriveView, WinConfiguration->UseDarkTheme());
|
||||
}
|
||||
LocalDirView->Color = PanelColor();
|
||||
LocalDriveView->Color = LocalDirView->Color;
|
||||
LocalDirView->Font->Color = PanelFontColor(LocalDirView->Color);
|
||||
LocalDriveView->Font->Color = LocalDirView->Font->Color;
|
||||
|
||||
bool LocalSide = (FCurrentSide == osLocal);
|
||||
TAction * CurrentCopyAction = LocalSide ? NonVisualDataModule->LocalCopyAction : NonVisualDataModule->RemoteCopyAction;
|
||||
|
||||
@@ -1030,6 +1030,7 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Height = 298
|
||||
Constraints.MinHeight = 220
|
||||
Constraints.MinWidth = 185
|
||||
ParentColor = True
|
||||
TabOrder = 1
|
||||
object RemotePathLabel: TPathLabel [0]
|
||||
Left = 0
|
||||
@@ -1118,7 +1119,6 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Top = 0
|
||||
Width = 458
|
||||
Height = 79
|
||||
Color = clBtnFace
|
||||
FixAlign = True
|
||||
OnContextPopup = DockContextPopup
|
||||
object RemoteHistoryToolbar: TTBXToolbar
|
||||
@@ -1313,7 +1313,6 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Top = 270
|
||||
Width = 458
|
||||
Height = 9
|
||||
Color = clBtnFace
|
||||
FixAlign = True
|
||||
Position = dpBottom
|
||||
end
|
||||
@@ -1322,6 +1321,7 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Top = 532
|
||||
Width = 898
|
||||
Height = 116
|
||||
ParentColor = True
|
||||
TabOrder = 2
|
||||
inherited QueueLabel: TPathLabel
|
||||
Width = 898
|
||||
@@ -1346,10 +1346,10 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Height = 298
|
||||
Align = alLeft
|
||||
BevelOuter = bvNone
|
||||
Color = clWindow
|
||||
Constraints.MinHeight = 220
|
||||
Constraints.MinWidth = 185
|
||||
ParentBackground = False
|
||||
ParentColor = True
|
||||
TabOrder = 0
|
||||
object LocalPathLabel: TPathLabel
|
||||
Left = 0
|
||||
@@ -1378,9 +1378,7 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
'ctory trees equal.'
|
||||
Align = alTop
|
||||
AutoSnap = False
|
||||
Color = clBtnFace
|
||||
MinSize = 70
|
||||
ParentColor = False
|
||||
ResizeStyle = rsUpdate
|
||||
end
|
||||
object LocalStatusBar: TTBXStatusBar
|
||||
@@ -1467,7 +1465,6 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Top = 0
|
||||
Width = 435
|
||||
Height = 79
|
||||
Color = clBtnFace
|
||||
FixAlign = True
|
||||
OnContextPopup = DockContextPopup
|
||||
object LocalHistoryToolbar: TTBXToolbar
|
||||
@@ -1676,7 +1673,6 @@ inherited ScpCommanderForm: TScpCommanderForm
|
||||
Top = 270
|
||||
Width = 435
|
||||
Height = 9
|
||||
Color = clBtnFace
|
||||
FixAlign = True
|
||||
Position = dpBottom
|
||||
end
|
||||
|
||||
@@ -183,6 +183,7 @@ type
|
||||
procedure LVMSetExtendedListViewStyle(var Message: TMessage); message LVM_SETEXTENDEDLISTVIEWSTYLE;
|
||||
procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
|
||||
procedure CMDPIChanged(var Message: TMessage); message CM_DPICHANGED;
|
||||
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
|
||||
|
||||
procedure DumbCustomDrawItem(Sender: TCustomListView; Item: TListItem;
|
||||
State: TCustomDrawState; var DefaultDraw: Boolean);
|
||||
@@ -1115,6 +1116,27 @@ begin
|
||||
NeedImageLists(True);
|
||||
end;
|
||||
|
||||
const
|
||||
RequiredStyles = LVS_EX_DOUBLEBUFFER or LVS_EX_TRANSPARENTBKGND;
|
||||
|
||||
procedure TCustomDirView.CMEnabledChanged(var Message: TMessage);
|
||||
var
|
||||
ListViewStyle: DWORD;
|
||||
begin
|
||||
inherited;
|
||||
// We need this so that we can control background color of disabled file panel for dark theme.
|
||||
// See comment in LVMSetExtendedListViewStyle for an explanation.
|
||||
ListViewStyle := ListView_GetExtendedListViewStyle(Handle);
|
||||
if Enabled then
|
||||
begin
|
||||
ListView_SetExtendedListViewStyle(Handle, (ListViewStyle or RequiredStyles));
|
||||
end
|
||||
else
|
||||
begin
|
||||
ListView_SetExtendedListViewStyle(Handle, (ListViewStyle and (not RequiredStyles)));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomDirView.FreeImageLists;
|
||||
begin
|
||||
FreeAndNil(FImageList16);
|
||||
@@ -1143,11 +1165,10 @@ procedure TCustomDirView.LVMSetExtendedListViewStyle(var Message: TMessage);
|
||||
// keyboard (Page-up/Down). This gets fixed by LVS_EX_TRANSPARENTBKGND,
|
||||
// but that works on Vista and newer only. See WMKeyDown
|
||||
// for workaround on earlier systems.
|
||||
const
|
||||
RequiredStyles = LVS_EX_DOUBLEBUFFER or LVS_EX_TRANSPARENTBKGND;
|
||||
begin
|
||||
// This prevents TCustomListView.ResetExStyles resetting our styles
|
||||
if (Message.WParam = 0) and
|
||||
if Enabled and
|
||||
(Message.WParam = 0) and
|
||||
((Message.LParam and RequiredStyles) <> RequiredStyles) then
|
||||
begin
|
||||
ListView_SetExtendedListViewStyle(Handle, Message.LParam or RequiredStyles);
|
||||
|
||||
1
source/packages/tbx/TBX.pas
vendored
1
source/packages/tbx/TBX.pas
vendored
@@ -3464,6 +3464,7 @@ end;
|
||||
initialization
|
||||
FixPlaySoundDelay;
|
||||
RegisterTBXTheme('OfficeXP', TTBXOfficeXPTheme);
|
||||
RegisterTBXTheme('DarkOfficeXP', TTBXDarkOfficeXPTheme);
|
||||
TBXNexus := TTBXNexus.Create('OfficeXP');
|
||||
TBXMenuAnimation := TTBXMenuAnimation.Create;
|
||||
|
||||
|
||||
4
source/packages/tbx/TBXExtItems.pas
vendored
4
source/packages/tbx/TBXExtItems.pas
vendored
@@ -839,8 +839,8 @@ begin
|
||||
Fnt := Item.EditorFontSettings.CreateTransformedFont(TTBViewAccess(View).GetFont.Handle, C);
|
||||
OldFnt := SelectObject(DC, Fnt);
|
||||
SetBkMode(DC, TRANSPARENT);
|
||||
SetBkColor(DC, GetSysColor(FillColors[Item.Enabled]));
|
||||
SetTextColor(DC, GetSysColor(TextColors[Item.Enabled]));
|
||||
SetBkColor(DC, CurrentTheme.GetSysColor(FillColors[Item.Enabled]));
|
||||
SetTextColor(DC, CurrentTheme.GetSysColor(TextColors[Item.Enabled]));
|
||||
// WinSCP: Align edit text with toolbar labels
|
||||
InflateRect(R, 0, -1);
|
||||
DrawText(DC, PChar(S), Length(S), R, DT_SINGLELINE or DT_NOPREFIX or Alignments[Item.Alignment]);
|
||||
|
||||
129
source/packages/tbx/TBXOfficeXPTheme.pas
vendored
129
source/packages/tbx/TBXOfficeXPTheme.pas
vendored
@@ -42,12 +42,15 @@ type
|
||||
ToolbarSeparatorColor: TColor;
|
||||
IconShadowColor: TColor;
|
||||
StatusPanelFrameColor: TColor;
|
||||
FDark: Boolean;
|
||||
|
||||
procedure SetupColorCache; virtual;
|
||||
protected
|
||||
{ Internal Methods }
|
||||
function GetPartColor(const ItemInfo: TTBXItemInfo; ItemPart: TItemPart): TColor;
|
||||
function GetBtnColor(const ItemInfo: TTBXItemInfo; ItemPart: TItemPart): TColor;
|
||||
function GetStandardColor(Color: TColor): TColor;
|
||||
procedure Init;
|
||||
public
|
||||
constructor Create(const AName: string); override;
|
||||
destructor Destroy; override;
|
||||
@@ -64,6 +67,7 @@ type
|
||||
procedure GetViewBorder(Control: TControl; ViewType: Integer; out Border: TPoint); override;
|
||||
function GetViewColor(AViewType: Integer): TColor; override;
|
||||
procedure GetViewMargins(ViewType: Integer; out Margins: TTBXMargins); override;
|
||||
function GetSysColor(nIndex: Integer): DWORD; override;
|
||||
|
||||
{ Painting routines }
|
||||
procedure PaintBackgnd(Canvas: TCanvas; const ADockRect, ARect, AClipRect: TRect; AColor: TColor; Transparent: Boolean; AViewType: Integer); override;
|
||||
@@ -86,6 +90,12 @@ type
|
||||
procedure PaintStatusBar(Control: TWinControl; Canvas: TCanvas; R: TRect; Part: Integer); override;
|
||||
end;
|
||||
|
||||
type
|
||||
TTBXDarkOfficeXPTheme = class(TTBXOfficeXPTheme)
|
||||
public
|
||||
constructor Create(const AName: string); override;
|
||||
end;
|
||||
|
||||
function GetSelectedBodyColor: TColor;
|
||||
|
||||
implementation
|
||||
@@ -165,7 +175,7 @@ begin
|
||||
end
|
||||
else if (AViewType and VT_POPUP) = VT_POPUP then
|
||||
begin
|
||||
if (AViewType and PVT_LISTBOX) = PVT_LISTBOX then Result := clWindow
|
||||
if (AViewType and PVT_LISTBOX) = PVT_LISTBOX then Result := GetStandardColor(clWindow)
|
||||
else Result := PopupColor;
|
||||
end
|
||||
else if (AViewType and VT_DOCKPANEL) = VT_DOCKPANEL then Result := DockPanelColor
|
||||
@@ -461,8 +471,8 @@ begin
|
||||
R := ARect;
|
||||
if not Embedded then
|
||||
begin
|
||||
FrameRectEx(DC, R, clWindow, False);
|
||||
C := clWindow;
|
||||
FrameRectEx(DC, R, GetStandardColor(clWindow), False);
|
||||
C := GetStandardColor(clWindow);
|
||||
end
|
||||
else C := GetBtnColor(ItemInfo, ipFrame);
|
||||
DrawLineEx(DC, R.Left - 1, R.Top, R.Left - 1, R.Bottom, C);
|
||||
@@ -489,8 +499,8 @@ begin
|
||||
BR.Left := ARect.Left; BR.Top := ARect.Top; BR.Right := ARect.Right;
|
||||
if not Embedded then
|
||||
begin
|
||||
FrameRectEx(DC, BR, clWindow, False);
|
||||
C := clWindow;
|
||||
FrameRectEx(DC, BR, GetStandardColor(clWindow), False);
|
||||
C := GetStandardColor(clWindow);
|
||||
end
|
||||
else C := GetBtnColor(ItemInfo, ipFrame);
|
||||
DrawLineEx(DC, BR.Left - 1, BR.Top, BR.Left - 1, BR.Bottom, C);
|
||||
@@ -515,8 +525,8 @@ begin
|
||||
BR.Left := ARect.Left; BR.Bottom := ARect.Bottom; BR.Right := ARect.Right;
|
||||
if not Embedded then
|
||||
begin
|
||||
FrameRectEx(DC, BR, clWindow, False);
|
||||
C := clWindow;
|
||||
FrameRectEx(DC, BR, GetStandardColor(clWindow), False);
|
||||
C := GetStandardColor(clWindow);
|
||||
end
|
||||
else C := GetBtnColor(ItemInfo, ipFrame);
|
||||
DrawLineEx(DC, BR.Left - 1, BR.Top, BR.Left - 1, BR.Bottom, C);
|
||||
@@ -556,10 +566,10 @@ begin
|
||||
if ((ItemInfo.ViewType and VT_TOOLBAR) <> VT_TOOLBAR) and (GetPartColor(ItemInfo, ipFrame) = clNone) then
|
||||
FrameRectEx(DC, R, ToolbarColor, False)
|
||||
else
|
||||
FrameRectEx(DC, R, clWindow, False);
|
||||
FrameRectEx(DC, R, GetStandardColor(clWindow), False);
|
||||
|
||||
InflateRect(R, -1, -1);
|
||||
FillRectEx(DC, R, clWindow);
|
||||
FillRectEx(DC, R, GetStandardColor(clWindow));
|
||||
if ((ItemInfo.ViewType and VT_TOOLBAR) <> VT_TOOLBAR) and (GetPartColor(ItemInfo, ipFrame) = clNone) then
|
||||
begin
|
||||
R := ARect;
|
||||
@@ -780,7 +790,7 @@ begin
|
||||
|
||||
if not Enabled then
|
||||
begin
|
||||
HiContrast := ColorIntensity(GetItemImageBackground(ItemInfo)) < 80;
|
||||
HiContrast := (not FDark) and (ColorIntensity(GetItemImageBackground(ItemInfo)) < 80);
|
||||
if not HiContrast then
|
||||
DrawTBXIconShadow(Canvas, ARect, ImageList, ImageIndex, 0)
|
||||
else
|
||||
@@ -1192,9 +1202,18 @@ begin
|
||||
else
|
||||
begin
|
||||
{ View/Window Colors }
|
||||
MenubarColor := clBtnFace;
|
||||
ToolbarColor := Blend(clWindow, clBtnFace, 165);
|
||||
PopupColor := Blend(clBtnFace, clWindow, 143);
|
||||
if not FDark then
|
||||
begin
|
||||
MenubarColor := clBtnFace;
|
||||
ToolbarColor := Blend(clWindow, clBtnFace, 165);
|
||||
PopupColor := Blend(clBtnFace, clWindow, 143);
|
||||
end
|
||||
else
|
||||
begin
|
||||
MenubarColor := clBlack;
|
||||
ToolbarColor := RGB(32, 32, 32);
|
||||
PopupColor := RGB(43, 43, 43);
|
||||
end;
|
||||
DockPanelColor := PopupColor;
|
||||
PopupFrameColor := Blend(clBtnText, clBtnShadow, 20);
|
||||
SetContrast(PopupFrameColor, PopupColor, 100);
|
||||
@@ -1222,15 +1241,25 @@ begin
|
||||
SetContrast(PnlFrameColors[wfsInactive, wfpCaptionText], clBtnFace, 120);
|
||||
|
||||
BtnItemColors[bisNormal, ipBody] := clNone;
|
||||
BtnItemColors[bisNormal, ipText] := clBtnText;
|
||||
if not FDark then
|
||||
BtnItemColors[bisNormal, ipText] := clBtnText
|
||||
else
|
||||
BtnItemColors[bisNormal, ipText] := clWhite;
|
||||
SetContrast(BtnItemColors[bisNormal, ipText], ToolbarColor, 180);
|
||||
BtnItemColors[bisNormal, ipFrame] := clNone;
|
||||
BtnItemColors[bisDisabled, ipBody] := clNone;
|
||||
BtnItemColors[bisDisabled, ipText] := DisabledText;
|
||||
SetContrast(BtnItemColors[bisDisabled, ipText], ToolbarColor, 80);
|
||||
BtnItemColors[bisDisabled, ipFrame] := clNone;
|
||||
BtnItemColors[bisSelected, ipBody] := GetSelectedBodyColor;
|
||||
SetContrast(BtnItemColors[bisSelected, ipBody], ToolbarColor, 5);
|
||||
if not FDark then
|
||||
begin
|
||||
BtnItemColors[bisSelected, ipBody] := GetSelectedBodyColor;
|
||||
SetContrast(BtnItemColors[bisSelected, ipBody], ToolbarColor, 5);
|
||||
end
|
||||
else
|
||||
begin
|
||||
BtnItemColors[bisSelected, ipBody] := clBlack;
|
||||
end;
|
||||
BtnItemColors[bisSelected, ipText] := BtnItemColors[bisNormal, ipText];
|
||||
BtnItemColors[bisSelected, ipFrame] := clHighlight;
|
||||
BtnItemColors[bisPressed, ipBody] := Blend(clHighlight, clWindow, 50);
|
||||
@@ -1255,8 +1284,15 @@ begin
|
||||
BtnItemColors[bisPopupParent, ipFrame] := PopupFrameColor;
|
||||
|
||||
MenuItemColors[misNormal, ipBody] := clNone;
|
||||
MenuItemColors[misNormal, ipText] := clWindowText;
|
||||
SetContrast(MenuItemColors[misNormal, ipText], PopupColor, 180);
|
||||
if not FDark then
|
||||
begin
|
||||
MenuItemColors[misNormal, ipText] := clWindowText;
|
||||
SetContrast(MenuItemColors[misNormal, ipText], PopupColor, 180);
|
||||
end
|
||||
else
|
||||
begin
|
||||
MenuItemColors[misNormal, ipText] := clWhite;
|
||||
end;
|
||||
MenuItemColors[misNormal, ipFrame] := clNone;
|
||||
MenuItemColors[misDisabled, ipBody] := clNone;
|
||||
MenuItemColors[misDisabled, ipText] := Blend(clGrayText, clWindow, 70);
|
||||
@@ -1270,14 +1306,23 @@ begin
|
||||
MenuItemColors[misDisabledHot, ipFrame] := clHighlight;
|
||||
|
||||
{ Other Colors }
|
||||
DragHandleColor := Blend(clBtnShadow, clWindow, 75);
|
||||
if not FDark then
|
||||
begin
|
||||
DragHandleColor := Blend(clBtnShadow, clWindow, 75);
|
||||
ToolbarSeparatorColor := Blend(clBtnShadow, clWindow, 70);
|
||||
StatusPanelFrameColor := Blend(clWindow, clBtnFace, 30);
|
||||
SetContrast(StatusPanelFrameColor, clBtnFace, 30);
|
||||
end
|
||||
else
|
||||
begin
|
||||
DragHandleColor := RGB(65, 65, 65);
|
||||
ToolbarSeparatorColor := DragHandleColor;
|
||||
StatusPanelFrameColor := DragHandleColor;
|
||||
end;
|
||||
SetContrast(DragHandleColor, ToolbarColor, 85);
|
||||
IconShadowColor := Blend(clBlack, HotBtnFace, 25);
|
||||
ToolbarSeparatorColor := Blend(clBtnShadow, clWindow, 70);
|
||||
SetContrast(ToolbarSeparatorColor, ToolbarColor, 50);
|
||||
PopupSeparatorColor := ToolbarSeparatorColor;
|
||||
StatusPanelFrameColor := Blend(clWindow, clBtnFace, 30);
|
||||
SetContrast(StatusPanelFrameColor, clBtnFace, 30);
|
||||
|
||||
Undither(MenubarColor);
|
||||
Undither(ToolbarColor);
|
||||
@@ -1348,6 +1393,12 @@ end;
|
||||
constructor TTBXOfficeXPTheme.Create(const AName: string);
|
||||
begin
|
||||
inherited;
|
||||
FDark := False;
|
||||
Init;
|
||||
end;
|
||||
|
||||
procedure TTBXOfficeXPTheme.Init;
|
||||
begin
|
||||
if CounterLock = 0 then InitializeStock;
|
||||
Inc(CounterLock);
|
||||
AddTBXSysChangeNotification(Self);
|
||||
@@ -1370,6 +1421,26 @@ begin
|
||||
Margins.BottomHeight := 0;
|
||||
end;
|
||||
|
||||
function TTBXOfficeXPTheme.GetSysColor(nIndex: Integer): DWORD;
|
||||
begin
|
||||
if FDark and (nIndex = COLOR_WINDOWTEXT) then
|
||||
Result := clWhite
|
||||
else
|
||||
Result := Windows.GetSysColor(nIndex);
|
||||
end;
|
||||
|
||||
function TTBXOfficeXPTheme.GetStandardColor(Color: TColor): TColor;
|
||||
begin
|
||||
if FDark then
|
||||
begin
|
||||
if Color = clWindow then
|
||||
begin
|
||||
Color := RGB(65, 65, 65);
|
||||
end;
|
||||
end;
|
||||
Result := Color;
|
||||
end;
|
||||
|
||||
procedure TTBXOfficeXPTheme.PaintStatusBar(Control: TWinControl; Canvas: TCanvas; R: TRect; Part: Integer);
|
||||
var
|
||||
D: Integer;
|
||||
@@ -1384,12 +1455,15 @@ var
|
||||
|
||||
var
|
||||
Theme: THandle;
|
||||
C: TColor;
|
||||
begin
|
||||
DC := Canvas.Handle;
|
||||
case Part of
|
||||
SBP_BODY:
|
||||
begin
|
||||
FillRectEx(DC, R, clBtnFace);
|
||||
if not FDark then C := clBtnFace
|
||||
else C := ToolbarColor;
|
||||
FillRectEx(DC, R, C);
|
||||
end;
|
||||
SBP_PANE, SBP_LASTPANE:
|
||||
begin
|
||||
@@ -1416,4 +1490,13 @@ begin
|
||||
Result := Blend(clHighlight, Blend(clBtnFace, clWindow, 50), 10);
|
||||
end;
|
||||
|
||||
{ TTBXDarkOfficeXPTheme }
|
||||
|
||||
constructor TTBXDarkOfficeXPTheme.Create(const AName: string);
|
||||
begin
|
||||
inherited;
|
||||
FDark := True;
|
||||
Init;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
1
source/packages/tbx/TBXThemes.pas
vendored
1
source/packages/tbx/TBXThemes.pas
vendored
@@ -294,6 +294,7 @@ type
|
||||
procedure GetViewBorder(Control: TControl; ViewType: Integer; out Border: TPoint); virtual; abstract;
|
||||
function GetViewColor(ViewType: Integer): TColor; virtual; abstract;
|
||||
procedure GetViewMargins(ViewType: Integer; out Margins: TTBXMargins); virtual; abstract;
|
||||
function GetSysColor(nIndex: Integer): DWORD; virtual; abstract;
|
||||
|
||||
{ General painting routines }
|
||||
procedure PaintBackgnd(Canvas: TCanvas; const ADockRect, ARect, AClipRect: TRect; AColor: TColor; Transparent: Boolean; AViewType: Integer); virtual; abstract;
|
||||
|
||||
3
source/packages/tbx/TBXUtils.pas
vendored
3
source/packages/tbx/TBXUtils.pas
vendored
@@ -544,6 +544,9 @@ begin
|
||||
S := Src^;
|
||||
if S <> Dst^ then
|
||||
begin
|
||||
// The algorithm does not work well against a black background
|
||||
if ColorIntensity(Dst^) < 80 then
|
||||
Dst^ := $00909090;
|
||||
CBRB := Dst^ and $00FF00FF;
|
||||
CBG := Dst^ and $0000FF00;
|
||||
C := ((S and $00FF0000) shr 16 * 29 + (S and $0000FF00) shr 8 * 150 +
|
||||
|
||||
@@ -376,6 +376,14 @@ void __fastcall ConfigureInterface()
|
||||
AdjustLocaleFlag(LoadStr(BIDI_MODE), WinConfiguration->BidiModeOverride, false, bdRightToLeft, bdLeftToRight);
|
||||
Application->BiDiMode = static_cast<TBiDiMode>(BidiModeFlag);
|
||||
SetTBXSysParam(TSP_XPVISUALSTYLE, XPVS_AUTOMATIC);
|
||||
if (WinConfiguration != NULL)
|
||||
{
|
||||
UnicodeString Theme = WinConfiguration->UseDarkTheme() ? L"DarkOfficeXP" : L"OfficeXP";
|
||||
if (!SameText(TBXCurrentTheme(), Theme))
|
||||
{
|
||||
TBXSetTheme(Theme);
|
||||
}
|
||||
}
|
||||
// Has any effect on Wine only
|
||||
// (otherwise initial UserDocumentDirectory is equivalent to GetPersonalFolder())
|
||||
UserDocumentDirectory = GetPersonalFolder();
|
||||
|
||||
@@ -2564,6 +2564,11 @@ void TDesktopFontManager::UpdateControl(TControl * Control)
|
||||
DesktopFont->PixelsPerInch = PublicControl->Font->PixelsPerInch;
|
||||
}
|
||||
|
||||
// Neither CreateFontIndirect nor RestoreFont set color, so we should should have the default set by TFont constructor here.
|
||||
DebugAssert(DesktopFont->Color == clWindowText);
|
||||
// Preserve color (particularly whice color of file panel font in dark mode)
|
||||
DesktopFont->Color = PublicControl->Font->Color;
|
||||
|
||||
PublicControl->Font->Assign(DesktopFont.get());
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2716,3 +2721,26 @@ TPanel * __fastcall CreateBlankPanel(TComponent * Owner)
|
||||
Panel->BevelKind = bkNone;
|
||||
return Panel;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
typedef bool (WINAPI * AllowDarkModeForWindowProc)(HWND Handle, bool Allow);
|
||||
AllowDarkModeForWindowProc AAllowDarkModeForWindow;
|
||||
bool AllowDarkModeForWindowLoaded = false;
|
||||
void AllowDarkModeForWindow(TWinControl * Control, bool Allow)
|
||||
{
|
||||
if (!AllowDarkModeForWindowLoaded)
|
||||
{
|
||||
HMODULE UxThemeLib = GetModuleHandle(L"UxTheme");
|
||||
if (DebugAlwaysTrue(UxThemeLib != NULL))
|
||||
{
|
||||
AAllowDarkModeForWindow =
|
||||
reinterpret_cast<AllowDarkModeForWindowProc>(GetProcAddress(UxThemeLib, MAKEINTRESOURCEA(133)));
|
||||
}
|
||||
AllowDarkModeForWindowLoaded = true;
|
||||
}
|
||||
|
||||
if ((AAllowDarkModeForWindow != NULL) &&
|
||||
DebugAlwaysTrue(Control->HandleAllocated()))
|
||||
{
|
||||
AAllowDarkModeForWindow(Control->Handle, Allow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ void __fastcall HookFormActivation(TCustomForm * Form);
|
||||
void __fastcall UnhookFormActivation(TCustomForm * Form);
|
||||
void __fastcall ShowFormNoActivate(TForm * Form);
|
||||
TPanel * __fastcall CreateBlankPanel(TComponent * Owner);
|
||||
void AllowDarkModeForWindow(TWinControl * Control, bool Allow);
|
||||
typedef void __fastcall (*TRescaleEvent)(TComponent * Sender, TObject * Token);
|
||||
void __fastcall SetRescaleFunction(
|
||||
TComponent * Component, TRescaleEvent OnRescale, TObject * Token = NULL, bool OwnsToken = false);
|
||||
|
||||
@@ -479,6 +479,7 @@ bool __fastcall TEditorList::IsDefaultList() const
|
||||
//---------------------------------------------------------------------------
|
||||
__fastcall TWinConfiguration::TWinConfiguration(): TCustomWinConfiguration()
|
||||
{
|
||||
ResetSysDarkTheme();
|
||||
FInvalidDefaultTranslationMessage = L"";
|
||||
FDDExtInstalled = -1;
|
||||
FBookmarks = new TBookmarks();
|
||||
@@ -566,6 +567,7 @@ void __fastcall TWinConfiguration::Default()
|
||||
FTemporaryDirectoryCleanup = true;
|
||||
FConfirmTemporaryDirectoryCleanup = true;
|
||||
FPreservePanelState = true;
|
||||
FDarkTheme = asAuto;
|
||||
FLastStoredSession = L"";
|
||||
// deliberately not being saved, so that when saving ad-hoc workspace,
|
||||
// we do not offer to overwrite the last saved workspace, what may be undesirable
|
||||
@@ -970,6 +972,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList)
|
||||
KEY(Bool, TemporaryDirectoryCleanup); \
|
||||
KEY(Bool, ConfirmTemporaryDirectoryCleanup); \
|
||||
KEY(Bool, PreservePanelState); \
|
||||
KEY(Integer, DarkTheme); \
|
||||
KEY(String, LastStoredSession); \
|
||||
KEY(Bool, AutoSaveWorkspace); \
|
||||
KEY(Bool, AutoSaveWorkspacePasswords); \
|
||||
@@ -2073,6 +2076,57 @@ void __fastcall TWinConfiguration::SetPreservePanelState(bool value)
|
||||
SET_CONFIG_PROPERTY(PreservePanelState);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::SetDarkTheme(TAutoSwitch value)
|
||||
{
|
||||
SET_CONFIG_PROPERTY_EX(DarkTheme, ConfigureInterface());
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static int __fastcall SysDarkTheme(HKEY RootKey)
|
||||
{
|
||||
std::unique_ptr<TRegistry> Registry(new TRegistry());
|
||||
Registry->RootKey = RootKey;
|
||||
UnicodeString ThemesPersonalizeKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
||||
UnicodeString AppsUseLightThemeValue = L"AppsUseLightTheme";
|
||||
int Result = -1;
|
||||
if (Registry->OpenKeyReadOnly(ThemesPersonalizeKey) &&
|
||||
Registry->ValueExists(AppsUseLightThemeValue))
|
||||
{
|
||||
Result = Registry->ReadBool(AppsUseLightThemeValue) ? 0 : 1;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::ResetSysDarkTheme()
|
||||
{
|
||||
FSysDarkTheme = -1;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TWinConfiguration::UseDarkTheme()
|
||||
{
|
||||
if (FSysDarkTheme < 0)
|
||||
{
|
||||
FSysDarkTheme = SysDarkTheme(HKEY_CURRENT_USER);
|
||||
if (FSysDarkTheme < 0)
|
||||
{
|
||||
FSysDarkTheme = SysDarkTheme(HKEY_LOCAL_MACHINE);
|
||||
if (FSysDarkTheme < 0)
|
||||
{
|
||||
FSysDarkTheme = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (WinConfiguration->DarkTheme)
|
||||
{
|
||||
case asOn:
|
||||
return true;
|
||||
case asOff:
|
||||
return false;
|
||||
default:
|
||||
return (FSysDarkTheme > 0);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::SetLastStoredSession(UnicodeString value)
|
||||
{
|
||||
SET_CONFIG_PROPERTY(LastStoredSession);
|
||||
@@ -2723,6 +2777,7 @@ void __fastcall TWinConfiguration::UpdateStaticUsage()
|
||||
Usage->Set(L"Beta", IsBeta);
|
||||
|
||||
Usage->Set(L"Interface", Interface);
|
||||
Usage->Set(L"ThemeDark", UseDarkTheme());
|
||||
Usage->Set(L"CustomCommandsCount", (FCustomCommandsDefaults ? 0 : FCustomCommandList->Count));
|
||||
Usage->Set(L"UsingLocationProfiles", UseLocationProfiles);
|
||||
Usage->Set(L"UsingMasterPassword", UseMasterPassword);
|
||||
|
||||
@@ -399,6 +399,8 @@ private:
|
||||
UnicodeString FDefaultTranslationFile;
|
||||
UnicodeString FInvalidDefaultTranslationMessage;
|
||||
bool FPreservePanelState;
|
||||
TAutoSwitch FDarkTheme;
|
||||
int FSysDarkTheme;
|
||||
UnicodeString FLastStoredSession;
|
||||
UnicodeString FLastWorkspace;
|
||||
bool FAutoSaveWorkspace;
|
||||
@@ -502,6 +504,7 @@ private:
|
||||
void __fastcall SetTemporaryDirectoryCleanup(bool value);
|
||||
void __fastcall SetConfirmTemporaryDirectoryCleanup(bool value);
|
||||
void __fastcall SetPreservePanelState(bool value);
|
||||
void __fastcall SetDarkTheme(TAutoSwitch value);
|
||||
void __fastcall SetLastStoredSession(UnicodeString value);
|
||||
void __fastcall SetAutoSaveWorkspace(bool value);
|
||||
void __fastcall SetAutoSaveWorkspacePasswords(bool value);
|
||||
@@ -635,6 +638,8 @@ public:
|
||||
UnicodeString __fastcall GetProvisionaryExtensionId(const UnicodeString & FileName);
|
||||
bool __fastcall IsDDExtRunning();
|
||||
bool __fastcall IsDDExtBroken();
|
||||
bool __fastcall UseDarkTheme();
|
||||
void __fastcall ResetSysDarkTheme();
|
||||
|
||||
static void __fastcall RestoreFont(const TFontConfiguration & Configuration, TFont * Font);
|
||||
static void __fastcall StoreFont(TFont * Font, TFontConfiguration & Configuration);
|
||||
@@ -688,6 +693,7 @@ public:
|
||||
__property bool TemporaryDirectoryCleanup = { read = FTemporaryDirectoryCleanup, write = SetTemporaryDirectoryCleanup };
|
||||
__property bool ConfirmTemporaryDirectoryCleanup = { read = FConfirmTemporaryDirectoryCleanup, write = SetConfirmTemporaryDirectoryCleanup };
|
||||
__property bool PreservePanelState = { read = FPreservePanelState, write = SetPreservePanelState };
|
||||
__property TAutoSwitch DarkTheme = { read = FDarkTheme, write = SetDarkTheme };
|
||||
__property UnicodeString LastStoredSession = { read = FLastStoredSession, write = SetLastStoredSession };
|
||||
__property UnicodeString LastWorkspace = { read = FLastWorkspace, write = FLastWorkspace };
|
||||
__property bool AutoSaveWorkspace = { read = FAutoSaveWorkspace, write = SetAutoSaveWorkspace };
|
||||
|
||||
Reference in New Issue
Block a user