Skip to content

Commit 09cd844

Browse files
authored
Merge pull request #3684 from xdustinface/backport-ui-redesign
qt: Backport UI redesign to v0.16.x
2 parents d428779 + 0969c2d commit 09cd844

105 files changed

Lines changed: 6876 additions & 4018 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ src/dash-tx
1313
src/test/test_dash
1414
src/test/test_dash_fuzzy
1515
src/qt/test/test_dash-qt
16+
src/qt/res/css/colors/*
1617
src/bench/bench_dash
1718

1819
# autoreconf

contrib/dash-qt.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
FORMS += \
22
../src/qt/forms/aboutdialog.ui \
33
../src/qt/forms/addressbookpage.ui \
4+
../src/qt/forms/appearancewidget.ui \
45
../src/qt/forms/askpassphrasedialog.ui \
56
../src/qt/forms/coincontroldialog.ui \
67
../src/qt/forms/debugwindow.ui \
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#!/usr/bin/env python3
2+
#
3+
# update-css-files.py creates color analyse files in css/colors and updates the
4+
# `<colors></colors>` section in all css files.
5+
#
6+
# Copyright (c) 2020 The Dash Core developers
7+
# Distributed under the MIT/X11 software license, see the accompanying
8+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
9+
10+
from pathlib import Path
11+
import re
12+
import subprocess
13+
import sys
14+
15+
MATCH_REPLACE = '<colors>.+?</colors>'
16+
MATCH_COLORS = '#(?:[0-9a-fA-F]{2}){2,4}|#(?:[0-9a-f]{1}){3}'
17+
18+
def error(msg):
19+
exit('\nERROR: {}\n'.format(msg))
20+
21+
def parse_css(file_css):
22+
# Temporarily
23+
state = 0
24+
selectors = []
25+
26+
# Results
27+
by_attribute = {}
28+
by_color = {}
29+
30+
for line in file_css.read_text().splitlines():
31+
32+
if line == '':
33+
continue
34+
35+
# start of a comment
36+
if state == 0 and line.startswith('/*'):
37+
if '*/' in line:
38+
state = 0
39+
else:
40+
state = 1
41+
# we are in a comment section
42+
elif state == 1:
43+
# end of the comment
44+
if '*/' in line:
45+
state = 0
46+
else:
47+
continue
48+
# first line of multiple selector
49+
elif (state == 0 or state == 2) and ',' in line:
50+
state = 2
51+
# first line of single selector or end of multiple
52+
elif (state == 0 or state == 2) and '{' in line:
53+
state = 3
54+
# end of element
55+
elif state == 4 and line == '}':
56+
state = 0
57+
58+
if state == 0 and len(selectors):
59+
selectors = []
60+
61+
if state == 2:
62+
selector = line.split(",")[0].strip(' ')
63+
selectors.append(selector)
64+
65+
if state == 3:
66+
selector = line.split("{")[0].strip(' ')
67+
selectors.append(selector)
68+
state = 4
69+
continue
70+
71+
if state == 4:
72+
matched_colors = re.findall(MATCH_COLORS, line)
73+
74+
if len(matched_colors) > 1:
75+
error("Multiple colors in a line.\n\n {}\n\nSeems to be an invalid file!".format(line))
76+
elif len(matched_colors) == 1:
77+
matched_color = matched_colors[0]
78+
element = line.split(":")[0].strip(' ')
79+
80+
if not matched_color in by_color:
81+
by_color[matched_color] = []
82+
83+
by_color[matched_color].append(element)
84+
85+
entry = element + " " + matched_color
86+
87+
if not entry in by_attribute:
88+
by_attribute[entry] = []
89+
90+
by_attribute[entry].extend(selectors)
91+
92+
def sort_color(color):
93+
tmp = color[0].replace('#', '0x')
94+
return int(tmp, 0)
95+
96+
def remove_duplicates(l):
97+
no_duplicates = []
98+
[no_duplicates.append(i) for i in l if not no_duplicates.count(i)]
99+
return no_duplicates
100+
101+
colors = []
102+
103+
# sort colors just by hex value
104+
if len(by_color):
105+
colors = sorted(by_color.items(), key=lambda x: sort_color(x))
106+
107+
for k, l in by_attribute.items():
108+
by_attribute[k] = remove_duplicates(l)
109+
110+
for k, l in by_color.items():
111+
by_color[k] = remove_duplicates(l)
112+
113+
return {'fileName': file_css.stem, 'byAttribute': by_attribute, 'byColor': by_color, 'colors': colors}
114+
115+
116+
def create_color_file(content, commit):
117+
118+
str_result = "Color analyse of " +\
119+
content['fileName'] + ".css " + \
120+
"by " + \
121+
Path(__file__).name + \
122+
" for commit " + \
123+
commit + \
124+
"\n\n"
125+
126+
if not len(content['colors']):
127+
return None
128+
129+
str_result += "# Used colors\n\n"
130+
for c in content['colors']:
131+
str_result += c[0] + '\n'
132+
133+
str_result += "\n# Grouped by attribute\n"
134+
135+
for k, v in content['byAttribute'].items():
136+
str_result += '\n' + k + '\n'
137+
for val in v:
138+
str_result += ' ' + val + '\n'
139+
140+
str_result += "\n# Grouped by color\n"
141+
142+
for k, v in content['byColor'].items():
143+
str_result += '\n' + k + '\n'
144+
for val in v:
145+
str_result += ' ' + val + '\n'
146+
147+
return str_result
148+
149+
if __name__ == '__main__':
150+
151+
if len(sys.argv) > 1:
152+
error('No argument required!')
153+
154+
try:
155+
css_folder_path = Path(__file__).parent.absolute() / Path('../../src/qt/res/css/')
156+
css_folder_path = css_folder_path.resolve(strict=True)
157+
except Exception:
158+
error("Path doesn't exist: {}".format(css_folder_path))
159+
160+
if not len(list(css_folder_path.glob('*.css'))):
161+
error("No .css files found in {}".format(css_folder_path))
162+
163+
results = [parse_css(x) for x in css_folder_path.glob('*.css') if x.is_file()]
164+
165+
colors_folder_path = css_folder_path / Path('colors/')
166+
if not colors_folder_path.is_dir():
167+
try:
168+
colors_folder_path.mkdir()
169+
except Exception:
170+
error("Can't create new folder: {}".format(colors_folder_path))
171+
172+
commit = subprocess.check_output(['git', '-C', css_folder_path, 'rev-parse', '--short', 'HEAD']).decode("utf-8")
173+
174+
for r in results:
175+
176+
# Update the css file
177+
css_file = css_folder_path / Path(r['fileName'] + '.css')
178+
css_content = css_file.read_text()
179+
to_replace = re.findall(MATCH_REPLACE, css_content, re.DOTALL)
180+
181+
str_result = "\n# Used colors in {}.css for commit {}\n".format(r['fileName'], commit)
182+
for c in r['colors']:
183+
str_result += c[0] + '\n'
184+
185+
str_replace = "<colors>\n{}\n</colors>".format(str_result)
186+
css_content = css_content.replace(to_replace[0], str_replace)
187+
css_file.write_text(css_content)
188+
189+
# Write the <css>_color.txt files
190+
str_result = create_color_file(r, commit)
191+
192+
if str_result is not None:
193+
color_file = colors_folder_path / Path(r['fileName'] + '_css_colors.txt')
194+
color_file.write_text(str_result)
195+
196+
print('\n{}.css -> {} created!'.format(r['fileName'], color_file))
197+
else:
198+
print('\n{}.css -> No colors found..'.format(r['fileName'] + ".css"))

