From 4969e3812fa4faad5c950aa28f6ae4e2642c5206 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Mon, 12 Jun 2023 05:28:18 -0700 Subject: [PATCH 01/11] Mac: Support Dark Mode in Advanced View --- clientgui/AdvancedFrame.cpp | 47 ++++++++++++++++++++++++++++++ clientgui/AdvancedFrame.h | 1 + clientgui/BOINCBaseFrame.cpp | 4 +++ clientgui/BOINCBaseFrame.h | 3 +- clientgui/BOINCListCtrl.cpp | 9 ++++-- clientgui/BOINCListCtrl.h | 1 + clientgui/ViewResources.cpp | 18 +++++++----- clientgui/ViewResources.h | 1 + clientgui/ViewStatistics.cpp | 23 ++++++++------- clientgui/ViewStatistics.h | 2 ++ clientgui/mac/templates/Info.plist | 2 -- 11 files changed, 88 insertions(+), 23 deletions(-) diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 4304a8cdd7b..93b111e1504 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -1980,6 +1980,53 @@ void CAdvancedFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { } +// On the Mac, we must destroy and recreate each wxListCtrl +// to properly transition between dark mode and regular mode +void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) { + CBOINCBaseView* theView = NULL;; + CBOINCListCtrl* theListCtrl = NULL; + long bottomItem; + wxTimerEvent timerEvent; + int currentPage = _GetCurrentViewPage(); + + StopTimers(); + SaveState(); + // Get the list copntrol's current scroll position + if ((currentPage > 0) && (currentPage <4)) { // CViewProjects = 1, CViewWork = 2, CViewTransfers = 3 + theView = (CBOINCBaseView*)(m_pNotebook->GetPage(currentPage)); + theListCtrl = theView->GetListCtrl(); + bottomItem = theListCtrl->GetTopItem() + theListCtrl->GetCountPerPage() - 1; + } + RepopulateNotebook(); + RestoreState(); + + // The last tab label ("Disk") is ellipsed here unless the window is resized + // TODO: figure out how to replace this hack with a proper fix + int x, y; + GetSize(&x, &y); + SetSize(x+1, y); + SetSize(x, y); + + // Scroll the recreated list control to the same row as before + if ((currentPage > 0) && (currentPage <4)) { + theView = (CBOINCBaseView*)(m_pNotebook->GetPage(currentPage)); + theView->FireOnListRender(timerEvent); + theListCtrl = theView->GetListCtrl(); + if (theListCtrl->GetCountPerPage() < theListCtrl->GetItemCount()) { + theListCtrl->EnsureVisible(bottomItem); + } + } + StartTimers(); + + CDlgEventLog* eventLog = wxGetApp().GetEventLog(); + if (eventLog) { + wxGetApp().OnEventLogClose(); // + delete eventLog; // eventLog->Destroy() creates a race condition if used here. + wxGetApp().DisplayEventLog(); + } +} + + void CAdvancedFrame::UpdateActivityModeControls( CC_STATUS& status ) { wxMenuBar* pMenuBar = GetMenuBar(); wxASSERT(pMenuBar); diff --git a/clientgui/AdvancedFrame.h b/clientgui/AdvancedFrame.h index 376dbd2b60a..0916beb4501 100644 --- a/clientgui/AdvancedFrame.h +++ b/clientgui/AdvancedFrame.h @@ -67,6 +67,7 @@ class CAdvancedFrame : public CBOINCBaseFrame void OnNetworkSelection( wxCommandEvent& event ); void OnSelectAll( wxCommandEvent& event ); + void OnDarkModeChanged( wxSysColourChangedEvent& event ); void OnMenuOpening( wxMenuEvent &event); void OnOptions( wxCommandEvent& event ); diff --git a/clientgui/BOINCBaseFrame.cpp b/clientgui/BOINCBaseFrame.cpp index 07c00ab5c95..d2a1bb6b36e 100644 --- a/clientgui/BOINCBaseFrame.cpp +++ b/clientgui/BOINCBaseFrame.cpp @@ -62,6 +62,7 @@ BEGIN_EVENT_TABLE (CBOINCBaseFrame, wxFrame) EVT_CLOSE(CBOINCBaseFrame::OnClose) EVT_MENU(ID_CLOSEWINDOW, CBOINCBaseFrame::OnCloseWindow) EVT_MENU(wxID_EXIT, CBOINCBaseFrame::OnExit) + EVT_SYS_COLOUR_CHANGED(CBOINCBaseFrame::OnDarkModeChanged) END_EVENT_TABLE () @@ -376,6 +377,9 @@ void CBOINCBaseFrame::OnExit(wxCommandEvent& WXUNUSED(event)) { wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnExit - Function End")); } +void CBOINCBaseFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) { +} + int CBOINCBaseFrame::GetCurrentViewPage() { return _GetCurrentViewPage(); diff --git a/clientgui/BOINCBaseFrame.h b/clientgui/BOINCBaseFrame.h index d7eab32e18b..23886cfaefe 100644 --- a/clientgui/BOINCBaseFrame.h +++ b/clientgui/BOINCBaseFrame.h @@ -64,6 +64,7 @@ class CBOINCBaseFrame : public wxFrame { virtual void OnClose( wxCloseEvent& event ); virtual void OnCloseWindow( wxCommandEvent& event ); virtual void OnExit( wxCommandEvent& event ); + virtual void OnDarkModeChanged( wxSysColourChangedEvent& event ); void OnWizardAttachProject( wxCommandEvent& event ); void OnWizardUpdate( wxCommandEvent& event ); @@ -107,7 +108,7 @@ class CBOINCBaseFrame : public wxFrame { virtual bool RestoreState(); virtual bool SaveState(); virtual bool CreateMenus(){return true;} - void ResetReminderTimers(); + void ResetReminderTimers(); protected: diff --git a/clientgui/BOINCListCtrl.cpp b/clientgui/BOINCListCtrl.cpp index 8c867eba9a7..0c02eb46de1 100644 --- a/clientgui/BOINCListCtrl.cpp +++ b/clientgui/BOINCListCtrl.cpp @@ -20,6 +20,7 @@ #endif #include "stdwx.h" +#include "BOINCGUIApp.h" #include "BOINCBaseView.h" #include "BOINCListCtrl.h" #include "Events.h" @@ -81,6 +82,8 @@ CBOINCListCtrl::CBOINCListCtrl( pView, iListWindowID, wxDefaultPosition, wxSize(-1, -1), iListWindowFlags ) { m_pParentView = pView; + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + m_isDarkMode = appearance.IsDark(); // Enable Zebra Striping EnableAlternateRowColours(true); @@ -522,7 +525,7 @@ void CBOINCListCtrl::DrawProgressBars() int n = (int)m_iRowsNeedingProgressBars.GetCount(); if (n <= 0) return; - wxColour progressColor = wxTheColourDatabase->Find(wxT("LIGHT BLUE")); + wxColour progressColor = wxTheColourDatabase->Find(m_isDarkMode ? wxT("DARK GREEN") : wxT("LIGHT BLUE")); wxBrush progressBrush(progressColor); numItems = GetItemCount(); @@ -604,8 +607,8 @@ void CBOINCListCtrl::DrawProgressBars() dc.SetPen(bkgd); dc.SetBrush(bkgd); #else - dc.SetPen(*wxWHITE_PEN); - dc.SetBrush(*wxWHITE_BRUSH); + dc.SetPen(m_isDarkMode ? *wxBLACK_PEN : *wxWHITE_PEN); + dc.SetBrush(m_isDarkMode ? *wxBLACK_BRUSH : *wxWHITE_BRUSH); #endif dc.DrawRectangle( rr ); diff --git a/clientgui/BOINCListCtrl.h b/clientgui/BOINCListCtrl.h index ac206b8b643..a8053e9e466 100644 --- a/clientgui/BOINCListCtrl.h +++ b/clientgui/BOINCListCtrl.h @@ -97,6 +97,7 @@ class CBOINCListCtrl : public LISTCTRL_BASE { CBOINCBaseView* m_pParentView; wxArrayInt m_iRowsNeedingProgressBars; + bool m_isDarkMode; #if ! USE_LIST_CACHE_HINT void OnMouseDown(wxMouseEvent& event); diff --git a/clientgui/ViewResources.cpp b/clientgui/ViewResources.cpp index aae67599795..0a8cd3f5332 100644 --- a/clientgui/ViewResources.cpp +++ b/clientgui/ViewResources.cpp @@ -47,6 +47,9 @@ CViewResources::CViewResources(wxNotebook* pNotebook) : { m_BOINCwasEmpty=false; + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + m_isDarkMode = appearance.IsDark(); + wxGridSizer* itemGridSizer = new wxGridSizer(2, 0, 3); wxASSERT(itemGridSizer); @@ -58,7 +61,7 @@ CViewResources::CViewResources(wxNotebook* pNotebook) : m_pieCtrlTotal->SetTransparent(true); m_pieCtrlTotal->SetHorLegendBorder(10); m_pieCtrlTotal->SetLabelFont(*wxSWISS_FONT); - m_pieCtrlTotal->SetLabelColour(wxColour(0,0,0)); + m_pieCtrlTotal->SetLabelColour(m_isDarkMode ? *wxWHITE : *wxBLACK); m_pieCtrlTotal->SetLabel(_("Total disk usage")); // initialize pie control @@ -79,7 +82,7 @@ CViewResources::CViewResources(wxNotebook* pNotebook) : m_pieCtrlBOINC->SetTransparent(true); m_pieCtrlBOINC->SetHorLegendBorder(10); m_pieCtrlBOINC->SetLabelFont(*wxSWISS_FONT); - m_pieCtrlBOINC->SetLabelColour(wxColour(0,0,0)); + m_pieCtrlTotal->SetLabelColour(m_isDarkMode ? *wxWHITE : *wxBLACK); m_pieCtrlBOINC->SetLabel(_("Disk usage by BOINC projects")); // initialize pie control @@ -260,7 +263,8 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(boinc_total, diskspace); part.SetLabel(_("used by BOINC: ") + diskspace); part.SetValue(boinc_total); - part.SetColour(wxColour(0,0,0)); + part.SetColour(m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0)); + part.SetColour(m_isDarkMode ? *wxWHITE : *wxBLACK); m_pieCtrlTotal->m_Series.Add(part); if (pDoc->disk_usage.d_allowed > 0) { @@ -270,7 +274,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(avail, diskspace); part.SetLabel(_("free, available to BOINC: ") + diskspace); part.SetValue(avail == 0 ? 1 : avail); - part.SetColour(wxColour(128, 128, 128)); + part.SetColour(m_isDarkMode ? wxColour(108, 108, 108) : wxColour(128, 128, 128)); m_pieCtrlTotal->m_Series.Add(part); double not_avail = free - avail; @@ -278,7 +282,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(not_avail, diskspace); part.SetLabel(_("free, not available to BOINC: ") + diskspace); part.SetValue(not_avail); - part.SetColour(wxColour(238,238,238)); + part.SetColour(m_isDarkMode ? wxColour(172,172,172) : wxColour(238,238,238)); m_pieCtrlTotal->m_Series.Add(part); } } else { @@ -288,7 +292,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(free, diskspace); part.SetLabel(_("free: ") + diskspace); part.SetValue(free); - part.SetColour(wxColour(238,238,238)); + part.SetColour(m_isDarkMode ? wxColour(172,172,172) : wxColour(238,238,238)); m_pieCtrlTotal->m_Series.Add(part); } @@ -297,7 +301,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(used_by_others, diskspace); part.SetLabel(_("used by other programs: ") + diskspace); part.SetValue(used_by_others); - part.SetColour(wxColour(192,192,192)); + part.SetColour(m_isDarkMode ? wxColour(140,140,140) : wxColour(192,192,192)); m_pieCtrlTotal->m_Series.Add(part); m_pieCtrlTotal->Refresh(); } diff --git a/clientgui/ViewResources.h b/clientgui/ViewResources.h index cb36af7b58f..29f208f1673 100644 --- a/clientgui/ViewResources.h +++ b/clientgui/ViewResources.h @@ -52,6 +52,7 @@ class CViewResources : public CBOINCBaseView wxPieCtrl* m_pieCtrlTotal; bool m_BOINCwasEmpty; + bool m_isDarkMode; virtual void UpdateSelection(); diff --git a/clientgui/ViewStatistics.cpp b/clientgui/ViewStatistics.cpp index 895c121d04d..4d1ff1accfc 100644 --- a/clientgui/ViewStatistics.cpp +++ b/clientgui/ViewStatistics.cpp @@ -155,6 +155,9 @@ CPaintStatistics::CPaintStatistics(wxWindow* parent, wxWindowID id, const wxPoin m_Legend_dY = 0; m_LegendDraw = true; + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + m_isDarkMode = appearance.IsDark(); + // Default colours m_pen_MarkerLineColour = wxColour(0, 0, 0); m_pen_ZoomRectColour = wxColour (128, 64, 95); @@ -165,21 +168,20 @@ CPaintStatistics::CPaintStatistics(wxWindow* parent, wxWindowID id, const wxPoin m_pen_AxisColourAutoZoom = wxColour(64, 128, 192); m_pen_AxisXColour = wxColour(64, 128, 192); m_pen_AxisYColour = wxColour(64, 128, 192); - m_pen_AxisXTextColour = wxColour(0, 0, 0); - m_pen_AxisYTextColour = wxColour(0, 0, 0); + m_pen_AxisXTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_AxisYTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); - m_brush_LegendColour = wxColour(235, 255, 255);//wxColour(220, 240, 255); + m_brush_LegendColour = m_isDarkMode ? wxColour(0, 64, 128) : wxColour(235, 255, 255); m_brush_LegendSelectColour = wxColour(192, 224, 255); m_pen_LegendSelectColour = wxColour(64, 128, 192); - m_pen_LegendSelectTextColour = wxColour(0, 0, 0); + m_pen_LegendSelectTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); m_pen_LegendColour = wxColour(64, 128, 192); - m_pen_LegendTextColour = wxColour(0, 0, 0); - - m_brush_MainColour = wxColour(255, 255, 255); + m_pen_LegendTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_brush_MainColour = m_isDarkMode ? wxColour(0,0,0) : wxColour(255, 255, 255); m_pen_MainColour = wxColour(64, 128, 192); - m_pen_HeadTextColour = wxColour(0, 0, 0); - m_pen_ProjectHeadTextColour = wxColour(0, 0, 0); + m_pen_HeadTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_ProjectHeadTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); m_pen_GraphTotalColour = wxColour(255, 0, 0); m_pen_GraphRACColour = wxColour(0, 160, 0); @@ -625,7 +627,8 @@ void CPaintStatistics::DrawLegend(wxDC &dc, PROJECTS* proj, CMainDocument* pDoc, dc.SetFont(m_font_bold); }else { dc.SetFont(m_font_standart_italic); - graphColour = wxColour(0, 0, 0); + graphColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + } x0 = wxCoord(m_WorkSpace_X_end) + buffer_x1 + wxCoord(7) + wxCoord(m_GraphPointWidth); diff --git a/clientgui/ViewStatistics.h b/clientgui/ViewStatistics.h index 2606425b735..48024a89d82 100644 --- a/clientgui/ViewStatistics.h +++ b/clientgui/ViewStatistics.h @@ -183,6 +183,8 @@ class CPaintStatistics : public wxWindow wxColour m_pen_GraphTotalHostColour; wxColour m_pen_GraphRACHostColour; + bool m_isDarkMode; + protected: void OnPaint(wxPaintEvent& event); void OnEraseBackground(wxEraseEvent & /*event*/){}; diff --git a/clientgui/mac/templates/Info.plist b/clientgui/mac/templates/Info.plist index 2d8d1a0d03d..97dca2ad082 100644 --- a/clientgui/mac/templates/Info.plist +++ b/clientgui/mac/templates/Info.plist @@ -22,7 +22,5 @@ %VERSION% NSPrincipalClass NSApplication - NSRequiresAquaSystemAppearance - From 6c14fec319b0eb097eb296cd92908e06b8b6986e Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Mon, 12 Jun 2023 05:54:50 -0700 Subject: [PATCH 02/11] remove trailing space --- clientgui/AdvancedFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 93b111e1504..5eae4ce819a 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -2020,7 +2020,7 @@ void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) CDlgEventLog* eventLog = wxGetApp().GetEventLog(); if (eventLog) { - wxGetApp().OnEventLogClose(); // + wxGetApp().OnEventLogClose(); delete eventLog; // eventLog->Destroy() creates a race condition if used here. wxGetApp().DisplayEventLog(); } From 3f0753a85b2a4e186a7d0ffbf117d76fe0c68b17 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Tue, 13 Jun 2023 06:45:19 -0700 Subject: [PATCH 03/11] Support Dark Mode for Notices and Disk tabs --- clientgui/AdvancedFrame.cpp | 10 ++++++---- clientgui/BOINCListCtrl.cpp | 2 +- clientgui/NoticeListCtrl.cpp | 24 ++++++++++++++++++++++-- clientgui/NoticeListCtrl.h | 1 + clientgui/common/wxPieCtrl.cpp | 12 ++++++++---- clientgui/common/wxPieCtrl.h | 1 + 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 5eae4ce819a..98f1878ee36 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -1992,8 +1992,8 @@ void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) StopTimers(); SaveState(); // Get the list copntrol's current scroll position - if ((currentPage > 0) && (currentPage <4)) { // CViewProjects = 1, CViewWork = 2, CViewTransfers = 3 - theView = (CBOINCBaseView*)(m_pNotebook->GetPage(currentPage)); + if ((currentPage == VW_PROJ) || (currentPage == VW_TASK) || (currentPage == VW_XFER)) { + theView = (CBOINCBaseView*)(m_pNotebook->GetPage(m_pNotebook->GetSelection())); theListCtrl = theView->GetListCtrl(); bottomItem = theListCtrl->GetTopItem() + theListCtrl->GetCountPerPage() - 1; } @@ -2008,14 +2008,16 @@ void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) SetSize(x, y); // Scroll the recreated list control to the same row as before - if ((currentPage > 0) && (currentPage <4)) { - theView = (CBOINCBaseView*)(m_pNotebook->GetPage(currentPage)); + if ((currentPage == VW_PROJ) || (currentPage == VW_TASK) || (currentPage == VW_XFER)) { + theView = (CBOINCBaseView*)(m_pNotebook->GetPage(m_pNotebook->GetSelection())); theView->FireOnListRender(timerEvent); theListCtrl = theView->GetListCtrl(); if (theListCtrl->GetCountPerPage() < theListCtrl->GetItemCount()) { theListCtrl->EnsureVisible(bottomItem); } } + // TODO: figure out how to preserve notices tab (currentPage == VW_NOTIF) scrolled position + StartTimers(); CDlgEventLog* eventLog = wxGetApp().GetEventLog(); diff --git a/clientgui/BOINCListCtrl.cpp b/clientgui/BOINCListCtrl.cpp index 0c02eb46de1..1c3525e043b 100644 --- a/clientgui/BOINCListCtrl.cpp +++ b/clientgui/BOINCListCtrl.cpp @@ -525,7 +525,7 @@ void CBOINCListCtrl::DrawProgressBars() int n = (int)m_iRowsNeedingProgressBars.GetCount(); if (n <= 0) return; - wxColour progressColor = wxTheColourDatabase->Find(m_isDarkMode ? wxT("DARK GREEN") : wxT("LIGHT BLUE")); + wxColour progressColor = m_isDarkMode ? wxColour(0, 64, 128) : wxColour(192, 217, 217); wxBrush progressBrush(progressColor); numItems = GetItemCount(); diff --git a/clientgui/NoticeListCtrl.cpp b/clientgui/NoticeListCtrl.cpp index 029b43bf657..8e2f37e6cf9 100644 --- a/clientgui/NoticeListCtrl.cpp +++ b/clientgui/NoticeListCtrl.cpp @@ -93,6 +93,9 @@ bool CNoticeListCtrl::Create( wxWindow* parent ) { #endif ////@end CNoticeListCtrl creation + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + m_isDarkMode = appearance.IsDark(); + wxBoxSizer *topsizer; topsizer = new wxBoxSizer(wxVERTICAL); @@ -101,7 +104,18 @@ bool CNoticeListCtrl::Create( wxWindow* parent ) { SetSizer(topsizer); m_itemCount = 0; - m_noticesBody = wxT(""); + if (m_isDarkMode){ + m_noticesBody = wxT(""); + } else { + m_noticesBody = wxT(""); + } + + // In Dark Mode, paint the windoe black immediately +#if wxUSE_WEBVIEW + m_browser->SetPage(m_noticesBody, wxEmptyString); +#else + m_browser->SetPage(m_noticesBody); +#endif // Display the fetching notices message until we have notices // to display or have determined that there are no notices. @@ -139,7 +153,13 @@ void CNoticeListCtrl::SetItemCount(int newCount) { wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced)); m_itemCount = newCount; - m_noticesBody = wxT(""); + + + if (m_isDarkMode){ + m_noticesBody = wxT(""); + } else { + m_noticesBody = wxT(""); + } for (i=0; iIsConnected()) { diff --git a/clientgui/NoticeListCtrl.h b/clientgui/NoticeListCtrl.h index e0b3adc0eb3..b0c6dade9dd 100644 --- a/clientgui/NoticeListCtrl.h +++ b/clientgui/NoticeListCtrl.h @@ -67,6 +67,7 @@ class CNoticeListCtrl: public wxWindow bool m_bNeedsReloading; int m_itemCount; wxString m_noticesBody; + bool m_isDarkMode; }; #endif diff --git a/clientgui/common/wxPieCtrl.cpp b/clientgui/common/wxPieCtrl.cpp index 70379257ce7..e3261d41f8c 100644 --- a/clientgui/common/wxPieCtrl.cpp +++ b/clientgui/common/wxPieCtrl.cpp @@ -48,14 +48,18 @@ wxPieCtrl::wxPieCtrl(wxWindow * parent, wxWindowID id, wxPoint pos, wxSize sz, long style, wxString name) :wxWindow(parent, id, pos, sz, style, name) { + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + m_isDarkMode = appearance.IsDark(); + if (m_isDarkMode) SetBackgroundColour(*wxBLACK); + m_ShowEdges=true; m_CanRepaint=true; - m_BackColour=*wxWHITE; + m_BackColour = m_isDarkMode ? *wxBLACK : *wxWHITE; m_padding=10; - m_TitleColour = wxColour(0,0,0); - m_LabelColour = *wxBLACK; - m_LegendBackColour = wxColour(255,255,0); + m_TitleColour = m_isDarkMode ? wxColour(255,255,255) : wxColour(0,0,0); + m_LabelColour = m_isDarkMode ? *wxWHITE : *wxBLACK; + m_LegendBackColour = m_isDarkMode ? wxColour(0, 0, 255) : wxColour(255,255,0); m_TitleFont = *wxSWISS_FONT; m_TitleFont.SetWeight(wxBOLD); m_LabelFont = *wxSWISS_FONT; diff --git a/clientgui/common/wxPieCtrl.h b/clientgui/common/wxPieCtrl.h index c42a61e25da..200791645fc 100644 --- a/clientgui/common/wxPieCtrl.h +++ b/clientgui/common/wxPieCtrl.h @@ -87,6 +87,7 @@ using wxWindow::SetTransparent; wxScrollBar* m_scrollBar; int m_Scrollbar_width; int m_firstlabelToDraw; + bool m_isDarkMode; //internal methods void GetPartAngles(wxArrayDouble & angles); From e2a130f648ae2d581d69da0b8fc0de1eef3327c0 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Wed, 14 Jun 2023 06:22:20 -0700 Subject: [PATCH 04/11] Continue implementng Dark Mode support --- clientgui/AdvancedFrame.cpp | 8 ++++++- clientgui/BOINCGUIApp.cpp | 3 +++ clientgui/BOINCGUIApp.h | 4 ++++ clientgui/BOINCListCtrl.cpp | 9 ++++--- clientgui/BOINCListCtrl.h | 1 - clientgui/NoticeListCtrl.cpp | 9 +++---- clientgui/NoticeListCtrl.h | 1 - clientgui/SkinManager.cpp | 3 +-- clientgui/ViewResources.cpp | 21 ++++++++--------- clientgui/ViewResources.h | 1 - clientgui/ViewStatistics.cpp | 22 ++++++++--------- clientgui/ViewStatistics.h | 2 -- clientgui/common/wxPieCtrl.cpp | 15 ++++++------ clientgui/common/wxPieCtrl.h | 1 - clientgui/sg_BoincSimpleFrame.cpp | 6 +++++ clientgui/sg_BoincSimpleFrame.h | 1 + clientgui/sg_DlgPreferences.cpp | 39 +++++++++++++++++++++++++++---- clientgui/sg_PanelBase.cpp | 4 ++++ 18 files changed, 96 insertions(+), 54 deletions(-) diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 98f1878ee36..7e65fa054ea 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -1982,6 +1982,7 @@ void CAdvancedFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { // On the Mac, we must destroy and recreate each wxListCtrl // to properly transition between dark mode and regular mode +// void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) { CBOINCBaseView* theView = NULL;; CBOINCListCtrl* theListCtrl = NULL; @@ -1991,7 +1992,11 @@ void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) StopTimers(); SaveState(); - // Get the list copntrol's current scroll position + + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + wxGetApp().SetIsDarkMode(appearance.IsDark()); + + // Get the list control's current scroll position if ((currentPage == VW_PROJ) || (currentPage == VW_TASK) || (currentPage == VW_XFER)) { theView = (CBOINCBaseView*)(m_pNotebook->GetPage(m_pNotebook->GetSelection())); theListCtrl = theView->GetListCtrl(); @@ -2002,6 +2007,7 @@ void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) // The last tab label ("Disk") is ellipsed here unless the window is resized // TODO: figure out how to replace this hack with a proper fix + int x, y; GetSize(&x, &y); SetSize(x+1, y); diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index bc889fabecb..e1c821aea66 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -75,6 +75,9 @@ bool CBOINCGUIApp::OnInit() { g_use_sandbox = false; #endif + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + m_isDarkMode = appearance.IsDark(); + s_bSkipExitConfirmation = false; m_bFilterEvents = false; m_bAboutDialogIsOpen = false; diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h index 4b4b6d69526..a93c79cd1b6 100644 --- a/clientgui/BOINCGUIApp.h +++ b/clientgui/BOINCGUIApp.h @@ -128,6 +128,8 @@ class CBOINCGUIApp : public wxApp { int m_bSafeMessageBoxDisplayed; + bool m_isDarkMode; + public: bool OnInit(); @@ -242,6 +244,8 @@ class CBOINCGUIApp : public wxApp { void SetAboutDialogIsOpen(bool set) { m_bAboutDialogIsOpen = set; } bool GetAboutDialogIsOpen() { return m_bAboutDialogIsOpen; } + void SetIsDarkMode (bool isDarkMode) { m_isDarkMode = isDarkMode; } + bool GetIsDarkMode() { return m_isDarkMode; } #ifdef __WXMAC__ // The following Cocoa routines are in CBOINCGUIApp.mm // diff --git a/clientgui/BOINCListCtrl.cpp b/clientgui/BOINCListCtrl.cpp index 1c3525e043b..278c2ee79aa 100644 --- a/clientgui/BOINCListCtrl.cpp +++ b/clientgui/BOINCListCtrl.cpp @@ -82,8 +82,6 @@ CBOINCListCtrl::CBOINCListCtrl( pView, iListWindowID, wxDefaultPosition, wxSize(-1, -1), iListWindowFlags ) { m_pParentView = pView; - wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); - m_isDarkMode = appearance.IsDark(); // Enable Zebra Striping EnableAlternateRowColours(true); @@ -505,6 +503,7 @@ void CBOINCListCtrl::DrawProgressBars() wxRect r, rr; int w = 0, x = 0, xx, yy, ww; int progressColumn = -1; + bool isDarkMode = wxGetApp().GetIsDarkMode(); if (m_pParentView->GetProgressColumn() >= 0) { progressColumn = m_pParentView->m_iColumnIDToColumnIndex[m_pParentView->GetProgressColumn()]; @@ -525,7 +524,7 @@ void CBOINCListCtrl::DrawProgressBars() int n = (int)m_iRowsNeedingProgressBars.GetCount(); if (n <= 0) return; - wxColour progressColor = m_isDarkMode ? wxColour(0, 64, 128) : wxColour(192, 217, 217); + wxColour progressColor = isDarkMode ? wxColour(0, 64, 128) : wxColour(192, 217, 217); wxBrush progressBrush(progressColor); numItems = GetItemCount(); @@ -607,8 +606,8 @@ void CBOINCListCtrl::DrawProgressBars() dc.SetPen(bkgd); dc.SetBrush(bkgd); #else - dc.SetPen(m_isDarkMode ? *wxBLACK_PEN : *wxWHITE_PEN); - dc.SetBrush(m_isDarkMode ? *wxBLACK_BRUSH : *wxWHITE_BRUSH); + dc.SetPen(isDarkMode ? *wxBLACK_PEN : *wxWHITE_PEN); + dc.SetBrush(isDarkMode ? *wxBLACK_BRUSH : *wxWHITE_BRUSH); #endif dc.DrawRectangle( rr ); diff --git a/clientgui/BOINCListCtrl.h b/clientgui/BOINCListCtrl.h index a8053e9e466..ac206b8b643 100644 --- a/clientgui/BOINCListCtrl.h +++ b/clientgui/BOINCListCtrl.h @@ -97,7 +97,6 @@ class CBOINCListCtrl : public LISTCTRL_BASE { CBOINCBaseView* m_pParentView; wxArrayInt m_iRowsNeedingProgressBars; - bool m_isDarkMode; #if ! USE_LIST_CACHE_HINT void OnMouseDown(wxMouseEvent& event); diff --git a/clientgui/NoticeListCtrl.cpp b/clientgui/NoticeListCtrl.cpp index 8e2f37e6cf9..5f799d6556e 100644 --- a/clientgui/NoticeListCtrl.cpp +++ b/clientgui/NoticeListCtrl.cpp @@ -93,9 +93,6 @@ bool CNoticeListCtrl::Create( wxWindow* parent ) { #endif ////@end CNoticeListCtrl creation - wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); - m_isDarkMode = appearance.IsDark(); - wxBoxSizer *topsizer; topsizer = new wxBoxSizer(wxVERTICAL); @@ -104,13 +101,13 @@ bool CNoticeListCtrl::Create( wxWindow* parent ) { SetSizer(topsizer); m_itemCount = 0; - if (m_isDarkMode){ + if (wxGetApp().GetIsDarkMode()){ m_noticesBody = wxT(""); } else { m_noticesBody = wxT(""); } - // In Dark Mode, paint the windoe black immediately + // In Dark Mode, paint the window black immediately #if wxUSE_WEBVIEW m_browser->SetPage(m_noticesBody, wxEmptyString); #else @@ -155,7 +152,7 @@ void CNoticeListCtrl::SetItemCount(int newCount) { m_itemCount = newCount; - if (m_isDarkMode){ + if (wxGetApp().GetIsDarkMode()){ m_noticesBody = wxT(""); } else { m_noticesBody = wxT(""); diff --git a/clientgui/NoticeListCtrl.h b/clientgui/NoticeListCtrl.h index b0c6dade9dd..e0b3adc0eb3 100644 --- a/clientgui/NoticeListCtrl.h +++ b/clientgui/NoticeListCtrl.h @@ -67,7 +67,6 @@ class CNoticeListCtrl: public wxWindow bool m_bNeedsReloading; int m_itemCount; wxString m_noticesBody; - bool m_isDarkMode; }; #endif diff --git a/clientgui/SkinManager.cpp b/clientgui/SkinManager.cpp index 10abf81a63a..ff9f9ac2ae1 100644 --- a/clientgui/SkinManager.cpp +++ b/clientgui/SkinManager.cpp @@ -380,7 +380,6 @@ void CSkinSimple::Clear() { m_iPanelOpacity = DEFAULT_OPACITY; } - int CSkinSimple::Parse(MIOFILE& in) { char buf[256]; std::string strBuffer; @@ -432,7 +431,7 @@ bool CSkinSimple::InitializeDelayedValidation() { ); m_DialogBackgroundImage.SetDefaults( wxT("dialog background"), (const char**)dialog_background_image_xpm, - wxT("255:255:255"), BKGD_ANCHOR_HORIZ_CENTER, BKGD_ANCHOR_VERT_CENTER + wxGetApp().GetIsDarkMode() ? wxT("0:0:0") : wxT("255:255:255"), BKGD_ANCHOR_HORIZ_CENTER, BKGD_ANCHOR_VERT_CENTER ); m_ProjectImage.SetDefaults( wxT("project"), (const char**)project_image_xpm diff --git a/clientgui/ViewResources.cpp b/clientgui/ViewResources.cpp index 0a8cd3f5332..aa8ba9ec896 100644 --- a/clientgui/ViewResources.cpp +++ b/clientgui/ViewResources.cpp @@ -45,11 +45,9 @@ CViewResources::CViewResources() CViewResources::CViewResources(wxNotebook* pNotebook) : CBOINCBaseView(pNotebook) { + bool isDarkMode = wxGetApp().GetIsDarkMode(); m_BOINCwasEmpty=false; - wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); - m_isDarkMode = appearance.IsDark(); - wxGridSizer* itemGridSizer = new wxGridSizer(2, 0, 3); wxASSERT(itemGridSizer); @@ -61,7 +59,7 @@ CViewResources::CViewResources(wxNotebook* pNotebook) : m_pieCtrlTotal->SetTransparent(true); m_pieCtrlTotal->SetHorLegendBorder(10); m_pieCtrlTotal->SetLabelFont(*wxSWISS_FONT); - m_pieCtrlTotal->SetLabelColour(m_isDarkMode ? *wxWHITE : *wxBLACK); + m_pieCtrlTotal->SetLabelColour(isDarkMode ? *wxWHITE : *wxBLACK); m_pieCtrlTotal->SetLabel(_("Total disk usage")); // initialize pie control @@ -82,7 +80,7 @@ CViewResources::CViewResources(wxNotebook* pNotebook) : m_pieCtrlBOINC->SetTransparent(true); m_pieCtrlBOINC->SetHorLegendBorder(10); m_pieCtrlBOINC->SetLabelFont(*wxSWISS_FONT); - m_pieCtrlTotal->SetLabelColour(m_isDarkMode ? *wxWHITE : *wxBLACK); + m_pieCtrlTotal->SetLabelColour(isDarkMode ? *wxWHITE : *wxBLACK); m_pieCtrlBOINC->SetLabel(_("Disk usage by BOINC projects")); // initialize pie control @@ -175,6 +173,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { wxString diskspace; static double project_total=0.0; unsigned int i; + bool isDarkMode = wxGetApp().GetIsDarkMode(); wxASSERT(pDoc); wxASSERT(wxDynamicCast(pDoc, CMainDocument)); @@ -263,8 +262,8 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(boinc_total, diskspace); part.SetLabel(_("used by BOINC: ") + diskspace); part.SetValue(boinc_total); - part.SetColour(m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0)); - part.SetColour(m_isDarkMode ? *wxWHITE : *wxBLACK); + part.SetColour(isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0)); + part.SetColour(isDarkMode ? *wxWHITE : *wxBLACK); m_pieCtrlTotal->m_Series.Add(part); if (pDoc->disk_usage.d_allowed > 0) { @@ -274,7 +273,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(avail, diskspace); part.SetLabel(_("free, available to BOINC: ") + diskspace); part.SetValue(avail == 0 ? 1 : avail); - part.SetColour(m_isDarkMode ? wxColour(108, 108, 108) : wxColour(128, 128, 128)); + part.SetColour(isDarkMode ? wxColour(108, 108, 108) : wxColour(128, 128, 128)); m_pieCtrlTotal->m_Series.Add(part); double not_avail = free - avail; @@ -282,7 +281,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(not_avail, diskspace); part.SetLabel(_("free, not available to BOINC: ") + diskspace); part.SetValue(not_avail); - part.SetColour(m_isDarkMode ? wxColour(172,172,172) : wxColour(238,238,238)); + part.SetColour(isDarkMode ? wxColour(172,172,172) : wxColour(238,238,238)); m_pieCtrlTotal->m_Series.Add(part); } } else { @@ -292,7 +291,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(free, diskspace); part.SetLabel(_("free: ") + diskspace); part.SetValue(free); - part.SetColour(m_isDarkMode ? wxColour(172,172,172) : wxColour(238,238,238)); + part.SetColour(isDarkMode ? wxColour(172,172,172) : wxColour(238,238,238)); m_pieCtrlTotal->m_Series.Add(part); } @@ -301,7 +300,7 @@ void CViewResources::OnListRender( wxTimerEvent& WXUNUSED(event) ) { FormatDiskSpace(used_by_others, diskspace); part.SetLabel(_("used by other programs: ") + diskspace); part.SetValue(used_by_others); - part.SetColour(m_isDarkMode ? wxColour(140,140,140) : wxColour(192,192,192)); + part.SetColour(isDarkMode ? wxColour(140,140,140) : wxColour(192,192,192)); m_pieCtrlTotal->m_Series.Add(part); m_pieCtrlTotal->Refresh(); } diff --git a/clientgui/ViewResources.h b/clientgui/ViewResources.h index 29f208f1673..cb36af7b58f 100644 --- a/clientgui/ViewResources.h +++ b/clientgui/ViewResources.h @@ -52,7 +52,6 @@ class CViewResources : public CBOINCBaseView wxPieCtrl* m_pieCtrlTotal; bool m_BOINCwasEmpty; - bool m_isDarkMode; virtual void UpdateSelection(); diff --git a/clientgui/ViewStatistics.cpp b/clientgui/ViewStatistics.cpp index 4d1ff1accfc..d1e2d9343e3 100644 --- a/clientgui/ViewStatistics.cpp +++ b/clientgui/ViewStatistics.cpp @@ -74,6 +74,7 @@ CPaintStatistics::CPaintStatistics(wxWindow* parent, wxWindowID id, const wxPoin { m_font_standart = *wxSWISS_FONT; m_font_bold = *wxSWISS_FONT; m_font_standart_italic = *wxSWISS_FONT; + bool isDarkMode = wxGetApp().GetIsDarkMode(); m_SelectedStatistic = show_user_total; heading = wxT(""); @@ -155,9 +156,6 @@ CPaintStatistics::CPaintStatistics(wxWindow* parent, wxWindowID id, const wxPoin m_Legend_dY = 0; m_LegendDraw = true; - wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); - m_isDarkMode = appearance.IsDark(); - // Default colours m_pen_MarkerLineColour = wxColour(0, 0, 0); m_pen_ZoomRectColour = wxColour (128, 64, 95); @@ -168,20 +166,20 @@ CPaintStatistics::CPaintStatistics(wxWindow* parent, wxWindowID id, const wxPoin m_pen_AxisColourAutoZoom = wxColour(64, 128, 192); m_pen_AxisXColour = wxColour(64, 128, 192); m_pen_AxisYColour = wxColour(64, 128, 192); - m_pen_AxisXTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); - m_pen_AxisYTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_AxisXTextColour = isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_AxisYTextColour = isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); - m_brush_LegendColour = m_isDarkMode ? wxColour(0, 64, 128) : wxColour(235, 255, 255); + m_brush_LegendColour = isDarkMode ? wxColour(0, 64, 128) : wxColour(235, 255, 255); m_brush_LegendSelectColour = wxColour(192, 224, 255); m_pen_LegendSelectColour = wxColour(64, 128, 192); - m_pen_LegendSelectTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_LegendSelectTextColour = isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); m_pen_LegendColour = wxColour(64, 128, 192); - m_pen_LegendTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); - m_brush_MainColour = m_isDarkMode ? wxColour(0,0,0) : wxColour(255, 255, 255); + m_pen_LegendTextColour = isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_brush_MainColour = isDarkMode ? wxColour(0,0,0) : wxColour(255, 255, 255); m_pen_MainColour = wxColour(64, 128, 192); - m_pen_HeadTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); - m_pen_ProjectHeadTextColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_HeadTextColour = isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + m_pen_ProjectHeadTextColour = isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); m_pen_GraphTotalColour = wxColour(255, 0, 0); m_pen_GraphRACColour = wxColour(0, 160, 0); @@ -627,7 +625,7 @@ void CPaintStatistics::DrawLegend(wxDC &dc, PROJECTS* proj, CMainDocument* pDoc, dc.SetFont(m_font_bold); }else { dc.SetFont(m_font_standart_italic); - graphColour = m_isDarkMode ? wxColour(255, 255, 255) : wxColour(0,0,0); + graphColour = wxGetApp().GetIsDarkMode() ? wxColour(255, 255, 255) : wxColour(0,0,0); } diff --git a/clientgui/ViewStatistics.h b/clientgui/ViewStatistics.h index 48024a89d82..2606425b735 100644 --- a/clientgui/ViewStatistics.h +++ b/clientgui/ViewStatistics.h @@ -183,8 +183,6 @@ class CPaintStatistics : public wxWindow wxColour m_pen_GraphTotalHostColour; wxColour m_pen_GraphRACHostColour; - bool m_isDarkMode; - protected: void OnPaint(wxPaintEvent& event); void OnEraseBackground(wxEraseEvent & /*event*/){}; diff --git a/clientgui/common/wxPieCtrl.cpp b/clientgui/common/wxPieCtrl.cpp index e3261d41f8c..35f12f1ccf8 100644 --- a/clientgui/common/wxPieCtrl.cpp +++ b/clientgui/common/wxPieCtrl.cpp @@ -10,6 +10,7 @@ ///////////////////////////////////////////////////////////////////////////// #include #include +#include "BOINCGUIApp.h" #include "wxPieCtrl.h" #include @@ -48,18 +49,18 @@ wxPieCtrl::wxPieCtrl(wxWindow * parent, wxWindowID id, wxPoint pos, wxSize sz, long style, wxString name) :wxWindow(parent, id, pos, sz, style, name) { - wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); - m_isDarkMode = appearance.IsDark(); - if (m_isDarkMode) SetBackgroundColour(*wxBLACK); + bool isDarkMode = wxGetApp().GetIsDarkMode(); + + if (isDarkMode) SetBackgroundColour(*wxBLACK); m_ShowEdges=true; m_CanRepaint=true; - m_BackColour = m_isDarkMode ? *wxBLACK : *wxWHITE; + m_BackColour = isDarkMode ? *wxBLACK : *wxWHITE; m_padding=10; - m_TitleColour = m_isDarkMode ? wxColour(255,255,255) : wxColour(0,0,0); - m_LabelColour = m_isDarkMode ? *wxWHITE : *wxBLACK; - m_LegendBackColour = m_isDarkMode ? wxColour(0, 0, 255) : wxColour(255,255,0); + m_TitleColour = isDarkMode ? wxColour(255,255,255) : wxColour(0,0,0); + m_LabelColour = isDarkMode ? *wxWHITE : *wxBLACK; + m_LegendBackColour = isDarkMode ? wxColour(0, 0, 255) : wxColour(255,255,0); m_TitleFont = *wxSWISS_FONT; m_TitleFont.SetWeight(wxBOLD); m_LabelFont = *wxSWISS_FONT; diff --git a/clientgui/common/wxPieCtrl.h b/clientgui/common/wxPieCtrl.h index 200791645fc..c42a61e25da 100644 --- a/clientgui/common/wxPieCtrl.h +++ b/clientgui/common/wxPieCtrl.h @@ -87,7 +87,6 @@ using wxWindow::SetTransparent; wxScrollBar* m_scrollBar; int m_Scrollbar_width; int m_firstlabelToDraw; - bool m_isDarkMode; //internal methods void GetPartAngles(wxArrayDouble & angles); diff --git a/clientgui/sg_BoincSimpleFrame.cpp b/clientgui/sg_BoincSimpleFrame.cpp index 7263cea4cae..cd24ef00d54 100644 --- a/clientgui/sg_BoincSimpleFrame.cpp +++ b/clientgui/sg_BoincSimpleFrame.cpp @@ -923,6 +923,12 @@ void CSimpleFrame::OnEventLog(wxCommandEvent& WXUNUSED(event)) { } +void CSimpleFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) { + wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); + wxGetApp().SetIsDarkMode(appearance.IsDark()); +} + + IMPLEMENT_DYNAMIC_CLASS(CSimpleGUIPanel, wxPanel) BEGIN_EVENT_TABLE(CSimpleGUIPanel, wxPanel) diff --git a/clientgui/sg_BoincSimpleFrame.h b/clientgui/sg_BoincSimpleFrame.h index 034898d0e84..8f5f5058526 100644 --- a/clientgui/sg_BoincSimpleFrame.h +++ b/clientgui/sg_BoincSimpleFrame.h @@ -123,6 +123,7 @@ class CSimpleFrame : public CBOINCBaseFrame void OnRefreshView( CFrameEvent& event ); void OnNotification( CFrameEvent& event ); void OnEventLog(wxCommandEvent& event); + void OnDarkModeChanged( wxSysColourChangedEvent& event ); void SetMsgsDlgOpen(CDlgMessages* newDlgPtr) { dlgMsgsPtr = newDlgPtr; } bool isMessagesDlgOpen() { return (dlgMsgsPtr != NULL); } diff --git a/clientgui/sg_DlgPreferences.cpp b/clientgui/sg_DlgPreferences.cpp index eb8ac2ad6b3..14f70ac7bf1 100644 --- a/clientgui/sg_DlgPreferences.cpp +++ b/clientgui/sg_DlgPreferences.cpp @@ -97,7 +97,8 @@ bool CPanelPreferences::Create() { m_backgroundBitmap = NULL; lastErrorCtrl = NULL; - stdTextBkgdColor = *wxWHITE; + + stdTextBkgdColor = wxGetApp().GetIsDarkMode() ? *wxBLACK : *wxWHITE; CreateControls(); @@ -446,6 +447,19 @@ void CPanelPreferences::MakeBackgroundBitmap() { if ( (w < sz.x) || (h < sz.y) ) { // Check to see if they need to be rescaled to fit in the window wxImage img = bmp.ConvertToImage(); + + if (wxGetApp().GetIsDarkMode()) { + // Darken the image + unsigned char *bgImagePixels = img.GetData(); // RGBRGBRGB... + for (int i=0; iGetPanelOpacity(); int image_weight = MAX_OPACITY - white_weight; + if (wxGetApp().GetIsDarkMode()) { // Darken the panel + white_weight /= 4; + white_weight /=4; + } // Workaround for CSimpleGUIPanel not reliably getting // Paint or EraseBackground events under Linux From ceb01f5e9ad918e3b24e9cdd2732574d5085e312 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Wed, 14 Jun 2023 17:34:22 -0700 Subject: [PATCH 05/11] Try to fix errors from CI builds --- clientgui/common/wxPieCtrl.cpp | 1 + clientgui/sg_DlgPreferences.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/clientgui/common/wxPieCtrl.cpp b/clientgui/common/wxPieCtrl.cpp index 35f12f1ccf8..12d9e6deaad 100644 --- a/clientgui/common/wxPieCtrl.cpp +++ b/clientgui/common/wxPieCtrl.cpp @@ -10,6 +10,7 @@ ///////////////////////////////////////////////////////////////////////////// #include #include +#include "stdwx.h" #include "BOINCGUIApp.h" #include "wxPieCtrl.h" #include diff --git a/clientgui/sg_DlgPreferences.cpp b/clientgui/sg_DlgPreferences.cpp index 14f70ac7bf1..a683290714c 100644 --- a/clientgui/sg_DlgPreferences.cpp +++ b/clientgui/sg_DlgPreferences.cpp @@ -97,7 +97,7 @@ bool CPanelPreferences::Create() { m_backgroundBitmap = NULL; lastErrorCtrl = NULL; - + stdTextBkgdColor = wxGetApp().GetIsDarkMode() ? *wxBLACK : *wxWHITE; CreateControls(); From 02c8887c13d2016668afe7dd9d33dfe5365d5020 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Thu, 15 Jun 2023 07:01:20 -0700 Subject: [PATCH 06/11] Continue implementng Dark Mode support --- clientgui/AdvancedFrame.cpp | 2 ++ clientgui/AdvancedFrame.h | 2 +- clientgui/BOINCBaseFrame.cpp | 4 ++- clientgui/BOINCBaseFrame.h | 2 +- clientgui/BOINCBaseView.cpp | 2 +- clientgui/BOINCBaseView.h | 2 +- clientgui/BOINCGUIApp.cpp | 3 ++ clientgui/BOINCGUIApp.h | 18 ++++++++++++ clientgui/BOINCListCtrl.cpp | 2 +- clientgui/BOINCListCtrl.h | 2 +- clientgui/NoticeListCtrl.cpp | 2 +- clientgui/NoticeListCtrl.h | 2 +- clientgui/SkinManager.cpp | 2 +- clientgui/SkinManager.h | 2 +- clientgui/ViewResources.cpp | 2 +- clientgui/ViewResources.h | 2 +- clientgui/ViewStatistics.cpp | 2 +- clientgui/ViewStatistics.h | 2 +- clientgui/sg_BoincSimpleFrame.cpp | 10 +++++++ clientgui/sg_BoincSimpleFrame.h | 2 +- clientgui/sg_DlgMessages.cpp | 49 ++++++++++++++++++++++++++++--- clientgui/sg_DlgMessages.h | 6 +++- clientgui/sg_DlgPreferences.cpp | 8 ++--- clientgui/sg_DlgPreferences.h | 2 +- clientgui/sg_PanelBase.cpp | 2 +- clientgui/sg_PanelBase.h | 2 +- 26 files changed, 108 insertions(+), 28 deletions(-) diff --git a/clientgui/AdvancedFrame.cpp b/clientgui/AdvancedFrame.cpp index 7e65fa054ea..a222049edd3 100644 --- a/clientgui/AdvancedFrame.cpp +++ b/clientgui/AdvancedFrame.cpp @@ -1984,6 +1984,7 @@ void CAdvancedFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { // to properly transition between dark mode and regular mode // void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) { +#if SUPPORTDARKMODE CBOINCBaseView* theView = NULL;; CBOINCListCtrl* theListCtrl = NULL; long bottomItem; @@ -2032,6 +2033,7 @@ void CAdvancedFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) delete eventLog; // eventLog->Destroy() creates a race condition if used here. wxGetApp().DisplayEventLog(); } +#endif // #if SUPPORTDARKMODE } diff --git a/clientgui/AdvancedFrame.h b/clientgui/AdvancedFrame.h index 0916beb4501..5300fb8f3a8 100644 --- a/clientgui/AdvancedFrame.h +++ b/clientgui/AdvancedFrame.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/BOINCBaseFrame.cpp b/clientgui/BOINCBaseFrame.cpp index d2a1bb6b36e..dbdd1a48165 100644 --- a/clientgui/BOINCBaseFrame.cpp +++ b/clientgui/BOINCBaseFrame.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -62,7 +62,9 @@ BEGIN_EVENT_TABLE (CBOINCBaseFrame, wxFrame) EVT_CLOSE(CBOINCBaseFrame::OnClose) EVT_MENU(ID_CLOSEWINDOW, CBOINCBaseFrame::OnCloseWindow) EVT_MENU(wxID_EXIT, CBOINCBaseFrame::OnExit) +#if SUPPORTDARKMODE EVT_SYS_COLOUR_CHANGED(CBOINCBaseFrame::OnDarkModeChanged) +#endif END_EVENT_TABLE () diff --git a/clientgui/BOINCBaseFrame.h b/clientgui/BOINCBaseFrame.h index 23886cfaefe..81c9b90de99 100644 --- a/clientgui/BOINCBaseFrame.h +++ b/clientgui/BOINCBaseFrame.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/BOINCBaseView.cpp b/clientgui/BOINCBaseView.cpp index 2d2b4049d0e..ad855914721 100644 --- a/clientgui/BOINCBaseView.cpp +++ b/clientgui/BOINCBaseView.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/BOINCBaseView.h b/clientgui/BOINCBaseView.h index b89a966dbe9..6bace5849c4 100644 --- a/clientgui/BOINCBaseView.h +++ b/clientgui/BOINCBaseView.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index e1c821aea66..7eb463fe525 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -75,8 +75,11 @@ bool CBOINCGUIApp::OnInit() { g_use_sandbox = false; #endif + m_isDarkMode = false; +#if SUPPORTDARKMODE wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); m_isDarkMode = appearance.IsDark(); +#endif s_bSkipExitConfirmation = false; m_bFilterEvents = false; diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h index a93c79cd1b6..96456fc69b7 100644 --- a/clientgui/BOINCGUIApp.h +++ b/clientgui/BOINCGUIApp.h @@ -34,6 +34,19 @@ #define BOINC_ADVANCEDGUI 1 #define BOINC_SIMPLEGUI 2 +// NOTE: MacOS automatically adjusts all standard OS-drawn UI items +// in Dark Mode, so BOINC must not modify their colors for Dark Mode. +// For MacOS, we adjust Dark Mode colors only for our custom UI items. +// If you implement Dark Mode support for another OS which requires +// BOINC to adjust standard UI items for Dark Mode, be sure to guard +// those changes so they do not affect the Mac implementation. +// +#if defined(__WXMAC__) +#define SUPPORTDARKMODE true +#else +#define SUPPORTDARKMODE false +#endif + class wxLogBOINC; class CBOINCBaseFrame; @@ -244,8 +257,13 @@ class CBOINCGUIApp : public wxApp { void SetAboutDialogIsOpen(bool set) { m_bAboutDialogIsOpen = set; } bool GetAboutDialogIsOpen() { return m_bAboutDialogIsOpen; } +#if SUPPORTDARKMODE void SetIsDarkMode (bool isDarkMode) { m_isDarkMode = isDarkMode; } bool GetIsDarkMode() { return m_isDarkMode; } +#else + void SetIsDarkMode (bool WXUNUSED(isDarkMode)) {} + bool GetIsDarkMode() { return false; } +#endif #ifdef __WXMAC__ // The following Cocoa routines are in CBOINCGUIApp.mm // diff --git a/clientgui/BOINCListCtrl.cpp b/clientgui/BOINCListCtrl.cpp index 278c2ee79aa..65d5b0cf0b9 100644 --- a/clientgui/BOINCListCtrl.cpp +++ b/clientgui/BOINCListCtrl.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/BOINCListCtrl.h b/clientgui/BOINCListCtrl.h index ac206b8b643..395f11a7d4f 100644 --- a/clientgui/BOINCListCtrl.h +++ b/clientgui/BOINCListCtrl.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2015 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/NoticeListCtrl.cpp b/clientgui/NoticeListCtrl.cpp index 5f799d6556e..be65187186d 100644 --- a/clientgui/NoticeListCtrl.cpp +++ b/clientgui/NoticeListCtrl.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/NoticeListCtrl.h b/clientgui/NoticeListCtrl.h index e0b3adc0eb3..e5615cc7a40 100644 --- a/clientgui/NoticeListCtrl.h +++ b/clientgui/NoticeListCtrl.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/SkinManager.cpp b/clientgui/SkinManager.cpp index ff9f9ac2ae1..46a31f0836d 100644 --- a/clientgui/SkinManager.cpp +++ b/clientgui/SkinManager.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/SkinManager.h b/clientgui/SkinManager.h index 5a877185d4c..f144d05becd 100644 --- a/clientgui/SkinManager.h +++ b/clientgui/SkinManager.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/ViewResources.cpp b/clientgui/ViewResources.cpp index aa8ba9ec896..4b5ed10741f 100644 --- a/clientgui/ViewResources.cpp +++ b/clientgui/ViewResources.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/ViewResources.h b/clientgui/ViewResources.h index cb36af7b58f..6a28f7af954 100644 --- a/clientgui/ViewResources.h +++ b/clientgui/ViewResources.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/ViewStatistics.cpp b/clientgui/ViewStatistics.cpp index d1e2d9343e3..0fb01712eab 100644 --- a/clientgui/ViewStatistics.cpp +++ b/clientgui/ViewStatistics.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/ViewStatistics.h b/clientgui/ViewStatistics.h index 2606425b735..ea4b361f278 100644 --- a/clientgui/ViewStatistics.h +++ b/clientgui/ViewStatistics.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/sg_BoincSimpleFrame.cpp b/clientgui/sg_BoincSimpleFrame.cpp index cd24ef00d54..5559fc612dd 100644 --- a/clientgui/sg_BoincSimpleFrame.cpp +++ b/clientgui/sg_BoincSimpleFrame.cpp @@ -48,6 +48,7 @@ #include "DlgOptions.h" #include "DlgDiagnosticLogFlags.h" #include "AdvancedFrame.h" +#include "NoticeListCtrl.h" #ifdef __WXMAC__ @@ -924,8 +925,17 @@ void CSimpleFrame::OnEventLog(wxCommandEvent& WXUNUSED(event)) { void CSimpleFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) { +#if SUPPORTDARKMODE wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); wxGetApp().SetIsDarkMode(appearance.IsDark()); + + CSkinManager* theSkinManagr = wxGetApp().GetSkinManager(); + theSkinManagr->ReloadSkin(theSkinManagr->GetSelectedSkin()); + + if (dlgMsgsPtr) { + dlgMsgsPtr->GetMsgsPanel()->RedrawNoticesListCtrl(); + } +#endif } diff --git a/clientgui/sg_BoincSimpleFrame.h b/clientgui/sg_BoincSimpleFrame.h index 8f5f5058526..33495c8d935 100644 --- a/clientgui/sg_BoincSimpleFrame.h +++ b/clientgui/sg_BoincSimpleFrame.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/sg_DlgMessages.cpp b/clientgui/sg_DlgMessages.cpp index dcc7c89d27b..2184cafe322 100644 --- a/clientgui/sg_DlgMessages.cpp +++ b/clientgui/sg_DlgMessages.cpp @@ -92,6 +92,7 @@ bool CPanelMessages::Create() ////@begin CPanelMessages member initialisation m_bProcessingRefreshEvent = false; ////@end CPanelMessages member initialisation + m_closeButton = NULL; CreateControls(); @@ -143,9 +144,11 @@ void CPanelMessages::CreateControls() wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL); - wxButton* itemButton44 = new wxButton(itemDialog1, wxID_OK, _("&Close"), wxDefaultPosition, wxDefaultSize); + if (!m_closeButton) { + m_closeButton = new wxButton(itemDialog1, wxID_OK, _("&Close"), wxDefaultPosition, wxDefaultSize); + } - itemBoxSizer4->Add(itemButton44, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + itemBoxSizer4->Add(m_closeButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); #ifdef __WXMAC__ // Don't let Close button overlap window's grow icon itemFlexGridSizer2->Add(itemBoxSizer4, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 12); @@ -205,6 +208,19 @@ void CPanelMessages::OnEraseBackground(wxEraseEvent& event){ if ( (w < sz.x) || (h < sz.y) ) { // Check to see if they need to be rescaled to fit in the window wxImage img = bmp.ConvertToImage(); + + if (wxGetApp().GetIsDarkMode()) { + // Darken the image + unsigned char *bgImagePixels = img.GetData(); // RGBRGBRGB... + for (int i=0; iUpdateUI(); +} + + /*! * CDlgMessages type definition */ diff --git a/clientgui/sg_DlgMessages.h b/clientgui/sg_DlgMessages.h index db0e19d0790..4756f07010c 100644 --- a/clientgui/sg_DlgMessages.h +++ b/clientgui/sg_DlgMessages.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -102,6 +102,8 @@ class CPanelMessages : public wxPanel /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_SIMPLE_HELP void OnButtonHelp( wxCommandEvent& event ); + void RedrawNoticesListCtrl(); + ////@end CPanelMessages event handler declarations ////@begin CPanelMessages member function declarations @@ -119,6 +121,7 @@ class CPanelMessages : public wxPanel wxStaticText* m_NoNoticesText; bool m_bFetchingNoticesTextWasDisplayed; bool m_bNoNoticesTextWasDisplayed; + wxButton* m_closeButton; }; @@ -151,6 +154,7 @@ class CDlgMessages : public wxDialog void OnRefresh() { m_pBackgroundPanel->OnRefresh(); } + CPanelMessages* GetMsgsPanel() { return m_pBackgroundPanel; } private: bool SaveState(); diff --git a/clientgui/sg_DlgPreferences.cpp b/clientgui/sg_DlgPreferences.cpp index a683290714c..62912a35771 100644 --- a/clientgui/sg_DlgPreferences.cpp +++ b/clientgui/sg_DlgPreferences.cpp @@ -491,8 +491,8 @@ void CPanelPreferences::MakeBackgroundBitmap() { break; } - // Select the desired bitmap (or its negative) into the - // memory DC so we can take the desired chunk of it. + // Select the desired bitmap (or its darkened version) into + // the memory DC so we can take the desired chunk of it. if (wxGetApp().GetIsDarkMode()) { // Darken the bitmap wxImage bgImage = bmp.ConvertToImage(); @@ -506,8 +506,8 @@ void CPanelPreferences::MakeBackgroundBitmap() { } } } - wxBitmap negative(bgImage); - memDC.SelectObject(negative); + wxBitmap darkened(bgImage); + memDC.SelectObject(darkened); } else { memDC.SelectObject(bmp); } diff --git a/clientgui/sg_DlgPreferences.h b/clientgui/sg_DlgPreferences.h index 10806e10855..161577721cc 100644 --- a/clientgui/sg_DlgPreferences.h +++ b/clientgui/sg_DlgPreferences.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/sg_PanelBase.cpp b/clientgui/sg_PanelBase.cpp index 97e80c59a9b..a482dc619d5 100644 --- a/clientgui/sg_PanelBase.cpp +++ b/clientgui/sg_PanelBase.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License diff --git a/clientgui/sg_PanelBase.h b/clientgui/sg_PanelBase.h index c20ab49ca26..c1e375ac98f 100644 --- a/clientgui/sg_PanelBase.h +++ b/clientgui/sg_PanelBase.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License From 862a1b4e8cc9985b5f34e7e4b85278928c408bbb Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Thu, 15 Jun 2023 07:32:37 -0700 Subject: [PATCH 07/11] Fix a memory leak --- clientgui/sg_DlgMessages.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clientgui/sg_DlgMessages.cpp b/clientgui/sg_DlgMessages.cpp index 2184cafe322..62ac194d813 100644 --- a/clientgui/sg_DlgMessages.cpp +++ b/clientgui/sg_DlgMessages.cpp @@ -365,6 +365,7 @@ bool CPanelMessages::OnRestoreState(wxConfigBase* /* pConfig */) { void CPanelMessages::RedrawNoticesListCtrl() { SetSizer(NULL); + m_pHtmlListPane->Destroy(); CreateControls(); m_pHtmlListPane->UpdateUI(); } From 3a5f3cc95ad4e33d772b855c9dcee05006a8c95c Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Thu, 15 Jun 2023 08:01:04 -0700 Subject: [PATCH 08/11] Continue implementing Dark Mode support --- clientgui/sg_DlgMessages.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/clientgui/sg_DlgMessages.cpp b/clientgui/sg_DlgMessages.cpp index 62ac194d813..6d86b3bb89b 100644 --- a/clientgui/sg_DlgMessages.cpp +++ b/clientgui/sg_DlgMessages.cpp @@ -125,7 +125,7 @@ void CPanelMessages::CreateControls() _("Fetching notices; please wait..."), wxPoint(20, 20), wxDefaultSize, 0 ); - m_FetchingNoticesText->SetBackgroundColour(*wxWHITE); + m_FetchingNoticesText->SetBackgroundColour(wxGetApp().GetIsDarkMode() ? *wxBLACK : *wxWHITE); itemFlexGridSizer2->Add(m_FetchingNoticesText, 0, wxEXPAND | wxLEFT | wxRIGHT, 5); m_NoNoticesText = new wxStaticText( @@ -133,7 +133,7 @@ void CPanelMessages::CreateControls() _("There are no notices at this time."), wxPoint(20, 20), wxDefaultSize, 0 ); - m_NoNoticesText->SetBackgroundColour(*wxWHITE); + m_NoNoticesText->SetBackgroundColour(wxGetApp().GetIsDarkMode() ? *wxBLACK : *wxWHITE); itemFlexGridSizer2->Add(m_NoNoticesText, 0, wxEXPAND | wxLEFT | wxRIGHT, 5); @@ -366,7 +366,27 @@ bool CPanelMessages::OnRestoreState(wxConfigBase* /* pConfig */) { void CPanelMessages::RedrawNoticesListCtrl() { SetSizer(NULL); m_pHtmlListPane->Destroy(); + m_FetchingNoticesText->Destroy(); + m_NoNoticesText->Destroy(); + bool fetchingNoticesTextWasDisplayed = m_bFetchingNoticesTextWasDisplayed; + bool noNoticesTextWasDisplayed = m_bNoNoticesTextWasDisplayed; + CreateControls(); + + m_bFetchingNoticesTextWasDisplayed = fetchingNoticesTextWasDisplayed; + if (fetchingNoticesTextWasDisplayed) { + m_bFetchingNoticesTextWasDisplayed = true; + m_FetchingNoticesText->Show(); + } + if (noNoticesTextWasDisplayed) { + m_bNoNoticesTextWasDisplayed = true; + m_NoNoticesText->Show(); + } + + if (m_bFetchingNoticesTextWasDisplayed || m_bNoNoticesTextWasDisplayed) { + Layout(); + } + m_pHtmlListPane->UpdateUI(); } From b025bb8ed1fb305f7047bc3f600e6b64694e1e29 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Fri, 16 Jun 2023 07:26:27 -0700 Subject: [PATCH 09/11] Continue implementing Dark Mode support on Mac --- clientgui/mac/MacBitmapComboBox.h | 3 ++- clientgui/sg_BoincSimpleFrame.cpp | 39 +++++++++++++++++++++++++++++-- clientgui/sg_BoincSimpleFrame.h | 3 +++ clientgui/sg_DlgMessages.cpp | 3 +++ clientgui/sg_DlgPreferences.cpp | 5 ++++ clientgui/sg_DlgPreferences.h | 2 ++ clientgui/sg_ProjectPanel.cpp | 4 ++-- clientgui/sg_ProjectPanel.h | 4 +++- clientgui/sg_TaskPanel.cpp | 9 ++++--- clientgui/sg_TaskPanel.h | 5 ++-- 10 files changed, 66 insertions(+), 11 deletions(-) diff --git a/clientgui/mac/MacBitmapComboBox.h b/clientgui/mac/MacBitmapComboBox.h index 3ec78009ed6..9de9cba0a02 100644 --- a/clientgui/mac/MacBitmapComboBox.h +++ b/clientgui/mac/MacBitmapComboBox.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -84,6 +84,7 @@ class CBOINCBitmapComboBox : public wxPanel wxString GetValue() { return m_ChoiceControl->GetStringSelection(); } wxString GetString(unsigned int n) const { return m_ChoiceControl->GetString(n); } wxString GetStringSelection() { return m_ChoiceControl->GetStringSelection(); } + int FindString(const wxString &s, bool bCase=false) { return m_ChoiceControl->FindString(s, bCase); } int Append(const wxString& item, const wxBitmap& bitmap); int Append(const wxString& item, const wxBitmap& bitmap, void *clientData); diff --git a/clientgui/sg_BoincSimpleFrame.cpp b/clientgui/sg_BoincSimpleFrame.cpp index 5559fc612dd..7830190e825 100644 --- a/clientgui/sg_BoincSimpleFrame.cpp +++ b/clientgui/sg_BoincSimpleFrame.cpp @@ -118,6 +118,7 @@ CSimpleFrame::CSimpleFrame(wxString title, wxIconBundle* icons, wxPoint position SetIcons(*icons); CreateMenus(); dlgMsgsPtr = NULL; + dlgPrefsPtr = NULL; m_pBackgroundPanel = new CSimpleGUIPanel(this); mainSizer = new wxBoxSizer(wxVERTICAL); mainSizer->Add(m_pBackgroundPanel, 1, wxLEFT | wxRIGHT | wxEXPAND, 0); @@ -631,7 +632,9 @@ void CSimpleFrame::OnPreferences(wxCommandEvent& WXUNUSED(event)) { CDlgPreferences dlg(GetParent()); if (dlg.OKToShow()) { + dlgPrefsPtr = &dlg; dlg.ShowModal(); + dlgPrefsPtr = NULL; } m_pBackgroundPanel->SetDlgOpen(false); @@ -929,12 +932,44 @@ void CSimpleFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) wxSystemAppearance appearance = wxSystemSettings::GetAppearance(); wxGetApp().SetIsDarkMode(appearance.IsDark()); - CSkinManager* theSkinManagr = wxGetApp().GetSkinManager(); - theSkinManagr->ReloadSkin(theSkinManagr->GetSelectedSkin()); + // Remember our task and project settings + wxString taskStr = m_pBackgroundPanel->m_taskPanel->GetSelectedTaskString(); + wxString projStr = m_pBackgroundPanel->m_projPanel->GetSelectedProjectString(); + + wxSizer* panelSizer = m_pBackgroundPanel->GetSizer(); + CSimpleTaskPanel* newTaskPanel = new CSimpleTaskPanel(m_pBackgroundPanel); + panelSizer->Replace(m_pBackgroundPanel->m_taskPanel, newTaskPanel); + m_pBackgroundPanel->m_taskPanel->Destroy(); + m_pBackgroundPanel->m_taskPanel = newTaskPanel; + m_pBackgroundPanel->m_taskPanel->ReskinInterface(); + + CSimpleProjectPanel* newProjectpanel = new CSimpleProjectPanel(m_pBackgroundPanel); + panelSizer->Replace(m_pBackgroundPanel->m_projPanel, newProjectpanel); + m_pBackgroundPanel->m_projPanel->Destroy(); + m_pBackgroundPanel->m_projPanel = newProjectpanel; + + m_pBackgroundPanel->Layout(); + + // Force a redraw in case a modal dialog is also open + m_pBackgroundPanel->m_taskPanel->UpdatePanel(false); + m_pBackgroundPanel->m_projPanel->UpdateInterface(); + + // Restore our task and project settings + int iTask = m_pBackgroundPanel->m_taskPanel->GetTaskSelectionCtrl()->FindString(taskStr); + m_pBackgroundPanel->m_taskPanel->GetTaskSelectionCtrl()->SetSelection(iTask); + int iProj = m_pBackgroundPanel->m_projPanel->GetProjectSelectionCtrl()->FindString(projStr); + m_pBackgroundPanel->m_projPanel->GetProjectSelectionCtrl()->SetSelection(iProj); + wxCommandEvent event; + m_pBackgroundPanel->m_taskPanel->OnTaskSelection(event); if (dlgMsgsPtr) { dlgMsgsPtr->GetMsgsPanel()->RedrawNoticesListCtrl(); } + + if (dlgPrefsPtr) { + dlgPrefsPtr->GetPrefsPanel()->MakeBackgroundBitmap(); + dlgPrefsPtr->Refresh(); + } #endif } diff --git a/clientgui/sg_BoincSimpleFrame.h b/clientgui/sg_BoincSimpleFrame.h index 33495c8d935..aaea1348b8d 100644 --- a/clientgui/sg_BoincSimpleFrame.h +++ b/clientgui/sg_BoincSimpleFrame.h @@ -29,6 +29,7 @@ class CSimpleTaskPanel; class CSimpleProjectPanel; class CSimpleTaskPanel; class CDlgMessages; +class CDlgPreferences; class CSimpleGUIPanel : public wxPanel { @@ -154,6 +155,8 @@ class CSimpleFrame : public CBOINCBaseFrame private: CDlgMessages* dlgMsgsPtr; + CDlgPreferences* dlgPrefsPtr; + wxBoxSizer* mainSizer; DECLARE_EVENT_TABLE() diff --git a/clientgui/sg_DlgMessages.cpp b/clientgui/sg_DlgMessages.cpp index 6d86b3bb89b..868c3e0df08 100644 --- a/clientgui/sg_DlgMessages.cpp +++ b/clientgui/sg_DlgMessages.cpp @@ -371,6 +371,9 @@ void CPanelMessages::RedrawNoticesListCtrl() { bool fetchingNoticesTextWasDisplayed = m_bFetchingNoticesTextWasDisplayed; bool noNoticesTextWasDisplayed = m_bNoNoticesTextWasDisplayed; + m_closeButton->Destroy(); + m_closeButton = NULL; + CreateControls(); m_bFetchingNoticesTextWasDisplayed = fetchingNoticesTextWasDisplayed; diff --git a/clientgui/sg_DlgPreferences.cpp b/clientgui/sg_DlgPreferences.cpp index 62912a35771..ff0c0b7f5d8 100644 --- a/clientgui/sg_DlgPreferences.cpp +++ b/clientgui/sg_DlgPreferences.cpp @@ -427,6 +427,11 @@ void CPanelPreferences::MakeBackgroundBitmap() { wxASSERT(pSkinSimple); wxASSERT(wxDynamicCast(pSkinSimple, CSkinSimple)); + if (m_backgroundBitmap) { + delete m_backgroundBitmap; + m_backgroundBitmap = NULL; + } + wxMemoryDC memDC; wxCoord w, h, x, y; diff --git a/clientgui/sg_DlgPreferences.h b/clientgui/sg_DlgPreferences.h index 161577721cc..76e027d136d 100644 --- a/clientgui/sg_DlgPreferences.h +++ b/clientgui/sg_DlgPreferences.h @@ -219,6 +219,8 @@ class CDlgPreferences: public wxDialog bool OKToShow() { return m_pBackgroundPanel->OKToShow(); } + CPanelPreferences* GetPrefsPanel() { return m_pBackgroundPanel; } + private: ////@begin CDlgPreferences member variables diff --git a/clientgui/sg_ProjectPanel.cpp b/clientgui/sg_ProjectPanel.cpp index c3b3d658599..dcaea98aba8 100644 --- a/clientgui/sg_ProjectPanel.cpp +++ b/clientgui/sg_ProjectPanel.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -78,7 +78,7 @@ CSimpleProjectPanel::CSimpleProjectPanel( wxWindow* parent ) : m_sSynchronizeToolTip = _("Synchronize projects with account manager system"); m_GotBGBitMap = false; // Can't be made until parent has been laid out. - SetForegroundColour(*wxBLACK); + SetForegroundColour(wxGetApp().GetIsDarkMode() ? *wxWHITE : *wxBLACK); wxBoxSizer* bSizer1; bSizer1 = new wxBoxSizer( wxVERTICAL ); diff --git a/clientgui/sg_ProjectPanel.h b/clientgui/sg_ProjectPanel.h index b07ec7b561d..c384ba38b07 100644 --- a/clientgui/sg_ProjectPanel.h +++ b/clientgui/sg_ProjectPanel.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -45,6 +45,8 @@ class CSimpleProjectPanel : public CSimplePanelBase ~CSimpleProjectPanel(); ProjectSelectionData* GetProjectSelectionData(); + wxString GetSelectedProjectString() { return m_ProjectSelectionCtrl->GetValue(); } + CBOINCBitmapComboBox* GetProjectSelectionCtrl() { return m_ProjectSelectionCtrl; } void UpdateInterface(); void ReskinInterface(); diff --git a/clientgui/sg_TaskPanel.cpp b/clientgui/sg_TaskPanel.cpp index c7d99ed2204..931b1fa0808 100644 --- a/clientgui/sg_TaskPanel.cpp +++ b/clientgui/sg_TaskPanel.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2022 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -53,7 +53,7 @@ CScrolledTextBox::CScrolledTextBox() { CScrolledTextBox::CScrolledTextBox( wxWindow* parent) : wxScrolledWindow( parent, ID_SGPROJECTDESCRIPTION, wxDefaultPosition, wxDefaultSize, wxVSCROLL) { - SetForegroundColour(*wxBLACK); + SetForegroundColour(wxGetApp().GetIsDarkMode() ? *wxWHITE : *wxBLACK); m_TextSizer = new wxBoxSizer( wxVERTICAL ); m_hLine = GetCharHeight(); @@ -462,7 +462,10 @@ CSimpleTaskPanel::CSimpleTaskPanel( wxWindow* parent ) : m_sNotAvailableString = _("Not available"); m_progressBarRect = NULL; - SetForegroundColour(*wxBLACK); + CSkinSimple* pSkinSimple = wxGetApp().GetSkinManager()->GetSimple(); + wxColour bgColor(*pSkinSimple->GetDialogBackgroundImage()->GetBackgroundColor()); + SetBackgroundColour(bgColor); + SetForegroundColour(wxGetApp().GetIsDarkMode() ? *wxWHITE : *wxBLACK); wxBoxSizer* bSizer1; bSizer1 = new wxBoxSizer( wxVERTICAL ); diff --git a/clientgui/sg_TaskPanel.h b/clientgui/sg_TaskPanel.h index 43e90fbc2ff..de9257289b4 100644 --- a/clientgui/sg_TaskPanel.h +++ b/clientgui/sg_TaskPanel.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -118,12 +118,13 @@ class CSimpleTaskPanel : public CSimplePanelBase TaskSelectionData* GetTaskSelectionData(); wxString GetSelectedTaskString() { return m_TaskSelectionCtrl->GetValue(); } + CBOINCBitmapComboBox* GetTaskSelectionCtrl() { return m_TaskSelectionCtrl; } void UpdatePanel(bool delayShow=false); + void OnTaskSelection(wxCommandEvent &event); wxRect* GetProgressRect(); void ReskinInterface(); private: - void OnTaskSelection(wxCommandEvent &event); void GetApplicationAndProjectNames(RESULT* result, wxString* appName, wxString* projName); wxString GetElapsedTimeString(double f); wxString GetTimeRemainingString(double f); From c439b67973601fa3a4aaa8276722f881df3ad71b Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Fri, 16 Jun 2023 07:32:22 -0700 Subject: [PATCH 10/11] Temporarily enable Dark Mode code on Linux --- clientgui/BOINCGUIApp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h index 96456fc69b7..04524c41064 100644 --- a/clientgui/BOINCGUIApp.h +++ b/clientgui/BOINCGUIApp.h @@ -41,7 +41,7 @@ // BOINC to adjust standard UI items for Dark Mode, be sure to guard // those changes so they do not affect the Mac implementation. // -#if defined(__WXMAC__) +#if (defined(__WXMAC__) || defined(__WXGTK__)) #define SUPPORTDARKMODE true #else #define SUPPORTDARKMODE false From 6a0ea0ce88d8aff48ea9c25afb51add68339fb92 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Sun, 18 Jun 2023 05:34:22 -0700 Subject: [PATCH 11/11] Linux: Fix Notices display in Dark Mode Mac: Ensure that the 3 buttons at bottom of Simple View are legible --- clientgui/NoticeListCtrl.cpp | 12 ++++++++++-- clientgui/sg_BoincSimpleFrame.cpp | 27 +++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/clientgui/NoticeListCtrl.cpp b/clientgui/NoticeListCtrl.cpp index be65187186d..28c4a9b82d8 100644 --- a/clientgui/NoticeListCtrl.cpp +++ b/clientgui/NoticeListCtrl.cpp @@ -102,7 +102,11 @@ bool CNoticeListCtrl::Create( wxWindow* parent ) { m_itemCount = 0; if (wxGetApp().GetIsDarkMode()){ +#if wxUSE_WEBVIEW m_noticesBody = wxT(""); +#else + m_noticesBody = wxT(""); +#endif } else { m_noticesBody = wxT(""); } @@ -153,9 +157,13 @@ void CNoticeListCtrl::SetItemCount(int newCount) { if (wxGetApp().GetIsDarkMode()){ - m_noticesBody = wxT(""); +#if wxUSE_WEBVIEW + m_noticesBody = wxT(""); +#else + m_noticesBody = wxT(""); +#endif } else { - m_noticesBody = wxT(""); + m_noticesBody = wxT(""); } for (i=0; iReplace(m_pBackgroundPanel->m_taskPanel, newTaskPanel); m_pBackgroundPanel->m_taskPanel->Destroy(); m_pBackgroundPanel->m_taskPanel = newTaskPanel; - m_pBackgroundPanel->m_taskPanel->ReskinInterface(); CSimpleProjectPanel* newProjectpanel = new CSimpleProjectPanel(m_pBackgroundPanel); panelSizer->Replace(m_pBackgroundPanel->m_projPanel, newProjectpanel); @@ -950,9 +949,7 @@ void CSimpleFrame::OnDarkModeChanged( wxSysColourChangedEvent& WXUNUSED(event) ) m_pBackgroundPanel->Layout(); - // Force a redraw in case a modal dialog is also open - m_pBackgroundPanel->m_taskPanel->UpdatePanel(false); - m_pBackgroundPanel->m_projPanel->UpdateInterface(); + m_pBackgroundPanel->ReskinInterface(); // Restore our task and project settings int iTask = m_pBackgroundPanel->m_taskPanel->GetTaskSelectionCtrl()->FindString(taskStr); @@ -1178,6 +1175,28 @@ void CSimpleGUIPanel::SetBackgroundBitmap() { wxMemoryDC srcDC(*srcBmp); dc.Blit(destX, destY, w, h, &srcDC, srcX, srcY, wxCOPY); +#ifdef __WXMAC__ + // In Dark Mode, MacOS makes button backgrounds partly tranparent + // rather than black. It uses a slightly darker rendition of the + // underlying bitmap, which can make the button's white text hard + // to read with some skins. So we force these button backgrounds + // to be dark gray. + if (wxGetApp().GetIsDarkMode()) { + wxPen oldPen = dc.GetPen(); + dc.SetPen(*wxBLACK); + wxBrush oldBrush = dc.GetBrush(); + dc.SetBrush(*wxBLACK_BRUSH); + wxRect r = m_NoticesButton->GetRect(); + dc.DrawRoundedRectangle(r, 5); + r = m_SuspendResumeButton->GetRect(); + dc.DrawRoundedRectangle(r, 5); + r = m_HelpButton->GetRect(); + dc.DrawRoundedRectangle(r, 5); + dc.SetPen(oldPen); + dc.SetBrush(oldBrush); + } +#endif + // dc.DrawBitmap(*pSkinSimple->GetBackgroundImage()->GetBitmap(), 0, 0, false); wxLogTrace(wxT("Function Start/End"), wxT("CSimpleGUIPanel::SetBackgroundBitmap - Function End"));