feat(gui): Implement tabbed interface for discussion takes
This commit is contained in:
14
src/gui_2.py
14
src/gui_2.py
@@ -2309,14 +2309,16 @@ def hello():
|
|||||||
return
|
return
|
||||||
if not self.is_viewing_prior_session and imgui.collapsing_header("Discussions", imgui.TreeNodeFlags_.default_open):
|
if not self.is_viewing_prior_session and imgui.collapsing_header("Discussions", imgui.TreeNodeFlags_.default_open):
|
||||||
names = self._get_discussion_names()
|
names = self._get_discussion_names()
|
||||||
if imgui.begin_combo("##disc_sel", self.active_discussion):
|
if imgui.begin_tab_bar("discussion_takes_tabs"):
|
||||||
for name in names:
|
for name in names:
|
||||||
is_selected = (name == self.active_discussion)
|
# Only force selection if active_discussion changed externally
|
||||||
if imgui.selectable(name, is_selected)[0]:
|
flags = imgui.TabItemFlags_.set_selected if name == self.active_discussion else 0
|
||||||
|
opened, _ = imgui.begin_tab_item(name, None, flags)
|
||||||
|
if opened:
|
||||||
|
if name != self.active_discussion:
|
||||||
self._switch_discussion(name)
|
self._switch_discussion(name)
|
||||||
if is_selected:
|
imgui.end_tab_item()
|
||||||
imgui.set_item_default_focus()
|
imgui.end_tab_bar()
|
||||||
imgui.end_combo()
|
|
||||||
if self.active_track:
|
if self.active_track:
|
||||||
imgui.same_line()
|
imgui.same_line()
|
||||||
changed, self._track_discussion_active = imgui.checkbox("Track Discussion", self._track_discussion_active)
|
changed, self._track_discussion_active = imgui.checkbox("Track Discussion", self._track_discussion_active)
|
||||||
|
|||||||
48
tests/test_gui_discussion_tabs.py
Normal file
48
tests/test_gui_discussion_tabs.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import pytest
|
||||||
|
from unittest.mock import patch, MagicMock, PropertyMock
|
||||||
|
|
||||||
|
from src import gui_2
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_gui():
|
||||||
|
gui = gui_2.App()
|
||||||
|
gui.project = {
|
||||||
|
'discussion': {
|
||||||
|
'active': 'main',
|
||||||
|
'discussions': {
|
||||||
|
'main': {'history': []},
|
||||||
|
'take_1': {'history': []},
|
||||||
|
'take_2': {'history': []}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gui.active_discussion = 'main'
|
||||||
|
# Mock some required state
|
||||||
|
gui.perf_profiling_enabled = False
|
||||||
|
gui.is_viewing_prior_session = False
|
||||||
|
gui._get_discussion_names = lambda: ['main', 'take_1', 'take_2']
|
||||||
|
return gui
|
||||||
|
|
||||||
|
def test_discussion_tabs_rendered(mock_gui):
|
||||||
|
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||||
|
patch('src.app_controller.AppController.active_project_root', new_callable=PropertyMock, return_value='.'):
|
||||||
|
# We expect a tab bar to be used instead of a combo box
|
||||||
|
mock_imgui.begin_tab_bar.return_value = True
|
||||||
|
mock_imgui.begin_tab_item.return_value = (True, True)
|
||||||
|
mock_imgui.input_text.return_value = (False, "")
|
||||||
|
mock_imgui.checkbox.return_value = (False, False)
|
||||||
|
mock_imgui.input_int.return_value = (False, 0)
|
||||||
|
|
||||||
|
# Prevent infinite loop in ListClipper
|
||||||
|
mock_clipper = MagicMock()
|
||||||
|
mock_clipper.step.return_value = False
|
||||||
|
mock_imgui.ListClipper.return_value = mock_clipper
|
||||||
|
|
||||||
|
mock_gui._render_discussion_panel()
|
||||||
|
|
||||||
|
mock_imgui.begin_tab_bar.assert_called_once_with('discussion_takes_tabs')
|
||||||
|
# Check that begin_tab_item was called for each take
|
||||||
|
calls = [c[0][0] for c in mock_imgui.begin_tab_item.call_args_list]
|
||||||
|
assert 'main' in calls
|
||||||
|
assert 'take_1' in calls
|
||||||
|
assert 'take_2' in calls
|
||||||
Reference in New Issue
Block a user