src/Makefile.qt.include

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ QT_TS = \
3232

3333
QT_FORMS_UI = \
3434
qt/forms/addressbookpage.ui \
35+
qt/forms/appearancewidget.ui \
3536
qt/forms/askpassphrasedialog.ui \
3637
qt/forms/coincontroldialog.ui \
3738
qt/forms/editaddressdialog.ui \
@@ -54,6 +55,7 @@ QT_FORMS_UI = \
5455
QT_MOC_CPP = \
5556
qt/moc_addressbookpage.cpp \
5657
qt/moc_addresstablemodel.cpp \
58+
qt/moc_appearancewidget.cpp \
5759
qt/moc_askpassphrasedialog.cpp \
5860
qt/moc_bantablemodel.cpp \
5961
qt/moc_bitcoinaddressvalidator.cpp \
@@ -126,6 +128,7 @@ PROTOBUF_PROTO = qt/paymentrequest.proto
126128
BITCOIN_QT_H = \
127129
qt/addressbookpage.h \
128130
qt/addresstablemodel.h \
131+
qt/appearancewidget.h \
129132
qt/askpassphrasedialog.h \
130133
qt/bantablemodel.h \
131134
qt/bitcoinaddressvalidator.h \
@@ -155,7 +158,6 @@ BITCOIN_QT_H = \
155158
qt/paymentrequestplus.h \
156159
qt/paymentserver.h \
157160
qt/peertablemodel.h \
158-
qt/platformstyle.h \
159161
qt/qrdialog.h \
160162
qt/qvalidatedlineedit.h \
161163
qt/qvaluecombobox.h \
@@ -238,6 +240,7 @@ RES_ICONS = \
238240
qt/res/icons/network_disabled.png
239241

