Skip to content

Commit 06a6055

Browse files
committed
ui: Make side panels to overlay the center panel in autohide layout.
This commit makes the side panels to overlay the body which avoids squashing and stretching of the message view which improves UX in autohide mode. To do this the `show_panel` functions have been updated to use Overlay. The focus setting in the `show_panel` functions which could be avoided at a later point needed a reordering in the SEARCH keypress which actually makes it the correct order, i.e., * first handle autohide * then handle search Tests updated.
1 parent 972add9 commit 06a6055

File tree

2 files changed

+69
-25
lines changed

2 files changed

+69
-25
lines changed

tests/ui/test_ui.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@ def mock_external_classes(self, mocker: MockerFixture) -> None:
2222
self.model = mocker.patch(CONTROLLER + ".model")
2323
self.write_box = mocker.patch(MODULE + ".WriteBox")
2424
self.search_box = mocker.patch(MODULE + ".SearchBox")
25-
26-
@pytest.fixture
27-
def view(self, mocker: MockerFixture) -> View:
2825
mocker.patch(MODULE + ".TabView")
2926
mocker.patch(MODULE + ".LeftColumnView")
3027
mocker.patch("zulipterminal.ui_tools.views.urwid.Frame")
3128
mocker.patch("zulipterminal.ui_tools.views.MessageView")
3229
mocker.patch(MODULE + ".RightColumnView")
3330

31+
@pytest.fixture
32+
def view(self, mocker: MockerFixture) -> View:
3433
# View is an urwid.Frame instance, a Box widget.
3534
mocker.patch(VIEW + ".sizing", return_value=frozenset({"box"}))
3635

@@ -235,37 +234,56 @@ def just_set_message_view(self: Any) -> None:
235234
def test_show_panel_methods(
236235
self,
237236
mocker: MockerFixture,
238-
view: View,
239237
visible: bool,
240238
autohide: bool,
241239
test_method: str,
242240
) -> None:
243-
view.body = mocker.Mock()
244-
view.body.contents = [view.left_panel, mocker.Mock(), mocker.Mock()]
245-
view.controller.autohide = autohide
246-
241+
self.controller.autohide = autohide
242+
view = View(self.controller)
243+
view.frame.body = view.body
244+
expected_overlay_options = [
245+
"",
246+
None,
247+
"given",
248+
0,
249+
None,
250+
0,
251+
0,
252+
"top",
253+
None,
254+
"relative",
255+
100,
256+
None,
257+
0,
258+
0,
259+
]
247260
if test_method == "left_panel":
248-
expected_width = LEFT_WIDTH
261+
expected_overlay_options[0] = "left"
262+
expected_overlay_options[3] = LEFT_WIDTH + 1
249263
expected_tab = view.left_tab
250264
expected_panel = view.left_panel
251265

252266
view.show_left_panel(visible=visible)
253267
else:
254-
expected_width = RIGHT_WIDTH
268+
expected_overlay_options[0] = "right"
269+
expected_overlay_options[3] = RIGHT_WIDTH + 1
255270
expected_tab = view.right_tab
256271
expected_panel = view.right_panel
257272

258273
view.show_right_panel(visible=visible)
259274

260275
if autohide:
261276
if visible:
262-
assert (expected_panel, mocker.ANY) in view.body.contents
263-
view.body.options.assert_called_once_with("given", expected_width)
277+
assert (expected_panel, mocker.ANY) in view.frame.body.top_w.contents
278+
assert view.frame.body.bottom_w == view.body
279+
assert view.frame.body.contents[1][1] == tuple(expected_overlay_options)
264280
else:
265-
assert (expected_tab, mocker.ANY) in view.body.contents
266-
view.body.options.assert_called_once_with("given", TAB_WIDTH)
281+
assert (expected_tab, mocker.ANY) in view.frame.body.contents
282+
assert view.body.focus_position == 1
267283
else:
268-
view.body.options.assert_not_called()
284+
# No change
285+
assert view.frame.body.contents[0][0] == view.left_panel
286+
assert view.frame.body.contents[2][0] == view.right_panel
269287

270288
def test_keypress_normal_mode_navigation(
271289
self,

zulipterminal/ui.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,43 @@ def show_left_panel(self, *, visible: bool) -> None:
190190
if not self.controller.autohide:
191191
return
192192

193-
width = LEFT_WIDTH if visible else TAB_WIDTH
194-
widget = self.left_panel if visible else self.left_tab
195-
self.body.contents[0] = (widget, self.body.options("given", width))
193+
if visible:
194+
self.frame.body = urwid.Overlay(
195+
urwid.Columns(
196+
[(LEFT_WIDTH, self.left_panel), (1, urwid.SolidFill("▏"))]
197+
),
198+
self.body,
199+
align="left",
200+
width=LEFT_WIDTH + 1,
201+
valign="top",
202+
height=("relative", 100),
203+
)
204+
else:
205+
self.frame.body = self.body
206+
# FIXME: This can be avoided after fixing the "sacrificing 1st
207+
# unread msg" issue and setting focus_column=1 when initializing.
208+
self.body.focus_position = 1
196209

197210
def show_right_panel(self, *, visible: bool) -> None:
198211
if not self.controller.autohide:
199212
return
200213

201-
width = RIGHT_WIDTH if visible else TAB_WIDTH
202-
widget = self.right_panel if visible else self.right_tab
203-
self.body.contents[2] = (widget, self.body.options("given", width))
214+
if visible:
215+
self.frame.body = urwid.Overlay(
216+
urwid.Columns(
217+
[(1, urwid.SolidFill("▕")), (RIGHT_WIDTH, self.right_panel)]
218+
),
219+
self.body,
220+
align="right",
221+
width=RIGHT_WIDTH + 1,
222+
valign="top",
223+
height=("relative", 100),
224+
)
225+
else:
226+
self.frame.body = self.body
227+
# FIXME: This can be avoided after fixing the "sacrificing 1st
228+
# unread msg" issue and setting focus_column=1 when initializing.
229+
self.body.focus_position = 1
204230

205231
def keypress(self, size: urwid_Box, key: str) -> Optional[str]:
206232
self.model.new_user_input = True
@@ -227,19 +253,19 @@ def keypress(self, size: urwid_Box, key: str) -> Optional[str]:
227253
self.mentioned_button.activate(key)
228254
elif is_command_key("SEARCH_PEOPLE", key):
229255
# Start User Search if not in editor_mode
230-
self.body.focus_position = 2
231-
self.users_view.keypress(size, key)
232256
self.show_left_panel(visible=False)
233257
self.show_right_panel(visible=True)
258+
self.body.focus_position = 2
259+
self.users_view.keypress(size, key)
234260
return key
235261
elif is_command_key("SEARCH_STREAMS", key) or is_command_key(
236262
"SEARCH_TOPICS", key
237263
):
238264
# jump stream search
239-
self.body.focus_position = 0
240-
self.left_panel.keypress(size, key)
241265
self.show_right_panel(visible=False)
242266
self.show_left_panel(visible=True)
267+
self.body.focus_position = 0
268+
self.left_panel.keypress(size, key)
243269
return key
244270
elif is_command_key("OPEN_DRAFT", key):
245271
saved_draft = self.model.session_draft_message()

0 commit comments

Comments
 (0)