Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 248 additions & 19 deletions src/main/python/mainApp.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,14 @@ def __init__(self):
self.addDockWidget(Qt.LeftDockWidgetArea, self.selectedElementsDock)
self.selectedElementsDock.hide()

self.dockWidget.setFeatures(QDockWidget.DockWidgetFloatable |
QDockWidget.DockWidgetMovable |
QDockWidget.DockWidgetClosable)
# ── Rebuild Component Selector dock with compact modern design ──
self._build_component_selector()

self.dockWidget_2.setFeatures(QDockWidget.DockWidgetFloatable |
QDockWidget.DockWidgetMovable |
QDockWidget.DockWidgetClosable)

self.dockWidget.setMinimumSize(200, 200)
self.dockWidget_2.setMinimumSize(200, 100)

self.dockWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.dockWidget_2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.dockWidget_2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

# Setting up interactive canvas
self.scene = self.container.graphics.get_scene()
Expand All @@ -224,6 +220,9 @@ def __init__(self):
self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)
self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
self.addDockWidget(Qt.RightDockWidgetArea, self.dockWidget)
# Pin dock width AFTER addDockWidget — this is the only point where it sticks.
# setFixedWidth before addDockWidget gets overridden by Qt's layout engine.
self.dockWidget.setFixedWidth(240)
self.addDockWidget(Qt.BottomDockWidgetArea, self.dockWidget_2)

# Set initial dock sizes after the window has been shown
Expand All @@ -246,19 +245,249 @@ def __init__(self):
push('Undo', initial_snapshot)
self._update_undo_redo_actions()

def _apply_initial_layout(self):
# Component Selector: ~300px wide, Selected Compounds: ~130px wide
self.resizeDocks(
[self.selectedElementsDock, self.dockWidget],
[130, 300],
Qt.Horizontal
def _build_component_selector(self):
"""Rebuild the Component Selector dock with collapse/expand toggle."""
ACCENT = '#0a84ff'
ACCENT_LIGHT = '#3d9fff'
BG = '#ffffff'
HEADER_BG = '#f2f2f2'
BTN_BG = '#ffffff'
BTN_BORDER = '#e0e0e0'
TEXT = '#333333'
ICON_SIZE = 30
BTN_HEIGHT = 50
HEADER_HEIGHT = 30

icons_base = os.path.join(parentPath, 'resources', 'base', 'icons')

sections = [
('Streams', [
('pushButton', 'MaterialStream', 'MaterialStream.png'),
]),
('Mixer/Splitter', [
('pushButton_7', 'Mixer', 'Mixer.png'),
('pushButton_10', 'Splitter', 'Splitter.png'),
]),
('Exchangers', [
('pushButton_11', 'Heater', 'Heater.png'),
('pushButton_12', 'Cooler', 'Cooler.png'),
]),
('Separator', [
('pushButton_9', 'Flash', 'Flash.png'),
('pushButton_13', 'Compound Sep.', 'CompoundSeparator.png'),
]),
('Pressure Changers', [
('pushButton_25', 'Valve', 'Valve.png'),
('pushButton_14', 'Centrifugal Pump', 'CentrifugalPump.png'),
('pushButton_15', 'Adiab. Compressor','AdiabaticCompressor.png'),
('pushButton_16', 'Adiab. Expander', 'AdiabaticExpander.png'),
]),
('Columns', [
('pushButton_26', 'Distillation Col.','DistillationColumn.png'),
('pushButton_18', 'Shortcut Col.', 'ShortcutColumn.png'),
]),
]

# ── State storage for toggle ──
self._panel_collapsed = False
self._comp_btn_data = [] # list of (QPushButton, display_text)
self._comp_headers = [] # section header QLabels

# Pre-build the two button stylesheets so toggle is instant
self._btn_style_expanded = f"""
QPushButton {{
background: {BTN_BG};
color: {TEXT};
font: bold 10pt 'Microsoft JhengHei';
border: 1px solid {BTN_BORDER};
border-radius: 4px;
text-align: left;
padding: 0 6px;
}}
QPushButton:hover {{
background: #e8f0fe;
border-color: {ACCENT};
color: {ACCENT};
}}
QPushButton:pressed {{
background: #d0e3ff;
border-color: {ACCENT};
}}
"""
self._btn_style_collapsed = f"""
QPushButton {{
background: {BTN_BG};
border: 1px solid {BTN_BORDER};
border-radius: 4px;
text-align: center;
padding: 0;
}}
QPushButton:hover {{
background: #e8f0fe;
border-color: {ACCENT};
}}
QPushButton:pressed {{
background: #d0e3ff;
border-color: {ACCENT};
}}
"""

# ── Configure dockWidget ──
self.dockWidget.setFeatures(
QDockWidget.DockWidgetFloatable |
QDockWidget.DockWidgetMovable |
QDockWidget.DockWidgetClosable
)
self.dockWidget.setWindowTitle('Components')
# Width pinned after addDockWidget in __init__

# ── content widget ──
content = QWidget()
content.setStyleSheet(f'background: {BG};')
main_layout = QVBoxLayout(content)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)

