1
0
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:
Martin Prikryl
2018-12-06 09:09:49 +00:00
parent 946d6440ed
commit 71340fa744
19 changed files with 358 additions and 47 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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();

View File

@@ -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");

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -3464,6 +3464,7 @@ end;
initialization
FixPlaySoundDelay;
RegisterTBXTheme('OfficeXP', TTBXOfficeXPTheme);
RegisterTBXTheme('DarkOfficeXP', TTBXDarkOfficeXPTheme);
TBXNexus := TTBXNexus.Create('OfficeXP');
TBXMenuAnimation := TTBXMenuAnimation.Create;

View File

@@ -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]);

View File

@@ -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.

View File

@@ -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;

View File

@@ -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 +

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 };