Compare commits
	
		
			2 Commits
		
	
	
		
			2b306562f8
			...
			4102c73124
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4102c73124 | ||
| 
						 | 
					9d995480a6 | 
@ -1,9 +1,11 @@
 | 
			
		||||
from PySide6.QtWidgets import (
 | 
			
		||||
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFrame, 
 | 
			
		||||
    QStackedWidget, QSpacerItem, QSizePolicy
 | 
			
		||||
    QStackedWidget, QSpacerItem, QSizePolicy, QGraphicsDropShadowEffect
 | 
			
		||||
)
 | 
			
		||||
from PySide6.QtCore import Qt, QSize
 | 
			
		||||
from PySide6.QtGui import QIcon
 | 
			
		||||
from PySide6.QtGui import QIcon, QColor
 | 
			
		||||
 | 
			
		||||
from app.core.theme import theme_manager
 | 
			
		||||
 | 
			
		||||
class YobbleHomeView(QWidget):
 | 
			
		||||
    def __init__(self, username: str):
 | 
			
		||||
@ -17,33 +19,39 @@ class YobbleHomeView(QWidget):
 | 
			
		||||
        main_layout.setSpacing(0)
 | 
			
		||||
 | 
			
		||||
        # 1. Верхняя панель
 | 
			
		||||
        top_bar = self.create_top_bar()
 | 
			
		||||
        main_layout.addWidget(top_bar)
 | 
			
		||||
        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)
 | 
			
		||||
        main_layout.addWidget(self.content_stack, 1)
 | 
			
		||||
 | 
			
		||||
        # 3. Нижняя панель навигации
 | 
			
		||||
        bottom_bar = self.create_bottom_bar()
 | 
			
		||||
        main_layout.addWidget(bottom_bar)
 | 
			
		||||
        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")
 | 
			
		||||
        top_bar_layout.addWidget(self.burger_menu_button)
 | 
			
		||||
 | 
			
		||||
        # Заголовок
 | 
			
		||||
        self.title_label = QLabel("Чаты") # Начальный заголовок
 | 
			
		||||
        self.title_label = QLabel("Чаты")
 | 
			
		||||
        self.title_label.setObjectName("TitleLabel")
 | 
			
		||||
        top_bar_layout.addWidget(self.title_label)
 | 
			
		||||
        top_bar_layout.addStretch()
 | 
			
		||||
@ -51,44 +59,40 @@ class YobbleHomeView(QWidget):
 | 
			
		||||
        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, 5) # Уменьшаем верхний и нижний отступы
 | 
			
		||||
        bottom_bar_layout.setContentsMargins(10, 0, 10, 0)
 | 
			
		||||
        bottom_bar_layout.setSpacing(10)
 | 
			
		||||
 | 
			
		||||
        # Создаем кнопки
 | 
			
		||||
        btn_feed = self.create_tab_button("📄", "Лента", 0)
 | 
			
		||||
        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)
 | 
			
		||||
        
 | 
			
		||||
        # Центральная кнопка "Создать"
 | 
			
		||||
        btn_create = QPushButton("+")
 | 
			
		||||
        btn_create.setObjectName("CreateButton")
 | 
			
		||||
        btn_create.setFixedSize(50, 50)
 | 
			
		||||
 | 
			
		||||
        # Добавляем кнопки в макет
 | 
			
		||||
        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)
 | 
			
		||||
        
 | 
			
		||||
        # Устанавливаем начальную активную вкладку
 | 
			
		||||
        self.update_tab_selection(2) # Чаты по умолчанию
 | 
			
		||||
        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)
 | 
			
		||||
        
 | 
			
		||||
        layout = QVBoxLayout(button)
 | 
			
		||||
        layout.setContentsMargins(0, 5, 0, 5)
 | 
			
		||||
        layout.setSpacing(2)
 | 
			
		||||
        layout.setSpacing(4)
 | 
			
		||||
 | 
			
		||||
        icon_label = QLabel(icon_text)
 | 
			
		||||
        icon_label.setAlignment(Qt.AlignCenter)
 | 
			
		||||