240242
BITCOIN_QT_BASE_CPP = \
243+
qt/appearancewidget.cpp \
241244
qt/bantablemodel.cpp \
242245
qt/bitcoinaddressvalidator.cpp \
243246
qt/bitcoinamountfield.cpp \
@@ -253,7 +256,6 @@ BITCOIN_QT_BASE_CPP = \
253256
qt/optionsdialog.cpp \
254257
qt/optionsmodel.cpp \
255258
qt/peertablemodel.cpp \
256-
qt/platformstyle.cpp \
257259
qt/qvalidatedlineedit.cpp \
258260
qt/qvaluecombobox.cpp \
259261
qt/rpcconsole.cpp \
@@ -352,8 +354,27 @@ RES_CSS = \
352354
qt/res/css/dark.css \
353355
qt/res/css/general.css \
354356
qt/res/css/light.css \
355-
qt/res/css/scrollbars.css \
356-
qt/res/css/trad.css
357+
qt/res/css/traditional.css
358+
359+
RES_FONTS = \
360+
qt/res/fonts/Montserrat/Montserrat-Black.otf \
361+
qt/res/fonts/Montserrat/Montserrat-BlackItalic.otf \
362+
qt/res/fonts/Montserrat/Montserrat-Bold.otf \
363+
qt/res/fonts/Montserrat/Montserrat-BoldItalic.otf \
364+
qt/res/fonts/Montserrat/Montserrat-ExtraBold.otf \
365+
qt/res/fonts/Montserrat/Montserrat-ExtraBoldItalic.otf \
366+
qt/res/fonts/Montserrat/Montserrat-ExtraLight.otf \
367+
qt/res/fonts/Montserrat/Montserrat-ExtraLightItalic.otf \
368+
qt/res/fonts/Montserrat/Montserrat-Italic.otf \
369+
qt/res/fonts/Montserrat/Montserrat-Light.otf \
370+
qt/res/fonts/Montserrat/Montserrat-LightItalic.otf \
371+
qt/res/fonts/Montserrat/Montserrat-Medium.otf \
372+
qt/res/fonts/Montserrat/Montserrat-MediumItalic.otf \
373+
qt/res/fonts/Montserrat/Montserrat-Regular.otf \
374+
qt/res/fonts/Montserrat/Montserrat-SemiBold.otf \
375+
qt/res/fonts/Montserrat/Montserrat-SemiBoldItalic.otf \
376+
qt/res/fonts/Montserrat/Montserrat-Thin.otf \
377+
qt/res/fonts/Montserrat/Montserrat-ThinItalic.otf
357378