# ── Collapse / Expand toggle button ──
toggle_btn = QPushButton('▶')
toggle_btn.setFixedHeight(24)
toggle_btn.setCursor(Qt.PointingHandCursor)
toggle_btn.setToolTip('Collapse panel')
toggle_btn.setStyleSheet(f"""
QPushButton {{
background: #f8f8f8;
color: #999999;
font: bold 11pt;
border: none;
border-bottom: 1px solid #e0e0e0;
border-radius: 0;
}}
QPushButton:hover {{
background: #e8f0fe;
color: {ACCENT};
}}
QPushButton:pressed {{
background: #d0e3ff;
}}
""")
toggle_btn.clicked.connect(self._toggle_component_panel)
self._panel_toggle_btn = toggle_btn
main_layout.addWidget(toggle_btn)

# ── scroll area ──
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
scroll.setFrameShape(QFrame.NoFrame)
scroll.setStyleSheet(f"""
QScrollArea {{
background: {BG};
border: none;
}}
QScrollBar:vertical {{
background: {BG};
width: 6px;
margin: 0;
border: none;
}}
QScrollBar::handle:vertical {{
background: #c8c8c8;
min-height: 30px;
border-radius: 3px;
}}
QScrollBar::handle:vertical:hover {{
background: {ACCENT_LIGHT};
}}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical {{
height: 0;
}}
""")

# ── scroll contents widget ──
scroll_widget = QWidget()
scroll_widget.setStyleSheet(f'background: {BG};')
scroll_layout = QVBoxLayout(scroll_widget)
scroll_layout.setContentsMargins(4, 4, 4, 4)
scroll_layout.setSpacing(2)

for section_name, buttons in sections:
header = QLabel(section_name.upper())
header.setFixedHeight(HEADER_HEIGHT)
header.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
header.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
header.setStyleSheet(f"""
QLabel {{
color: #666666;
font: bold 8pt 'Segoe UI';
background: {HEADER_BG};
border-radius: 3px;
padding: 0 6px;
}}
""")
self._comp_headers.append(header)
scroll_layout.addWidget(header)

for attr_name, display_text, icon_file in buttons:
btn = QPushButton(f' {display_text}')
btn.setFixedHeight(BTN_HEIGHT)
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
btn.setCursor(Qt.PointingHandCursor)

icon_path = os.path.join(icons_base, icon_file)
if os.path.exists(icon_path):
btn.setIcon(QIcon(icon_path))
btn.setIconSize(QSize(ICON_SIZE, ICON_SIZE))

btn.setStyleSheet(self._btn_style_expanded)

setattr(self, attr_name, btn)
self._comp_btn_data.append((btn, display_text))
scroll_layout.addWidget(btn)

scroll_layout.addStretch(1)
scroll.setWidget(scroll_widget)
main_layout.addWidget(scroll)
self.dockWidget.setWidget(content)

def _toggle_component_panel(self):
"""Collapse to icon-only (48px) or expand to full text (240px)."""
COLLAPSED_W = 48
EXPANDED_W = 240

if not self._panel_collapsed:
# ── Collapse ──
for btn, _ in self._comp_btn_data:
btn.setText('')
btn.setStyleSheet(self._btn_style_collapsed)
for h in self._comp_headers:
h.hide()
self._panel_toggle_btn.setText('◀')
self._panel_toggle_btn.setToolTip('Expand panel')
self.dockWidget.setFixedWidth(COLLAPSED_W)
self._panel_collapsed = True
else:
# ── Expand ──
for btn, text in self._comp_btn_data:
btn.setText(f' {text}')
btn.setStyleSheet(self._btn_style_expanded)
for h in self._comp_headers:
h.show()
self._panel_toggle_btn.setText('▶')
self._panel_toggle_btn.setToolTip('Collapse panel')
# Set to target width then unlock so the user can still resize
self.dockWidget.setFixedWidth(EXPANDED_W)
self.dockWidget.setMinimumWidth(240)
self.dockWidget.setMaximumWidth(524287)
self._panel_collapsed = False

def _apply_initial_layout(self):
# Unlock the dock from its startup fixed width so the user can resize it.
self.dockWidget.setMinimumWidth(240)
self.dockWidget.setMaximumWidth(524287)
# Message Browser: ~120px tall
self.resizeDocks(
[self.dockWidget_2],
[120],
Qt.Vertical
)
self.resizeDocks([self.dockWidget_2], [120], Qt.Vertical)

def _style_dock_separators(self):
self.setStyleSheet(self.styleSheet() + """
Expand Down
6 changes: 3 additions & 3 deletions src/main/ui/utils/main.ui
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</property>
<widget class="QWidget" name="centralwidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
Expand Down Expand Up @@ -230,7 +230,7 @@
</property>
<property name="minimumSize">
<size>
<width>200</width>
<width>150</width>
<height>300</height>
</size>
</property>
Expand Down Expand Up @@ -298,7 +298,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>221</width>
<width>165</width>
<height>956</height>
</rect>
</property>
Expand Down