Maarten van den Berg преди 6 години
родител
ревизия
f7bd7b50d2

+ 47 - 12
piket_client/gui.py

@@ -6,6 +6,7 @@ import logging
6 6
 import os
7 7
 import sys
8 8
 
9
+import qdarkstyle
9 10
 # pylint: disable=E0611
10 11
 from PySide2.QtWidgets import (
11 12
     QAction,
@@ -147,6 +148,7 @@ class PiketMainWindow(QMainWindow):
147 148
         super().__init__()
148 149
 
149 150
         self.main_widget = None
151
+        self.dark_theme = True
150 152
         self.toolbar = None
151 153
         self.osk = None
152 154
         self.undo_action = None
@@ -171,7 +173,7 @@ class PiketMainWindow(QMainWindow):
171 173
         self.setWindowState(Qt.WindowActive | Qt.WindowFullScreen)
172 174
 
173 175
         font_metrics = self.fontMetrics()
174
-        icon_size = font_metrics.height() * 2
176
+        icon_size = font_metrics.height() * 1.45
175 177
 
176 178
         # Initialize toolbar
177 179
         self.toolbar = QToolBar()
@@ -180,8 +182,11 @@ class PiketMainWindow(QMainWindow):
180 182
 
181 183
         # Left
182 184
         self.toolbar.addAction(
183
-            self.load_icon("add_person.svg"), "Nieuw persoon", self.add_person
185
+            self.load_icon("add_person.svg"), "+ Naam", self.add_person
184 186
         )
187
+        self.toolbar.addAction(
188
+            self.load_icon("add_consumption_type.svg"), "+ Lijst",
189
+            self.add_consumption_type)
185 190
         self.undo_action = self.toolbar.addAction(
186 191
             self.load_icon("undo.svg"), "Oeps", self.do_undo
187 192
         )
@@ -194,8 +199,8 @@ class PiketMainWindow(QMainWindow):
194 199
         self.toolbar.addWidget(self.create_spacer())
195 200
 
196 201
         # Right
197
-        ag = QActionGroup(self.toolbar)
198
-        ag.setExclusive(True)
202
+        self.ct_ag = QActionGroup(self.toolbar)
203
+        self.ct_ag.setExclusive(True)
199 204
 
200 205
         cts = ConsumptionType.get_all()
201 206
         if not cts:
@@ -231,18 +236,19 @@ class PiketMainWindow(QMainWindow):
231 236
                 sys.exit()
232 237
 
233 238
         for ct in cts:
234
-            action = QAction(self.load_icon(ct.icon or "beer_bottle.svg"), ct.name, ag)
239
+            action = QAction(self.load_icon(ct.icon or "beer_bottle.svg"),
240
+                    ct.name, self.ct_ag)
235 241
             action.setCheckable(True)
236 242
             action.setData(str(ct.consumption_type_id))
237 243
 
238
-        ag.actions()[0].setChecked(True)
239
-        [self.toolbar.addAction(a) for a in ag.actions()]
240
-        ag.triggered.connect(self.consumption_type_change)
244
+        self.ct_ag.actions()[0].setChecked(True)
245
+        [self.toolbar.addAction(a) for a in self.ct_ag.actions()]
246
+        self.ct_ag.triggered.connect(self.consumption_type_change)
241 247
 
242 248
         self.addToolBar(self.toolbar)
243 249
 
244 250
         # Initialize main widget
245
-        self.main_widget = NameButtons(ag.actions()[0].data(), self)
251
+        self.main_widget = NameButtons(self.ct_ag.actions()[0].data(), self)
246 252
         self.consumption_type_changed.connect(self.main_widget.consumption_type_changed)
247 253
         self.setCentralWidget(self.main_widget)
248 254
 
@@ -289,6 +295,30 @@ class PiketMainWindow(QMainWindow):
289 295
 
290 296
             self.main_widget.init_ui()
291 297
 
298
+    def add_consumption_type(self) -> None:
299
+        self.show_keyboard()
300
+        name, ok = QInputDialog.getItem(
301
+            self,
302
+            "Lijst toevoegen",
303
+            "Wat wil je strepen?",
304
+            ["Wijn", "Radler"]
305
+        )
306
+        self.hide_keyboard()
307
+
308
+        if ok and name:
309
+            ct = ConsumptionType(name=name)
310
+            ct = ct.create()
311
+
312
+            action = QAction(
313
+                self.load_icon(ct.icon or "beer_bottle.svg"),
314
+                ct.name,
315
+                self.ct_ag
316
+            )
317
+            action.setCheckable(True)
318
+            action.setData(str(ct.consumption_type_id))
319
+
320
+            self.toolbar.addAction(action)
321
+
292 322
     def confirm_quit(self) -> None:
293 323
         """ Ask for confirmation that the user wishes to quit, then do so. """
294 324
         ok = QMessageBox.warning(
@@ -328,6 +358,7 @@ class PiketMainWindow(QMainWindow):
328 358
         self.undo_queue.append(consumption)
329 359
         self.undo_action.setDisabled(False)
330 360
 
361
+
331 362
     @staticmethod
332 363
     def create_spacer() -> QWidget:
333 364
         """ Return an empty QWidget that automatically expands. """
@@ -337,17 +368,21 @@ class PiketMainWindow(QMainWindow):
337 368
 
338 369
     icons_dir = os.path.join(os.path.dirname(__file__), "icons")
339 370
 
340
-    @classmethod
341
-    def load_icon(cls, filename: str) -> QIcon:
371
+    def load_icon(self, filename: str) -> QIcon:
342 372
         """ Return a QtIcon loaded from the given `filename` in the icons
343 373
         directory. """
344 374
 
345
-        return QIcon(os.path.join(cls.icons_dir, filename))
375
+        if self.dark_theme:
376
+            filename = 'white_' + filename
377
+
378
+        icon = QIcon(os.path.join(self.icons_dir, filename))
379
+        return icon
346 380
 
347 381
 
348 382
 def main() -> None:
349 383
     """ Main entry point of GUI client. """
350 384
     app = QApplication(sys.argv)
385
+    app.setStyleSheet(qdarkstyle.load_stylesheet_pyside2())
351 386
     font = app.font()
352 387
     size = font.pointSize()
353 388
     font.setPointSize(size * 1.75)

Файловите разлики са ограничени, защото са твърде много
+ 1 - 93
piket_client/icons/add_consumption_type.svg


Файловите разлики са ограничени, защото са твърде много
+ 1 - 0
piket_client/icons/create_settlement.svg


Файловите разлики са ограничени, защото са твърде много
+ 1 - 0
piket_client/icons/lightbulb.svg


+ 35 - 0
piket_client/icons/white_add_consumption_type.svg

@@ -0,0 +1,35 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<svg
3
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+   xmlns:cc="http://creativecommons.org/ns#"
5
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+   xmlns:svg="http://www.w3.org/2000/svg"
7
+   xmlns="http://www.w3.org/2000/svg"
8
+   id="svg4"
9
+   version="1.1"
10
+   viewBox="0 0 384 512"
11
+   role="img"
12
+   class="svg-inline--fa fa-file-medical fa-w-12"
13
+   data-icon="file-medical"
14
+   data-prefix="fas"
15
+   aria-hidden="true">
16
+  <metadata
17
+     id="metadata10">
18
+    <rdf:RDF>
19
+      <cc:Work
20
+         rdf:about="">
21
+        <dc:format>image/svg+xml</dc:format>
22
+        <dc:type
23
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
24
+        <dc:title></dc:title>
25
+      </cc:Work>
26
+    </rdf:RDF>
27
+  </metadata>
28
+  <defs
29
+     id="defs8" />
30
+  <path
31
+     style="fill:#ffffff;fill-opacity:1"
32
+     id="path2"
33
+     d="M377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 160v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8z"
34
+     fill="white" />
35
+</svg>

+ 35 - 0
piket_client/icons/white_add_person.svg

@@ -0,0 +1,35 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<svg
3
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+   xmlns:cc="http://creativecommons.org/ns#"
5
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+   xmlns:svg="http://www.w3.org/2000/svg"
7
+   xmlns="http://www.w3.org/2000/svg"
8
+   aria-hidden="true"
9
+   data-prefix="fas"
10
+   data-icon="user"
11
+   class="svg-inline--fa fa-user fa-w-14"
12
+   role="img"
13
+   viewBox="0 0 448 512"
14
+   version="1.1"
15
+   id="svg4">
16
+  <metadata
17
+     id="metadata10">
18
+    <rdf:RDF>
19
+      <cc:Work
20
+         rdf:about="">
21
+        <dc:format>image/svg+xml</dc:format>
22
+        <dc:type
23
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
24
+        <dc:title></dc:title>
25
+      </cc:Work>
26
+    </rdf:RDF>
27
+  </metadata>
28
+  <defs
29
+     id="defs8" />
30
+  <path
31
+     style="fill:#ffffff;fill-opacity:1"
32
+     fill="white"
33
+     d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"
34
+     id="path2" />
35
+</svg>

Файловите разлики са ограничени, защото са твърде много
+ 82 - 0
piket_client/icons/white_beer_bottle.svg


Файловите разлики са ограничени, защото са твърде много
+ 35 - 0
piket_client/icons/white_lightbulb.svg


+ 59 - 0
piket_client/icons/white_quit.svg

@@ -0,0 +1,59 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<svg
3
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+   xmlns:cc="http://creativecommons.org/ns#"
5
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+   xmlns:svg="http://www.w3.org/2000/svg"
7
+   xmlns="http://www.w3.org/2000/svg"
8
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
9
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10
+   aria-hidden="true"
11
+   data-prefix="fas"
12
+   data-icon="sign-out-alt"
13
+   class="svg-inline--fa fa-sign-out-alt fa-w-16"
14
+   role="img"
15
+   viewBox="0 0 512 512"
16
+   version="1.1"
17
+   id="svg4"
18
+   sodipodi:docname="quit_white.svg"
19
+   inkscape:version="0.92.2 2405546, 2018-03-11">
20
+  <metadata
21
+     id="metadata10">
22
+    <rdf:RDF>
23
+      <cc:Work
24
+         rdf:about="">
25
+        <dc:format>image/svg+xml</dc:format>
26
+        <dc:type
27
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
28
+        <dc:title></dc:title>
29
+      </cc:Work>
30
+    </rdf:RDF>
31
+  </metadata>
32
+  <defs
33
+     id="defs8" />
34
+  <sodipodi:namedview
35
+     pagecolor="#ffffff"
36
+     bordercolor="#666666"
37
+     borderopacity="1"
38
+     objecttolerance="10"
39
+     gridtolerance="10"
40
+     guidetolerance="10"
41
+     inkscape:pageopacity="0"
42
+     inkscape:pageshadow="2"
43
+     inkscape:window-width="1596"
44
+     inkscape:window-height="861"
45
+     id="namedview6"
46
+     showgrid="false"
47
+     inkscape:zoom="0.4609375"
48
+     inkscape:cx="-190.91525"
49
+     inkscape:cy="256"
50
+     inkscape:window-x="1280"
51
+     inkscape:window-y="18"
52
+     inkscape:window-maximized="0"
53
+     inkscape:current-layer="svg4" />
54
+  <path
55
+     fill="white"
56
+     d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"
57
+     id="path2"
58
+     style="fill:#ffffff;fill-opacity:1" />
59
+</svg>

Файловите разлики са ограничени, защото са твърде много
+ 35 - 0
piket_client/icons/white_undo.svg


+ 1 - 0
piket_client/model.py

@@ -99,6 +99,7 @@ class Person(NamedTuple):
99 99
     @classmethod
100 100
     def get_all(cls, active=None) -> ["Person"]:
101 101
         """ Get all active People. """
102
+        active = int(active)
102 103
         req = requests.get(urljoin(SERVER_URL, "/people"),
103 104
                 params={'active':active})
104 105
 

+ 2 - 1
piket_server/__init__.py

@@ -139,7 +139,8 @@ def get_people():
139 139
     people = Person.query.order_by(Person.name).all()
140 140
     q = Person.query.order_by(Person.name)
141 141
     if request.args.get('active'):
142
-        q = q.filter_by(active=bool(request.args.get('active')))
142
+        active_status = request.args.get('active', type=int)
143
+        q = q.filter_by(active=active_status)
143 144
     people = q.all()
144 145
     result = [person.as_dict for person in people]
145 146
     return jsonify(people=result)

+ 1 - 1
piket_server/alembic.ini

@@ -2,7 +2,7 @@
2 2
 
3 3
 [alembic]
4 4
 # path to migration scripts
5
-script_location = alembic
5
+script_location = piket_server:alembic
6 6
 
7 7
 # template used to generate migration files
8 8
 # file_template = %%(rev)s_%%(slug)s

+ 1 - 1
piket_server/seed.py

@@ -73,7 +73,7 @@ def cmd_load_persons(args) -> None:
73 73
         for row in reader:
74 74
             p = Person(
75 75
                 name=row['name'],
76
-                active=bool(row['active'])
76
+                active=bool(int(row['active']))
77 77
             )
78 78
             db.session.add(p)
79 79
 

+ 2 - 1
setup.py

@@ -46,8 +46,9 @@ setup(
46 46
             ],
47 47
             'client': [
48 48
                 'PySide2',
49
-                'simpleaudio',
49
+                'qdarkstyle@https://github.com/ColinDuquesnoy/QDarkStyleSheet/tarball/d089f12f674c78285302e509745a68cc3fa4bb3b#sha256=83902ddd331b61036568c2d179fc302e5f448b5c6b2e2bd3dec4ffb76725c113',
50 50
                 'requests',
51
+                'simpleaudio',
51 52
             ],
52 53
             'osk': [
53 54
                 'dbus-python',