diff --git a/gui/core/json_settings.py b/gui/core/json_settings.py index ec784be..d54f6cd 100644 --- a/gui/core/json_settings.py +++ b/gui/core/json_settings.py @@ -37,18 +37,7 @@ class Settings(object): # DICTIONARY WITH SETTINGS # Just to have objects references - self.items = { - "app_name" : "", - "custom_title_bar" : True, - "startup_size" : [], - "minimum_size" : [], - "menu_size" : { - "minimum" : 0, - "maximum" : 0 - }, - "theme_name" : "", - "teste" : "" - } + self.items = {} # DESERIALIZE self.deserialize() diff --git a/gui/core/json_themes.py b/gui/core/json_themes.py index 6875ca1..480aa2b 100644 --- a/gui/core/json_themes.py +++ b/gui/core/json_themes.py @@ -45,27 +45,7 @@ class Themes(object): super(Themes, self).__init__() # DICTIONARY WITH SETTINGS - self.items = { - "theme_name" : "", - "app_color" : { - "dark_one" : "", - "dark_two" : "", - "dark_three" : "", - "dark_four" : "", - "bg_one" : "", - "bg_two" : "", - "icon_normal" : "", - "icon_hover" : "", - "icon_pressed" : "", - "icon_active" : "", - "context_color" : "", - "context_hover" : "", - "context_pressed" : "", - "text_title" : "", - "text_foreground" : "", - "text_description" : "" - } - } + self.items = {} # DESERIALIZE self.deserialize() diff --git a/gui/images/svg_icons/icon_menu.svg b/gui/images/svg_icons/icon_menu.svg new file mode 100644 index 0000000..e486198 --- /dev/null +++ b/gui/images/svg_icons/icon_menu.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/gui/images/svg_icons/icon_menu_close.svg b/gui/images/svg_icons/icon_menu_close.svg new file mode 100644 index 0000000..699f1f2 --- /dev/null +++ b/gui/images/svg_icons/icon_menu_close.svg @@ -0,0 +1,61 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/gui/uis/windows/main_window/ui_main.py b/gui/uis/windows/main_window/ui_main.py index 3e6011b..d7e4a5d 100644 --- a/gui/uis/windows/main_window/ui_main.py +++ b/gui/uis/windows/main_window/ui_main.py @@ -88,25 +88,41 @@ class UI_MainWindow(object): # ADD FRAME LEFT MENU # Add here the custom left menu bar # /////////////////////////////////////////////////////////////// + left_menu_margin = self.settings["left_menu_content_margins"] + left_menu_minimum = self.settings["lef_menu_size"]["minimum"] self.left_menu_frame = QFrame() - self.left_menu_frame.setMaximumSize(50, 17280) - self.left_menu_frame.setMinimumSize(self.settings["menu_size"]["minimum"], 0) + self.left_menu_frame.setMaximumSize(left_menu_minimum + (left_menu_margin * 2), 17280) + self.left_menu_frame.setMinimumSize(left_menu_minimum + (left_menu_margin * 2), 0) # LEFT MENU LAYOUT self.left_menu_layout = QHBoxLayout(self.left_menu_frame) - self.left_menu_layout.setContentsMargins(0,0,0,0) + self.left_menu_layout.setContentsMargins( + left_menu_margin, + left_menu_margin, + left_menu_margin, + left_menu_margin + ) # ADD LEFT MENU # Add custom left menu here # /////////////////////////////////////////////////////////////// self.left_menu = PyLeftMenu( parent = self.left_menu_frame, - app_parent = self.central_widget, + app_parent = self.central_widget, # For tooltip parent dark_one = self.themes["app_color"]["dark_one"] ) self.left_menu_layout.addWidget(self.left_menu) print(self.themes["app_color"]["dark_one"]) + # ADD LEFT COLUMN + # Add here the left column with Stacked Widgets + # /////////////////////////////////////////////////////////////// + left_column_minimum = self.settings["lef_column_size"]["minimum"] + self.left_column_frame = QFrame() + self.left_column_frame.setMaximumSize(left_column_minimum, 17280) + self.left_column_frame.setMinimumSize(left_column_minimum, 0) + self.left_column_frame.setStyleSheet(f"background: {self.themes['app_color']['bg_two']}") + # ADD RIGHT WIDGETS # Add here the right widgets # /////////////////////////////////////////////////////////////// @@ -114,7 +130,7 @@ class UI_MainWindow(object): # ADD RIGHT APP LAYOUT self.right_app_layout = QVBoxLayout(self.right_app_frame) - self.right_app_layout.setContentsMargins(0,0,0,0) + self.right_app_layout.setContentsMargins(3,3,3,3) self.right_app_layout.setSpacing(6) # ADD TITLE BAR FRAME @@ -122,6 +138,10 @@ class UI_MainWindow(object): self.title_bar_frame.setMaximumHeight(40) self.title_bar_frame.setMaximumHeight(40) self.title_bar_frame.setStyleSheet("background: #343b48; border-radius: 8px;") + # apagar + close = QPushButton("Fechar") + close.setParent(self.title_bar_frame) + close.clicked.connect(lambda: parent.close()) # ADD CONTENT AREA self.content_area_frame = QFrame() @@ -142,6 +162,7 @@ class UI_MainWindow(object): # Add here your custom widgets or default widgets # /////////////////////////////////////////////////////////////// self.window.layout.addWidget(self.left_menu_frame) + self.window.layout.addWidget(self.left_column_frame) self.window.layout.addWidget(self.right_app_frame) # ADD CENTRAL WIDGET AND SET CONTENT MARGINS diff --git a/gui/widgets/py_left_menu/py_div.py b/gui/widgets/py_left_menu/py_div.py new file mode 100644 index 0000000..ec970dd --- /dev/null +++ b/gui/widgets/py_left_menu/py_div.py @@ -0,0 +1,38 @@ +# /////////////////////////////////////////////////////////////// +# +# BY: WANDERSON M.PIMENTA +# PROJECT MADE WITH: Qt Designer and PySide6 +# V: 1.0.0 +# +# This project can be used freely for all uses, as long as they maintain the +# respective credits only in the Python scripts, any information in the visual +# interface (GUI) can be modified without any implication. +# +# There are limitations on Qt licenses if you want to use your products +# commercially, I recommend reading them on the official website: +# https://doc.qt.io/qtforpython/licenses.html +# +# /////////////////////////////////////////////////////////////// + +# IMPORT PACKAGES AND MODULES +# /////////////////////////////////////////////////////////////// +import os + +# IMPORT QT CORE +# /////////////////////////////////////////////////////////////// +from qt_core import * + +# CUSTOM LEFT MENU +# /////////////////////////////////////////////////////////////// +class PyDiv(QWidget): + def __init__(self, color): + super(PyDiv, self).__init__() + + self.layout = QVBoxLayout(self) + self.layout.setContentsMargins(5,0,5,0) + self.frame_line = QFrame() + self.frame_line.setStyleSheet(f"background: {color};") + self.frame_line.setMaximumHeight(1) + self.frame_line.setMinimumHeight(1) + self.layout.addWidget(self.frame_line) + self.setMaximumHeight(1) diff --git a/gui/widgets/py_left_menu/py_left_menu.py b/gui/widgets/py_left_menu/py_left_menu.py index 1b49902..ccd0045 100644 --- a/gui/widgets/py_left_menu/py_left_menu.py +++ b/gui/widgets/py_left_menu/py_left_menu.py @@ -14,25 +14,14 @@ # # /////////////////////////////////////////////////////////////// -# IMPORT PACKAGES AND MODULES -# /////////////////////////////////////////////////////////////// -import os - # IMPORT QT CORE # /////////////////////////////////////////////////////////////// from qt_core import * -# IMPORT SETTINGS -# /////////////////////////////////////////////////////////////// -from gui.core.json_settings import Settings - -# IMPORT SETTINGS -# /////////////////////////////////////////////////////////////// -from gui.core.json_themes import Themes - -# IMPORT BUTTON +# IMPORT BUTTON AND DIV # /////////////////////////////////////////////////////////////// from . py_left_menu_button import PyLeftMenuButton +from . py_div import PyDiv # PY LEFT MENU # /////////////////////////////////////////////////////////////// @@ -42,6 +31,8 @@ class PyLeftMenu(QWidget): parent = None, app_parent = None, dark_one = "#1b1e23", + dark_three = "#21252d", + dark_four = "#272c36", bg_one = "#2c313c", icon_color = "#c3ccdf", icon_color_hover = "#dce1ec", @@ -49,7 +40,11 @@ class PyLeftMenu(QWidget): icon_color_active = "#f5f6f9", context_color = "#568af2", duration_time = 500, - radius = 8 + radius = 8, + minimum_width = 50, + maximum_width = 240, + icon_path = "gui/images/svg_icons/icon_menu.svg", + icon_path_close = "gui/images/svg_icons/icon_menu_close.svg", ): super(PyLeftMenu, self).__init__() @@ -64,6 +59,10 @@ class PyLeftMenu(QWidget): self._context_color = context_color self._duration_time = duration_time self._radius = radius + self._minimum_width = minimum_width + self._maximum_width = maximum_width + self._icon_path = icon_path + self._icon_path_close = icon_path_close # SET PARENT self._parent = parent @@ -80,29 +79,54 @@ class PyLeftMenu(QWidget): "Add user menu", "Test tooltip", ) - self.button.clicked.connect(lambda: self.size_change()) - self.button_2 = QPushButton("teste") - self.button_3 = PyLeftMenuButton( + self.button.clicked.connect(lambda: self.toggle_animation()) + + # TOGGLE BUTTON AND DIV MENUS + # /////////////////////////////////////////////////////////////// + self.toggle_button = PyLeftMenuButton( app_parent, - "Teste menu", - "Tooltip 2", + "Hide Menu", + "Expand/Retract menu", + icon_path = icon_path + ) + self.toggle_button.clicked.connect(self.toggle_animation) + self.div_top = PyDiv(dark_four) + + # ADD TO TOP LAYOUT + self.top_layout.addWidget(self.toggle_button) + self.top_layout.addWidget(self.div_top) + self.top_layout.addWidget(self.button) # Apagar + + # BUTTON WIDGETS + # /////////////////////////////////////////////////////////////// + self.div_button = PyDiv(dark_four) + self.settings_button = PyLeftMenuButton( + app_parent, + "Settings", + "Open settings", icon_path="gui/images/svg_icons/icon_settings.svg" ) - self.layout.addWidget(self.button) - self.layout.addWidget(self.button_2) - self.layout.addWidget(self.button_3) + self.bottom_layout.addWidget(self.div_button) + self.bottom_layout.addWidget(self.settings_button) + + def toggle_animation(self): + if self.toggle_button._is_toggle_active: + self.toggle_button.set_active_toggle(False) + self.toggle_button.set_icon(self._icon_path) + else: + self.toggle_button.set_active_toggle(True) + self.toggle_button.set_icon(self._icon_path_close) - def size_change(self): self.animation = QPropertyAnimation(self._parent, b"minimumWidth") self.animation.stop() - if self.width() == 50: + if self.width() == self._minimum_width: self.animation.setStartValue(self.width()) - self.animation.setEndValue(240) + self.animation.setEndValue(self._maximum_width) # ACTIVE self.button.set_active(True) else: self.animation.setStartValue(self.width()) - self.animation.setEndValue(50) + self.animation.setEndValue(self._minimum_width) # ACTIVE self.button.set_active(False) self.animation.setEasingCurve(QEasingCurve.InOutCubic) @@ -117,11 +141,31 @@ class PyLeftMenu(QWidget): self.left_menu_layout.setContentsMargins(0,0,0,0) # ADD BG - self.bg = QFrame(self) + self.bg = QFrame() - # ADD LAYOUT - self.layout = QVBoxLayout(self.bg) - self.layout.setContentsMargins(0,0,0,0) + # TOP FRAME + self.top_frame = QFrame() + + # BOTTOM FRAME + self.bottom_frame = QFrame() + + # ADD LAYOUTS + self._layout = QVBoxLayout(self.bg) + self._layout.setContentsMargins(0,0,0,0) + + # TOP LAYOUT + self.top_layout = QVBoxLayout(self.top_frame) + self.top_layout.setContentsMargins(0,0,0,0) + self.top_layout.setSpacing(1) + + # BOTTOM LAYOUT + self.bottom_layout = QVBoxLayout(self.bottom_frame) + self.bottom_layout.setContentsMargins(0,0,0,0) + self.bottom_layout.setSpacing(1) + + # ADD TOP AND BOTTOM FRAME + self._layout.addWidget(self.top_frame, 0, Qt.AlignTop) + self._layout.addWidget(self.bottom_frame, 0, Qt.AlignBottom) # ADD BG TO LAYOUT self.left_menu_layout.addWidget(self.bg) diff --git a/gui/widgets/py_left_menu/py_left_menu_button.py b/gui/widgets/py_left_menu/py_left_menu_button.py index 4144eaa..4011792 100644 --- a/gui/widgets/py_left_menu/py_left_menu_button.py +++ b/gui/widgets/py_left_menu/py_left_menu_button.py @@ -16,17 +16,12 @@ # IMPORT PACKAGES AND MODULES # /////////////////////////////////////////////////////////////// -from gui.widgets.py_window import styles import os # IMPORT QT CORE # /////////////////////////////////////////////////////////////// from qt_core import * -# IMPORT COLORS -# /////////////////////////////////////////////////////////////// -from gui.core.json_themes import Themes - # CUSTOM LEFT MENU # /////////////////////////////////////////////////////////////// class PyLeftMenuButton(QPushButton): @@ -49,7 +44,8 @@ class PyLeftMenuButton(QPushButton): text_active = "#dce1ec", icon_path = "gui/images/svg_icons/icon_add_user.svg", icon_active_menu = "gui/images/svg_icons/active_menu.svg", - is_active = False + is_active = False, + is_toggle_active = False ): super(PyLeftMenuButton, self).__init__() self.setText(text) @@ -73,12 +69,13 @@ class PyLeftMenuButton(QPushButton): self._icon_color_pressed = icon_color_pressed self._icon_color_active = icon_color_active self._icon_active_menu = icon_active_menu - self._is_active = is_active self._set_icon_color = self._icon_color # Set icon color self._set_bg_color = self._dark_one # Set BG color self._set_text_foreground = text_foreground self._set_text_active = text_active self._parent = app_parent + self._is_active = is_active + self._is_toggle_active = is_toggle_active # TOOLTIP self._tooltip_text = tooltip_text @@ -133,34 +130,65 @@ class PyLeftMenuButton(QPushButton): p.setPen(QColor(self._set_text_active)) p.drawText(rect_text, Qt.AlignVCenter, self.text()) + # DRAW ICONS + self.icon_paint(p, self._icon_path, rect_icon, self._set_icon_color) + # NORMAL BG else: - # BG INSIDE - p.setBrush(QColor(self._set_bg_color)) - p.drawRoundedRect(rect_inside, 8, 8) + if self._is_toggle_active: + # BG INSIDE + p.setBrush(QColor(self._dark_three)) + p.drawRoundedRect(rect_inside, 8, 8) - # DRAW TEXT - p.setPen(QColor(self._set_text_foreground)) - p.drawText(rect_text, Qt.AlignVCenter, self.text()) + # DRAW TEXT + p.setPen(QColor(self._set_text_foreground)) + p.drawText(rect_text, Qt.AlignVCenter, self.text()) - # DRAW ICONS - self.icon_paint(p, self._icon_path, rect_icon) + # DRAW ICONS + if self._is_toggle_active: + self.icon_paint(p, self._icon_path, rect_icon, self._context_color) + else: + self.icon_paint(p, self._icon_path, rect_icon, self._set_icon_color) + else: + # BG INSIDE + p.setBrush(QColor(self._set_bg_color)) + p.drawRoundedRect(rect_inside, 8, 8) + + # DRAW TEXT + p.setPen(QColor(self._set_text_foreground)) + p.drawText(rect_text, Qt.AlignVCenter, self.text()) + + # DRAW ICONS + self.icon_paint(p, self._icon_path, rect_icon, self._set_icon_color) p.end() - # DRAW ICON WITH COLORS + # SET ACTIVE MENU # /////////////////////////////////////////////////////////////// def set_active(self, is_active): self._is_active = is_active + if not is_active: + self._set_icon_color = self._icon_color + self.repaint() + + # SET ACTIVE TOGGLE + # /////////////////////////////////////////////////////////////// + def set_active_toggle(self, is_active): + self._is_toggle_active = is_active + + # SET ICON + # /////////////////////////////////////////////////////////////// + def set_icon(self, icon_path): + self._icon_path = icon_path self.repaint() # DRAW ICON WITH COLORS # /////////////////////////////////////////////////////////////// - def icon_paint(self, qp, image, rect): + def icon_paint(self, qp, image, rect, color): icon = QPixmap(image) painter = QPainter(icon) painter.setCompositionMode(QPainter.CompositionMode_SourceIn) - painter.fillRect(icon.rect(), self._set_icon_color) + painter.fillRect(icon.rect(), color) qp.drawPixmap( (rect.width() - icon.width()) / 2, (rect.height() - icon.height()) / 2, diff --git a/gui/widgets/py_window/py_window.py b/gui/widgets/py_window/py_window.py index b9760c5..f00a471 100644 --- a/gui/widgets/py_window/py_window.py +++ b/gui/widgets/py_window/py_window.py @@ -40,7 +40,8 @@ class PyWindow(QFrame): self, parent, layout = Qt.Vertical, - margin = 5, + margin = 0, + spacing = 2, bg_color = "#2c313c", text_color = "#fff", text_font = "9pt 'Segoe UI'", @@ -86,6 +87,7 @@ class PyWindow(QFrame): # HORIZONTAL LAYOUT self.layout = QHBoxLayout(self) self.layout.setContentsMargins(margin, margin, margin, margin) + self.layout.setSpacing(spacing) # ADD DROP SHADOW # /////////////////////////////////////////////////////////////// diff --git a/settings.json b/settings.json index 1d24c18..dd84267 100644 --- a/settings.json +++ b/settings.json @@ -9,9 +9,14 @@ 960, 540 ], - "menu_size" : { + "lef_menu_size" : { "minimum" : 50, "maximum" : 240 }, + "left_menu_content_margins" : 3, + "lef_column_size" : { + "minimum" : 240, + "maximum" : 240 + }, "theme_name": "default" } \ No newline at end of file