desktop_app/app/ui/views/yobble_home_view.py
2025-09-26 15:32:27 +03:00

268 lines
9.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFrame,
QStackedWidget, QSpacerItem, QSizePolicy, QGraphicsDropShadowEffect
)
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QIcon, QColor
from app.core.theme import theme_manager
class YobbleHomeView(QWidget):
def __init__(self, username: str):
super().__init__()
self.username = username
self.setWindowTitle(f"Yobble Home - {username}")
# --- Основной макет ---
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# 1. Верхняя панель
self.top_bar = self.create_top_bar()
main_layout.addWidget(self.top_bar)
# 2. Центральная область контента
self.content_stack = QStackedWidget()
self.setup_content_pages()
main_layout.addWidget(self.content_stack, 1)
# 3. Нижняя панель навигации
self.bottom_bar = self.create_bottom_bar()
main_layout.addWidget(self.bottom_bar)
self.update_styles() # Применяем стили при инициализации
# Подключаемся к сигналу смены темы
theme_manager.theme_changed.connect(self.update_styles)
def update_styles(self):
"""Обновляет стили компонента при смене темы."""
self.setStyleSheet(self.get_stylesheet())
def create_top_bar(self):
"""Создает верхнюю панель с меню и заголовком."""
top_bar_widget = QWidget()
top_bar_widget.setObjectName("TopBar")
top_bar_layout = QHBoxLayout(top_bar_widget)
top_bar_layout.setContentsMargins(10, 5, 10, 5)
self.burger_menu_button = QPushButton("")
self.burger_menu_button.setObjectName("BurgerMenuButton")
self.burger_menu_button.setFocusPolicy(Qt.NoFocus)
top_bar_layout.addWidget(self.burger_menu_button)
self.title_label = QLabel("Чаты")
self.title_label.setObjectName("TitleLabel")
top_bar_layout.addWidget(self.title_label)
top_bar_layout.addStretch()
return top_bar_widget
def create_bottom_bar(self):
"""Создает нижнюю панель навигации в стиле SwiftUI."""
bottom_bar_widget = QWidget()
bottom_bar_widget.setObjectName("BottomBar")
bottom_bar_layout = QHBoxLayout(bottom_bar_widget)
bottom_bar_layout.setContentsMargins(10, 0, 10, 0)
bottom_bar_layout.setSpacing(10)
btn_feed = self.create_tab_button("", "Лента", 0)
btn_search = self.create_tab_button("🔍", "Поиск", 1)
btn_create = self.create_create_button()
btn_chats = self.create_tab_button("💬", "Чаты", 2)
btn_profile = self.create_tab_button("👤", "Лицо", 3)
bottom_bar_layout.addWidget(btn_feed)
bottom_bar_layout.addWidget(btn_search)
bottom_bar_layout.addWidget(btn_create)
bottom_bar_layout.addWidget(btn_chats)
bottom_bar_layout.addWidget(btn_profile)
for btn in [btn_feed, btn_search, btn_chats, btn_profile]:
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
btn.setFocusPolicy(Qt.NoFocus)
btn_create.setFocusPolicy(Qt.NoFocus)
self.update_tab_selection(2)
return bottom_bar_widget
def create_tab_button(self, icon_text, text, index):
button = QPushButton()
button.setObjectName("TabButton")
button.setCursor(Qt.PointingHandCursor)
button.setFocusPolicy(Qt.NoFocus)
layout = QVBoxLayout(button)
layout.setContentsMargins(0, 5, 0, 5)
layout.setSpacing(4)
icon_label = QLabel(icon_text)
icon_label.setAlignment(Qt.AlignCenter)
icon_label.setObjectName("TabIcon")
text_label = QLabel(text)
text_label.setAlignment(Qt.AlignCenter)
text_label.setObjectName("TabText")
layout.addWidget(icon_label)
layout.addWidget(text_label)
button.setProperty("tab_index", index)
button.clicked.connect(lambda: self.on_tab_button_clicked(index))
return button
def create_create_button(self):
button = QPushButton("+")
button.setObjectName("CreateButton")
button.setFixedSize(56, 56)
button.setCursor(Qt.PointingHandCursor)
button.setFocusPolicy(Qt.NoFocus)
shadow = QGraphicsDropShadowEffect(self)
shadow.setBlurRadius(18)
shadow.setColor(QColor(0, 0, 0, 100))
shadow.setOffset(0, 3)
button.setGraphicsEffect(shadow)
return button
def setup_content_pages(self):
self.content_stack.addWidget(QLabel("Контент Ленты"))
self.content_stack.addWidget(QLabel("Контент Поиска"))
self.content_stack.addWidget(QLabel("Контент Чатов"))
self.content_stack.addWidget(QLabel("Контент Профиля"))
def on_tab_button_clicked(self, index):
self.content_stack.setCurrentIndex(index)
self.update_tab_selection(index)
titles = ["Лента", "Поиск", "Чаты", "Лицо"]
self.title_label.setText(titles[index])
def update_tab_selection(self, selected_index):
if not hasattr(self, 'bottom_bar'):
return
for button in self.bottom_bar.findChildren(QPushButton):
is_tab_button = button.property("tab_index") is not None
if is_tab_button:
button.setProperty("selected", button.property("tab_index") == selected_index)
button.style().unpolish(button)
button.style().polish(button)
def get_stylesheet(self):
"""Возвращает QSS стили для компонента в зависимости от темы."""
is_dark = theme_manager.is_dark()
# Цветовая палитра
bg_color = "#1c1c1e" if is_dark else "white"
bar_bg_color = "#2c2c2e" if is_dark else "#f8f8f8"
bar_border_color = "#3c3c3c" if is_dark else "#e7e7e7"
text_color = "#8e8e93" if is_dark else "#888888"
title_color = "white" if is_dark else "black"
active_color = "#0A84FF"
top_bar_bg = "#2c2c2e" if is_dark else "#f5f5f5"
top_bar_border = "#3c3c3c" if is_dark else "#e0e0e0"
hover_color = "#d0d0d0" if not is_dark else "#444444"
return f"""
YobbleHomeView {{
background-color: {bg_color};
}}
/* Глобальные стили для кнопок */
QPushButton {{
background: transparent;
border: none;
outline: none;
}}
QPushButton:focus,
QPushButton:pressed,
QPushButton:checked {{
background: transparent;
border: none;
outline: none;
}}
/* Верхняя панель */
#TopBar {{
background-color: {top_bar_bg};
border-bottom: 1px solid {top_bar_border};
}}
#BurgerMenuButton {{
font-size: 24px;
border: none;
padding: 5px;
color: {title_color};
background: transparent;
}}
#TitleLabel {{
font-size: 18px;
font-weight: bold;
color: {title_color};
}}
/* Нижняя панель */
#BottomBar {{
background-color: {bar_bg_color};
border-top: 1px solid {bar_border_color};
padding-top: 5px;
padding-bottom: 15px;
}}
/* Кнопки вкладок */
#TabButton {{
background: transparent;
border: none;
outline: none;
padding: 5px;
}}
#TabButton:hover {{
background-color: {hover_color};
border-radius: 6px;
}}
#TabButton #TabIcon {{ color: {text_color}; }}
#TabButton #TabText {{ color: {text_color}; }}
#TabButton[selected="true"] #TabIcon,
#TabButton[selected="true"] #TabText {{
color: {active_color};
}}
#TabIcon, #TabText {{
border: none;
outline: none;
background-color: transparent;
}}
#TabIcon {{ font-size: 22px; }}
#TabText {{ font-size: 12px; }}
/* Центральная кнопка "Создать" */
#CreateButton {{
color: white;
font-size: 30px;
font-weight: 300;
border: none;
border-radius: 28px;
background-color: qlineargradient(
x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #007AFF, stop: 1 #0056b3
);
margin-bottom: 20px;
}}
#CreateButton:hover {{
background-color: qlineargradient(
x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #0088FF, stop: 1 #0066c3
);
}}
#CreateButton:pressed {{
background-color: qlineargradient(
x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #0056b3, stop: 1 #004493
);
}}
"""