From d609a4e4ab89d876289233490adcc46571adc15c Mon Sep 17 00:00:00 2001
From: Oscar Gustafsson <oscar.gustafsson@gmail.com>
Date: Mon, 10 Apr 2023 19:53:44 +0200
Subject: [PATCH] Add icons

---
 README.md                           |  1 +
 b_asic/GUI/main_window.py           | 11 +++++++++--
 b_asic/gui_utils/icons.py           | 20 ++++++++++++++++++++
 b_asic/gui_utils/plot_window.py     |  8 +++++---
 b_asic/scheduler_gui/main_window.py |  4 ++++
 pyproject.toml                      |  1 +
 requirements.txt                    |  1 +
 7 files changed, 41 insertions(+), 5 deletions(-)
 create mode 100644 b_asic/gui_utils/icons.py

diff --git a/README.md b/README.md
index b1684b2d..fb3ee09e 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ The following packages are required in order to build the library:
     -   [QtPy](https://github.com/spyder-ide/qtpy)
     -   [setuptools_scm](https://github.com/pypa/setuptools_scm/)
     -   [NetworkX](https://networkx.org/)
+    -   [QtAwesome](https://github.com/spyder-ide/qtawesome/)
 -   Qt 5 or 6, with Python bindings, one of:
     - pyside2
     - pyqt5
diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py
index 414d0084..7ce2ebf3 100644
--- a/b_asic/GUI/main_window.py
+++ b/b_asic/GUI/main_window.py
@@ -44,6 +44,7 @@ from b_asic.GUI.simulation_worker import SimulationWorker
 from b_asic.GUI.util_dialogs import FaqWindow, KeybindingsWindow
 from b_asic.gui_utils.about_window import AboutWindow
 from b_asic.gui_utils.decorators import decorate_class, handle_error
+from b_asic.gui_utils.icons import get_icon
 from b_asic.gui_utils.plot_window import PlotWindow
 from b_asic.operation import Operation
 from b_asic.port import InputPort, OutputPort
@@ -99,8 +100,12 @@ class SFGMainWindow(QMainWindow):
 
         # Create _toolbar
         self._toolbar = self.addToolBar("Toolbar")
-        self._toolbar.addAction("Create SFG", self.create_sfg_from_toolbar)
-        self._toolbar.addAction("Clear workspace", self._clear_workspace)
+        self._toolbar.addAction(
+            get_icon('new-sfg'), "Create SFG", self.create_sfg_from_toolbar
+        )
+        self._toolbar.addAction(
+            get_icon('close'), "Clear workspace", self._clear_workspace
+        )
 
         # Add operations
         self._max_recent_files = 4
@@ -146,7 +151,9 @@ class SFGMainWindow(QMainWindow):
             self._on_list_widget_item_clicked
         )
         self._ui.save_menu.triggered.connect(self.save_work)
+        self._ui.save_menu.setIcon(get_icon('save'))
         self._ui.load_menu.triggered.connect(self.load_work)
+        self._ui.load_menu.setIcon(get_icon('open'))
         self._ui.load_operations.triggered.connect(self.add_namespace)
         self._ui.exit_menu.triggered.connect(self.exit_app)
         self._shortcut_open = QShortcut(QKeySequence("Ctrl+O"), self)
diff --git a/b_asic/gui_utils/icons.py b/b_asic/gui_utils/icons.py
new file mode 100644
index 00000000..c729246c
--- /dev/null
+++ b/b_asic/gui_utils/icons.py
@@ -0,0 +1,20 @@
+"""B-ASIC icons."""
+
+import qtawesome
+
+ICONS = {
+    'save': 'mdi6.content-save',
+    'new': 'mdi6.file-outline',
+    'open': 'mdi6.folder-open',
+    'legend': 'mdi6.map-legend',
+    'close': 'mdi6.close',
+    'all': 'mdi6.select-all',
+    'none': 'mdi6.select-remove',
+    'new-sfg': 'mdi6.new-box',
+    'plot-schedule': 'mdi6.chart-gantt',
+}
+
+
+def get_icon(name):
+    """Return icon for given name"""
+    return qtawesome.icon(ICONS[name])
diff --git a/b_asic/gui_utils/plot_window.py b/b_asic/gui_utils/plot_window.py
index 4ea8f254..726142b6 100644
--- a/b_asic/gui_utils/plot_window.py
+++ b/b_asic/gui_utils/plot_window.py
@@ -21,6 +21,7 @@ from qtpy.QtWidgets import (  # QFrame,; QScrollArea,; QLineEdit,; QSizePolicy,;
     QWidget,
 )
 
+from b_asic.gui_utils.icons import get_icon
 from b_asic.operation import ResultKey
 from b_asic.types import Num
 
@@ -119,10 +120,10 @@ class PlotWindow(QWidget):
 
         # Add two buttons for selecting all/none:
         hlayout = QHBoxLayout()
-        self._button_all = QPushButton("&All")
+        self._button_all = QPushButton(get_icon('all'), "&All")
         self._button_all.clicked.connect(self._button_all_click)
         hlayout.addWidget(self._button_all)
-        self._button_none = QPushButton("&None")
+        self._button_none = QPushButton(get_icon('none'), "&None")
         self._button_none.clicked.connect(self._button_none_click)
         hlayout.addWidget(self._button_none)
         listlayout.addLayout(hlayout)
@@ -155,6 +156,7 @@ class PlotWindow(QWidget):
         self._legend_checkbox = QCheckBox("&Legend")
         self._legend_checkbox.stateChanged.connect(self._legend_checkbox_change)
         self._legend_checkbox.setCheckState(Qt.CheckState.Checked)
+        self._legend_checkbox.setIcon(get_icon('legend'))
         listlayout.addWidget(self._legend_checkbox)
         # self.ontop_checkbox = QCheckBox("&On top")
         # self.ontop_checkbox.stateChanged.connect(self._ontop_checkbox_change)
@@ -166,7 +168,7 @@ class PlotWindow(QWidget):
         listlayout.addWidget(relim_button)
 
         # Add "Close" buttons
-        button_close = QPushButton("&Close", self)
+        button_close = QPushButton(get_icon('close'), "&Close", self)
         button_close.clicked.connect(self.close)
         listlayout.addWidget(button_close)
         self._relim()
diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index 2ed5db7b..2e6e90c7 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -50,6 +50,7 @@ import b_asic.scheduler_gui.logger as logger
 from b_asic._version import __version__
 from b_asic.graph_component import GraphComponent, GraphID
 from b_asic.gui_utils.about_window import AboutWindow
+from b_asic.gui_utils.icons import get_icon
 from b_asic.schedule import Schedule
 from b_asic.scheduler_gui.axes_item import AxesItem
 from b_asic.scheduler_gui.operation_item import OperationItem
@@ -133,14 +134,17 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
 
         # Connect signals to slots
         self.menu_load_from_file.triggered.connect(self._load_schedule_from_pyfile)
+        self.menu_load_from_file.setIcon(get_icon('open'))
         self.menu_close_schedule.triggered.connect(self.close_schedule)
         self.menu_save.triggered.connect(self.save)
+        self.menu_save.setIcon(get_icon('save'))
         self.menu_save_as.triggered.connect(self.save_as)
         self.menu_quit.triggered.connect(self.close)
         self.menu_node_info.triggered.connect(self.show_info_table)
         self.menu_exit_dialog.triggered.connect(self.hide_exit_dialog)
         self.actionReorder.triggered.connect(self._action_reorder)
         self.actionPlot_schedule.triggered.connect(self._plot_schedule)
+        self.actionPlot_schedule.setIcon(get_icon('plot-schedule'))
         self.splitter.splitterMoved.connect(self._splitter_moved)
         self.actionDocumentation.triggered.connect(self._open_documentation)
         self.actionAbout.triggered.connect(self._open_about_window)
diff --git a/pyproject.toml b/pyproject.toml
index af4223ca..3ccf58f7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -14,6 +14,7 @@ dependencies = [
     "matplotlib",
     "setuptools_scm[toml]>=6.2",
     "networkx",
+    "qtawesome"
 ]
 classifiers = [
     "Intended Audience :: Education",
diff --git a/requirements.txt b/requirements.txt
index 1a591a91..ff0a1020 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,3 +4,4 @@ graphviz>=0.19
 matplotlib
 setuptools_scm[toml]>=6.2
 networkx
+qtawesome
-- 
GitLab