@ -105,90 +109,125 @@ class YobbleHomeView(QWidget):
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
        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):
 | 
			
		||||
        """Создает страницы-заглушки для QStackedWidget."""
 | 
			
		||||
        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):
 | 
			
		||||
        """Обновляет визуальное состояние кнопок вкладок."""
 | 
			
		||||
        bottom_bar = self.findChild(QWidget, "BottomBar")
 | 
			
		||||
        if not bottom_bar: return
 | 
			
		||||
 | 
			
		||||
        for button in bottom_bar.findChildren(QPushButton):
 | 
			
		||||
            if button.property("tab_index") == selected_index:
 | 
			
		||||
                button.setProperty("selected", True)
 | 
			
		||||
            else:
 | 
			
		||||
                button.setProperty("selected", False)
 | 
			
		||||
            
 | 
			
		||||
            # Обновляем стиль, чтобы изменения применились
 | 
			
		||||
            button.style().unpolish(button)
 | 
			
		||||
            button.style().polish(button)
 | 
			
		||||
        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 стили для компонента."""
 | 
			
		||||
        return """
 | 
			
		||||
            YobbleHomeView {
 | 
			
		||||
                background-color: white; /* Фон для основного виджета */
 | 
			
		||||
            }
 | 
			
		||||
        """Возвращает 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"
 | 
			
		||||
 | 
			
		||||
        return f"""
 | 
			
		||||
            YobbleHomeView {{
 | 
			
		||||
                background-color: {bg_color};
 | 
			
		||||
            }}
 | 
			
		||||
            /* Верхняя панель */
 | 
			
		||||
            #TopBar {
 | 
			
		||||
                background-color: #f5f5f5;
 | 
			
		||||
                border-bottom: 1px solid #e0e0e0;
 | 
			
		||||
            }
 | 
			
		||||
            #BurgerMenuButton {
 | 
			
		||||
            #TopBar {{
 | 
			
		||||
                background-color: {top_bar_bg};
 | 
			
		||||
                border-bottom: 1px solid {top_bar_border};
 | 
			
		||||
            }}
 | 
			
		||||
            #BurgerMenuButton {{
 | 
			
		||||
                font-size: 24px;
 | 
			
		||||
                border: none;
 | 
			
		||||
                padding: 5px;
 | 
			
		||||
            }
 | 
			
		||||
            #TitleLabel {
 | 
			
		||||
                color: {title_color};
 | 
			
		||||
            }}
 | 
			
		||||
            #TitleLabel {{
 | 
			
		||||
                font-size: 18px;
 | 
			
		||||
                font-weight: bold;
 | 
			
		||||
            }
 | 
			
		||||
                color: {title_color};
 | 
			
		||||
            }}
 | 
			
		||||
 | 
			
		||||
            /* Нижняя панель */
 | 
			
		||||
            #BottomBar {
 | 
			
		||||
                background-color: #f5f5f5;
 | 
			
		||||
                border-top: 1px solid #e0e0e0;
 | 
			
		||||
            }
 | 
			
		||||
            #BottomBar {{
 | 
			
		||||
                background-color: {bar_bg_color};
 | 
			
		||||
                border-top: 1px solid {bar_border_color};
 | 
			
		||||
                padding-top: 5px;
 | 
			
		||||
                padding-bottom: 15px;
 | 
			
		||||
            }}
 | 
			
		||||
 | 
			
		||||
            /* Кнопки вкладок */
 | 
			
		||||
            #TabButton {
 | 
			
		||||
            #TabButton {{
 | 
			
		||||
                background-color: transparent;
 | 
			
		||||
                border: none;
 | 
			
		||||
                padding: 5px;
 | 
			
		||||
                color: #888;
 | 
			
		||||
            }
 | 
			
		||||
            #TabButton[selected="true"] #TabText {
 | 
			
		||||
                color: #007AFF; /* Яркий синий для активной вкладки */
 | 
			
		||||
            }
 | 
			
		||||
            #TabButton[selected="true"] #TabIcon {
 | 
			
		||||
                color: #007AFF;
 | 
			
		||||
            }
 | 
			
		||||
            #TabIcon { font-size: 22px; }
 | 
			
		||||
            #TabText { font-size: 12px; }
 | 
			
		||||
            }}
 | 
			
		||||
            #TabButton #TabIcon {{ color: {text_color}; }}
 | 
			
		||||
            #TabButton #TabText {{ color: {text_color}; }}
 | 
			
		||||
 | 
			
		||||
            #TabButton[selected="true"] #TabIcon,
 | 
			
		||||
            #TabButton[selected="true"] #TabText {{
 | 
			
		||||
                color: {active_color};
 | 
			
		||||
            }}
 | 
			
		||||
            #TabIcon {{ font-size: 22px; }}
 | 
			
		||||
            #TabText {{ font-size: 12px; }}
 | 
			
		||||
 | 
			
		||||
            /* Центральная кнопка "Создать" */
 | 
			
		||||
            #CreateButton {
 | 
			
		||||
                background-color: #007AFF;
 | 
			
		||||
            #CreateButton {{
 | 
			
		||||
                color: white;
 | 
			
		||||
                font-size: 24px;
 | 
			
		||||
                font-weight: bold;
 | 
			
		||||
                font-size: 30px;
 | 
			
		||||
                font-weight: 300;
 | 
			
		||||
                border: none;
 | 
			
		||||
                border-radius: 25px; /* Делает ее круглой */
 | 
			
		||||
            }
 | 
			
		||||
            #CreateButton:hover {
 | 
			
		||||
                background-color: #0056b3;
 | 
			
		||||
            }
 | 
			
		||||
                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
 | 
			
		||||
                );
 | 
			
		||||
            }}
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user