Skip to content

Commit

Permalink
Merge pull request picotorrent#1269 from make-42/feature/add-dark-mode
Browse files Browse the repository at this point in the history
Add dark mode!
  • Loading branch information
vktr authored May 18, 2023
2 parents 94eeb2f + 2e95b67 commit 79644e8
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 16 deletions.
5 changes: 4 additions & 1 deletion lang/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,8 @@
"export": "Export",
"magnet_link_s": "Magnet link(s)",
"torrent_file_s": "Torrent file(s)",
"exported_magnet_link_s": "Exported magnet link(s)"
"exported_magnet_link_s": "Exported magnet link(s)",
"theme": "Theme",
"light_theme": "Light",
"follow_system_theme": "System"
}
2 changes: 2 additions & 0 deletions res/dbmigrations/20220508103321_insert_theme_id.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INSERT INTO setting (key, value, default_value)
VALUES ('theme_id', NULL, '"system"');
Binary file added res/terminal-dark-theme.ico
Binary file not shown.
7 changes: 7 additions & 0 deletions src/picotorrent/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,18 @@ bool Application::OnInit()

auto cfg = std::make_shared<pt::Core::Configuration>(db);

// Load current locale
pt::UI::Translator& translator = pt::UI::Translator::GetInstance();
translator.LoadDatabase(env->GetCoreDbFilePath());
translator.SetLocale(
cfg->Get<std::string>("locale_name")
.value_or(env->GetCurrentLocale()));

// Load theme
if (cfg->IsDarkMode())
{
wxApp::MSWEnableDarkMode();
}

// Load plugins
for (auto& p : fs::directory_iterator(env->GetApplicationPath()))
Expand Down
27 changes: 27 additions & 0 deletions src/picotorrent/core/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "database.hpp"
#include "environment.hpp"

#include <Windows.h>

namespace fs = std::filesystem;

using pt::Core::Configuration;
Expand Down Expand Up @@ -214,3 +216,28 @@ void Configuration::UpsertListenInterface(Configuration::ListenInterface const&
stmt->Execute();
}
}

bool Configuration::IsSystemDarkMode()
{
bool systemUsesDarkTheme = false;
HKEY hKey = 0;
DWORD dwValue = 1;
DWORD dwBufSize = sizeof(dwValue);
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
RegQueryValueEx(hKey, TEXT("AppsUseLightTheme"), NULL, NULL, (LPBYTE)&dwValue, &dwBufSize);
RegCloseKey(hKey);
}
if (dwValue == 0)
{
systemUsesDarkTheme = true;
}
return systemUsesDarkTheme;
}

bool Configuration::IsDarkMode()
{
return Configuration::Get<std::string>("theme_id").value_or("system") == "light"
? false
: Configuration::IsSystemDarkMode();
}
4 changes: 4 additions & 0 deletions src/picotorrent/core/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ namespace Core

std::vector<DhtBootstrapNode> GetDhtBootstrapNodes();

// Dark mode
bool IsDarkMode();
bool IsSystemDarkMode();

std::vector<Filter> GetFilters();
std::optional<Filter> GetFilterById(int id);

Expand Down
2 changes: 2 additions & 0 deletions src/picotorrent/resources.rc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FileIcon ICON "..\\..\\res\\file.ico"

// Icons
ICO_TERMINAL ICON "..\\..\\res\\terminal.ico"
ICO_TERMINAL_DARK_THEME ICON "..\\..\\res\\terminal-dark-theme.ico"

// SQL migrations
20181208115043_create_setting_table DBMIGRATION "..\\..\\res\\dbmigrations\\20181208115043_create_setting_table.sql"
Expand All @@ -30,6 +31,7 @@ ICO_TERMINAL ICON "..\\..\\res\\terminal.ico"
20201107234213_setup_filters DBMIGRATION "..\\..\\res\\dbmigrations\\20201107234213_setup_filters.sql"
20201219222232_insert_connections_limit DBMIGRATION "..\\..\\res\\dbmigrations\\20201219222232_insert_connections_limit.sql"
20201227195100_insert_ipfilter_settings DBMIGRATION "..\\..\\res\\dbmigrations\\20201227195100_insert_ipfilter_settings.sql"
20220508103321_insert_theme_id DBMIGRATION "..\\..\\res\\dbmigrations\\20220508103321_insert_theme_id.sql"

VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILE_VERSION
Expand Down
7 changes: 4 additions & 3 deletions src/picotorrent/ui/console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
#include "ids.hpp"
#include "models/torrentlistmodel.hpp"
#include "torrentlistview.hpp"
#include "../core/configuration.hpp"

using pt::UI::Console;

wxDEFINE_EVENT(ptEVT_FILTER_CHANGED, wxCommandEvent);