358379
RES_MOVIES = $(wildcard $(srcdir)/qt/res/movies/spinner-*.png)
359380

@@ -367,7 +388,7 @@ qt_libdashqt_a_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
367388
qt_libdashqt_a_OBJCXXFLAGS = $(AM_OBJCXXFLAGS) $(QT_PIE_FLAGS)
368389

369390
qt_libdashqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
370-
$(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_CSS) $(RES_MOVIES)
391+
$(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_CSS) $(RES_FONTS) $(RES_MOVIES)
371392

372393
nodist_qt_libdashqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
373394
$(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP)
@@ -430,12 +451,12 @@ $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
430451
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
431452
@rm $(@D)/temp_$(<F)
432453

433-
$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_CSS) $(RES_MOVIES) $(PROTOBUF_H)
454+
$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_CSS) $(RES_FONTS) $(RES_MOVIES) $(PROTOBUF_H)
434455
@test -f $(RCC)
435456
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) $(RCCFLAGS) -name dash $< | \
436457
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
437458

438-
CLEAN_QT = $(nodist_qt_libdashqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_dash_locale.qrc
459+
CLEAN_QT = $(nodist_qt_libdashqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_dash_locale.qrc qt/res/css/colors/*
439460

440461
CLEANFILES += $(CLEAN_QT)
441462

src/qt/addressbookpage.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,22 @@
1616
#include <qt/editaddressdialog.h>
1717
#include <qt/guiutil.h>
1818
#include <qt/optionsmodel.h>
19-
#include <qt/platformstyle.h>
2019
#include <qt/qrdialog.h>
2120

2221
#include <QIcon>
2322
#include <QMenu>
2423
#include <QMessageBox>
2524
#include <QSortFilterProxyModel>
2625

27-
AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :
26+
AddressBookPage::AddressBookPage(Mode _mode, Tabs _tab, QWidget *parent) :
2827
QDialog(parent),
2928
ui(new Ui::AddressBookPage),
3029
model(0),
3130
mode(_mode),
3231
tab(_tab)
3332
{
3433
ui->setupUi(this);
35-
if (!platformStyle->getImagesOnButtons()) {
36-
ui->newAddress->setIcon(QIcon());
37-
ui->copyAddress->setIcon(QIcon());
38-
ui->deleteAddress->setIcon(QIcon());
39-
ui->exportButton->setIcon(QIcon());
40-
} else {
41-
ui->newAddress->setIcon(QIcon(":/icons/add"));
42-
ui->copyAddress->setIcon(QIcon(":/icons/editcopy"));
43-
ui->deleteAddress->setIcon(QIcon(":/icons/remove"));
44-
ui->exportButton->setIcon(QIcon(":/icons/export"));
45-
}
34+
4635
ui->showAddressQRCode->setIcon(QIcon());
4736

4837
switch(mode)
@@ -106,6 +95,8 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode,
10695
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
10796

10897
connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(accept()));
98+
99+
GUIUtil::updateFonts();
109100
}
110101

111102
AddressBookPage::~AddressBookPage()

src/qt/addressbookpage.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <QDialog>
99

1010
class AddressTableModel;
11-
class PlatformStyle;
1211

1312
namespace Ui {
1413
class AddressBookPage;
@@ -38,7 +37,7 @@ class AddressBookPage : public QDialog
3837
ForEditing /**< Open address book for editing */
3938
};
4039

41-
explicit AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent);
40+
explicit AddressBookPage(Mode mode, Tabs tab, QWidget* parent);
4241
~AddressBookPage();
4342

4443
void setModel(AddressTableModel *model);

0 commit comments

Comments
 (0)