Console::Console(wxWindow* parent, wxWindowID id, pt::UI::Models::TorrentListModel* model)
Console::Console(wxWindow* parent, wxWindowID id, pt::UI::Models::TorrentListModel* model, bool isDarkMode)
: wxPanel(parent, id),
m_input(new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_LEFT | wxTE_PROCESS_ENTER)),
m_model(model)
{
m_input->SetFont(
wxFont(9, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Consolas")));

wxIcon funnel(L"ICO_TERMINAL", wxBITMAP_TYPE_ICO_RESOURCE, FromDIP(16), FromDIP(16));
wxIcon funnel(isDarkMode ? L"ICO_TERMINAL_DARK_THEME" : L"ICO_TERMINAL", wxBITMAP_TYPE_ICO_RESOURCE, FromDIP(16), FromDIP(16));

int i = FromDIP(16);
printf("%d", i);
Expand All @@ -26,7 +27,7 @@ Console::Console(wxWindow* parent, wxWindowID id, pt::UI::Models::TorrentListMod
sizer->Add(new wxStaticBitmap(this, wxID_ANY, funnel), 0, wxALIGN_CENTER | wxLEFT, FromDIP(4));
sizer->Add(m_input, 1, wxEXPAND | wxALL, FromDIP(4));

this->SetBackgroundColour(*wxWHITE);
this->SetBackgroundColour(isDarkMode ? wxColour(32,32,32) : wxColour(255,255,255));
this->SetSizerAndFit(sizer);

this->Bind(
Expand Down
4 changes: 3 additions & 1 deletion src/picotorrent/ui/console.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <memory>

#include "../core/configuration.hpp"

wxDECLARE_EVENT(ptEVT_FILTER_CHANGED, wxCommandEvent);

namespace pt::UI::Models { class TorrentListModel; }
Expand All @@ -16,7 +18,7 @@ namespace pt::UI
class Console : public wxPanel
{
public:
Console(wxWindow* parent, wxWindowID id, Models::TorrentListModel* model);
Console(wxWindow* parent, wxWindowID id, Models::TorrentListModel* model, bool isDarkMode);
void SetText(std::string const& text);

private:
Expand Down
28 changes: 28 additions & 0 deletions src/picotorrent/ui/dialogs/preferencesgeneralpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ PreferencesGeneralPage::PreferencesGeneralPage(wxWindow* parent, std::shared_ptr
wxStaticBoxSizer* uiSizer = new wxStaticBoxSizer(wxVERTICAL, this, i18n("user_interface"));
wxFlexGridSizer* uiGrid = new wxFlexGridSizer(2, FromDIP(10), FromDIP(10));
m_language = new wxChoice(uiSizer->GetStaticBox(), wxID_ANY);
m_theme = new wxChoice(uiSizer->GetStaticBox(), wxID_ANY);
uiGrid->AddGrowableCol(1, 1);
uiGrid->Add(new wxStaticText(uiSizer->GetStaticBox(), wxID_ANY, i18n("language")), 0, wxALIGN_CENTER_VERTICAL);
uiGrid->Add(m_language, 1, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
uiGrid->Add(new wxStaticText(uiSizer->GetStaticBox(), wxID_ANY, i18n("theme")), 0, wxALIGN_CENTER_VERTICAL);
uiGrid->Add(m_theme, 1, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
uiSizer->Add(uiGrid, 1, wxEXPAND | wxALL, FromDIP(5));

wxStaticBoxSizer* miscSizer = new wxStaticBoxSizer(wxVERTICAL, this, i18n("miscellaneous"));
Expand Down Expand Up @@ -144,6 +147,17 @@ PreferencesGeneralPage::PreferencesGeneralPage(wxWindow* parent, std::shared_ptr
m_language->SetSelection(pos);
}
}

m_theme->Append(i18n("follow_system_theme"), new ClientData<std::string>("system"));
m_theme->Append(i18n("light_theme"), new ClientData<std::string>("light"));
if (m_cfg->Get<std::string>("theme_id").value_or("system") == "light")
{
m_theme->SetSelection(1);
}
else
{
m_theme->SetSelection(0);
}

m_labelColor->SetValue(m_cfg->Get<bool>("use_label_as_list_bgcolor").value());
m_skipAddTorrentDialog->SetValue(m_cfg->Get<bool>("skip_add_torrent_dialog").value());
Expand Down Expand Up @@ -191,6 +205,11 @@ void PreferencesGeneralPage::Save(bool* restartRequired)
? reinterpret_cast<ClientData<std::string>*>(m_language->GetClientObject(langIndex))
: nullptr;

int themeIndex = m_theme->GetSelection();
ClientData<std::string> *themeData = themeIndex >= 0
? reinterpret_cast<ClientData<std::string> *>(m_theme->GetClientObject(themeIndex))
: nullptr;

int startPosIndex = m_startPosition->GetSelection();
ClientData<Configuration::WindowState>* startPosData = reinterpret_cast<ClientData<Configuration::WindowState>*>(m_startPosition->GetClientObject(startPosIndex));

Expand All @@ -204,6 +223,15 @@ void PreferencesGeneralPage::Save(bool* restartRequired)
m_cfg->Set("locale_name", langData->GetValue());
}

if (themeData != nullptr)
{
if (themeData->GetValue() != m_cfg->Get<std::string>("theme_id"))
{
*restartRequired = true;
}
m_cfg->Set("theme_id", themeData->GetValue());
}

if (startPosData != nullptr)
{
m_cfg->Set("start_position", static_cast<int>(startPosData->GetValue()));
Expand Down
1 change: 1 addition & 0 deletions src/picotorrent/ui/dialogs/preferencesgeneralpage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace Dialogs
std::shared_ptr<Core::Configuration> m_cfg;

wxChoice* m_language;
wxChoice* m_theme;
wxCheckBox* m_labelColor;
wxCheckBox* m_skipAddTorrentDialog;
wxCheckBox* m_autoStart;
Expand Down
2 changes: 1 addition & 1 deletion src/picotorrent/ui/mainframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ MainFrame::MainFrame(std::shared_ptr<pt::Core::Environment> env, std::shared_ptr
m_menuItemFilters(nullptr),
m_ipc(std::make_unique<IPC::Server>(this))
{
m_console = new Console(this, wxID_ANY, m_torrentListModel);
m_console = new Console(this, wxID_ANY, m_torrentListModel, m_cfg->IsDarkMode());

m_splitter->SetWindowStyleFlag(
m_splitter->GetWindowStyleFlag() | wxSP_LIVE_UPDATE);
Expand Down
8 changes: 5 additions & 3 deletions src/picotorrent/ui/torrentdetailsoverviewpanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "../bittorrent/torrenthandle.hpp"
#include "../bittorrent/torrentstatus.hpp"
#include "../core/utils.hpp"
#include "../core/configuration.hpp"
#include "translator.hpp"
#include "widgets/pieceprogressbar.hpp"

Expand Down Expand Up @@ -84,10 +85,11 @@ class CopyableStaticText : public wxStaticText
}
};

TorrentDetailsOverviewPanel::TorrentDetailsOverviewPanel(wxWindow* parent, wxWindowID id, int cols, bool showPieceProgress)
TorrentDetailsOverviewPanel::TorrentDetailsOverviewPanel(wxWindow* parent, wxWindowID id, bool isDarkMode, int cols, bool showPieceProgress)
: wxScrolledWindow(parent, id),
m_pieceProgress(nullptr),
m_name(new CopyableStaticText(this)),
m_isDarkMode(isDarkMode),
m_infoHash(new CopyableStaticText(this)),
m_savePath(new CopyableStaticText(this)),
m_pieces(new CopyableStaticText(this)),
Expand Down Expand Up @@ -141,7 +143,7 @@ TorrentDetailsOverviewPanel::TorrentDetailsOverviewPanel(wxWindow* parent, wxWin

if (showPieceProgress)
{
m_pieceProgress = new Widgets::PieceProgressBar(this, wxID_ANY);
m_pieceProgress = new Widgets::PieceProgressBar(this, wxID_ANY, m_isDarkMode);
m_mainSizer->Add(m_pieceProgress, 0, wxEXPAND | wxTOP | wxRIGHT | wxLEFT, FromDIP(5));
}

Expand Down Expand Up @@ -247,7 +249,7 @@ void TorrentDetailsOverviewPanel::UpdateView(int cols, bool showPieceProgress)
{
if (showPieceProgress && m_pieceProgress == nullptr)
{
m_pieceProgress = new Widgets::PieceProgressBar(this, wxID_ANY);
m_pieceProgress = new Widgets::PieceProgressBar(this, wxID_ANY, m_isDarkMode);
m_mainSizer->Insert(0, m_pieceProgress, 0, wxEXPAND | wxTOP | wxRIGHT | wxLEFT, FromDIP(5));
}
else if (!showPieceProgress && m_pieceProgress != nullptr)
Expand Down
5 changes: 4 additions & 1 deletion src/picotorrent/ui/torrentdetailsoverviewpanel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <wx/wx.h>
#endif

#include "../core/configuration.hpp"

class wxFlexGridSizer;

namespace pt::UI::Widgets { class PieceProgressBar; }
Expand All @@ -20,7 +22,7 @@ namespace UI
class TorrentDetailsOverviewPanel : public wxScrolledWindow
{
public:
TorrentDetailsOverviewPanel(wxWindow* parent, wxWindowID id, int cols = 2, bool showPieceProgress = true);
TorrentDetailsOverviewPanel(wxWindow* parent, wxWindowID id, bool isDarkMode, int cols = 2, bool showPieceProgress = true);

void Refresh(BitTorrent::TorrentHandle* torrent);
void Reset();
Expand All @@ -42,6 +44,7 @@ namespace UI
wxStaticText* m_lastUpload;
wxStaticText* m_totalDownload;
wxStaticText* m_totalUpload;
bool m_isDarkMode;
};
}
}
2 changes: 1 addition & 1 deletion src/picotorrent/ui/torrentdetailsview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using pt::UI::TorrentDetailsView;
TorrentDetailsView::TorrentDetailsView(wxWindow* parent, wxWindowID id, std::shared_ptr<pt::Core::Configuration> cfg)
: wxNotebook(parent, id),
m_cfg(cfg),
m_overview(new TorrentDetailsOverviewPanel(this, wxID_ANY)),
m_overview(new TorrentDetailsOverviewPanel(this, wxID_ANY, cfg->IsDarkMode())),
m_files(new TorrentDetailsFilesPanel(this, wxID_ANY)),
m_peers(new TorrentDetailsPeersPanel(this, wxID_ANY)),
m_trackers(new TorrentDetailsTrackersPanel(this, wxID_ANY))
Expand Down
10 changes: 7 additions & 3 deletions src/picotorrent/ui/widgets/pieceprogressbar.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
#include "pieceprogressbar.hpp"

#include "../../core/configuration.hpp"

#include <wx/dcbuffer.h>
#include <wx/colour.h>

namespace lt = libtorrent;
using pt::UI::Widgets::PieceProgressBar;

PieceProgressBar::PieceProgressBar(wxWindow* parent, wxWindowID id, lt::typed_bitfield<lt::piece_index_t> field)
PieceProgressBar::PieceProgressBar(wxWindow* parent, wxWindowID id, bool isDarkMode, lt::typed_bitfield<lt::piece_index_t> field)
: wxPanel(parent, id, wxDefaultPosition, wxSize(-1, parent->FromDIP(15)), wxTAB_TRAVERSAL | wxNO_BORDER | wxBG_STYLE_PAINT),
m_bitfield(field)
{
Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(PieceProgressBar::OnEraseBackground));
Connect(wxEVT_PAINT, wxPaintEventHandler(PieceProgressBar::OnPaint));
Connect(wxEVT_SIZE, wxSizeEventHandler(PieceProgressBar::OnSize));
m_bgColor = isDarkMode ? wxColour(32,32,32) : wxColour(255,255,255);
}

void PieceProgressBar::UpdateBitfield(lt::typed_bitfield<lt::piece_index_t> const& field)
Expand Down Expand Up @@ -46,7 +50,7 @@ void PieceProgressBar::RenderProgress(wxDC& dc)
wxMemoryDC memDC;

memDC.SelectObject(prg);
memDC.SetBrush(*wxWHITE);
memDC.SetBrush(m_bgColor);
memDC.SetPen(darkBorder);
memDC.DrawRectangle({ 0, 0 }, prg.GetSize());

Expand All @@ -71,7 +75,7 @@ void PieceProgressBar::RenderProgress(wxDC& dc)
}
else
{
dc.SetBrush(*wxWHITE);
dc.SetBrush(m_bgColor);
dc.SetPen(wxColor(190, 190, 190));
dc.DrawRectangle(this->GetClientRect());
}
Expand Down
7 changes: 5 additions & 2 deletions src/picotorrent/ui/widgets/pieceprogressbar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/colour.h>

#include <libtorrent/bitfield.hpp>
#include <libtorrent/fwd.hpp>

#include "../../core/configuration.hpp"

namespace pt::UI::Widgets
{
class PieceProgressBar : public wxPanel
{
public:
PieceProgressBar(wxWindow* parent, wxWindowID id, libtorrent::typed_bitfield<libtorrent::piece_index_t> field = {});
PieceProgressBar(wxWindow* parent, wxWindowID id, bool isDarkMode, libtorrent::typed_bitfield<libtorrent::piece_index_t> field = {});
void UpdateBitfield(libtorrent::typed_bitfield<libtorrent::piece_index_t> const& field);

protected:
Expand All @@ -23,7 +26,7 @@ namespace pt::UI::Widgets

private:
void RenderProgress(wxDC& dc);

wxColour m_bgColor;
libtorrent::typed_bitfield<libtorrent::piece_index_t> m_bitfield;
};
}

0 comments on commit 79644e8

Please sign in to comment.