diff --git a/src/calibre/gui2/central.py b/src/calibre/gui2/central.py index 4e0766cc7e..75300b2900 100644 --- a/src/calibre/gui2/central.py +++ b/src/calibre/gui2/central.py @@ -191,6 +191,9 @@ class SplitterHandle(QWidget): def __init__(self, parent: QWidget=None, orientation: Qt.Orientation = Qt.Orientation.Vertical): super().__init__(parent) + self.set_orientation(orientation) + + def set_orientation(self, orientation): self.orientation = orientation if orientation is Qt.Orientation.Vertical: self.setCursor(Qt.CursorShape.SplitHCursor) @@ -362,6 +365,10 @@ class CentralContainer(QWidget): self.top_handle = h(Qt.Orientation.Horizontal) self.bottom_handle = h(Qt.Orientation.Horizontal) + @property + def narrow_cb_on_top(self): + return self.width() / self.height() <= 1.4 + @property def is_visible(self): return self.wide_is_visible if self.layout is Layout.wide else self.narrow_is_visible @@ -565,8 +572,10 @@ class CentralContainer(QWidget): self.book_list.setVisible(self.is_visible.book_list) self.quick_view.setVisible(self.is_visible.quick_view) if self.layout is Layout.wide: + self.right_handle.set_orientation(Qt.Orientation.Vertical) self.do_wide_layout() else: + self.right_handle.set_orientation(Qt.Orientation.Horizontal if self.narrow_cb_on_top else Qt.Orientation.Vertical) self.do_narrow_layout() self.update() @@ -737,7 +746,59 @@ class CentralContainer(QWidget): def min_central_height_narrow(self): return max(150, self.cover_browser.minimumHeight()) + def do_narrow_layout_with_cb_on_top(self): + s = self.style() + normal_handle_width = int(s.pixelMetric(QStyle.PixelMetric.PM_SplitterWidth, widget=self)) + available_height = self.height() + for handle in (self.bottom_handle, self.right_handle): + hs = handle.state + height = self.bottom_handle.COLLAPSED_SIZE + if hs is HandleState.both_visible or hs is HandleState.only_side_visible: + height = normal_handle_width + handle.resize(self.width(), height) + available_height -= height + bd = int(self.narrow_desires.book_details_height * self.height()) if self.is_visible.book_details else 0 + bd = max(0, min(bd, max(0, available_height - self.min_central_height_narrow() - 40))) + central_height = available_height - bd + self.right_handle.height() + self.bottom_handle.move(0, central_height - self.bottom_handle.height()) + if self.is_visible.book_details: + self.book_details.setGeometry(0, self.bottom_handle.y() + self.bottom_handle.height(), self.width(), bd) + available_width = self.width() + hs = self.left_handle.state + width = self.left_handle.COLLAPSED_SIZE + if hs is HandleState.both_visible or hs is HandleState.only_side_visible: + width = normal_handle_width + self.left_handle.resize(width, central_height) + available_width -= width + tb = int(self.narrow_desires.tag_browser_width * self.width()) if self.is_visible.tag_browser else 0 + self.left_handle.move(tb, 0) + if self.is_visible.tag_browser: + self.tag_browser.setGeometry(0, 0, tb, central_height) + central_x = self.left_handle.x() + self.left_handle.width() + central_width = self.width() - central_x + central_height -= self.right_handle.height() + cb = min(max(0, central_height - 80), int(self.height() * self.narrow_desires.cover_browser_width)) if self.is_visible.cover_browser else 0 + if cb and cb < self.cover_browser.minimumHeight(): + cb = min(self.cover_browser.minimumHeight(), central_height) + if self.is_visible.cover_browser: + self.cover_browser.setGeometry(central_x, 0, central_width, cb) + self.right_handle.resize(central_width, self.right_handle.height()) + self.right_handle.move(central_x, cb) + central_top = self.right_handle.y() + self.right_handle.height() + central_height = self.bottom_handle.y() - central_top + self.top_handle.resize(central_width, normal_handle_width if self.is_visible.quick_view else 0) + available_height = central_height - self.top_handle.height() + qv = int(self.height() * self.narrow_desires.quick_view_height) if self.is_visible.quick_view else 0 + qv = min(qv, max(0, available_height - 80)) + bl = max(0, available_height - qv) + self.book_list.setGeometry(central_x, central_top, central_width, bl) + self.top_handle.move(central_x, self.book_list.y() + self.book_list.height()) + if self.is_visible.quick_view: + self.quick_view.setGeometry(central_x, self.top_handle.y() + self.top_handle.height(), central_width, qv) + def do_narrow_layout(self): + if self.narrow_cb_on_top: + return self.do_narrow_layout_with_cb_on_top() s = self.style() normal_handle_width = int(s.pixelMetric(QStyle.PixelMetric.PM_SplitterWidth, widget=self)) available_height = self.height() @@ -798,6 +859,8 @@ class CentralContainer(QWidget): if handle is self.left_handle: x = int(pos.x()) available_width = self.width() - self.left_handle.width() - self.right_handle.width() - self.min_central_width_narrow() + if self.narrow_cb_on_top: + available_width += self.right_handle.width() self.is_visible.tag_browser = True if x < HIDE_THRESHOLD: self.is_visible.tag_browser = False @@ -805,15 +868,24 @@ class CentralContainer(QWidget): else: self.narrow_desires.tag_browser_width = min(available_width, x) / self.width() elif handle is self.right_handle: - x = int(pos.x()) - available_width = self.width() - self.left_handle.width() - self.right_handle.width() - self.min_central_width_narrow() - self.is_visible.cover_browser = True - w = min(available_width, self.width() - x - self.right_handle.width()) - if w < HIDE_THRESHOLD: - self.is_visible.cover_browser = False - self.narrow_desires.book_details_width = 0 + if self.narrow_cb_on_top: + y = int(pos.y()) + self.is_visible.cover_browser = True + if y < max(self.cover_browser.minimumHeight(), HIDE_THRESHOLD): + self.is_visible.cover_browser = False + self.narrow_desires.cover_browser_width = 0 + else: + self.narrow_desires.cover_browser_width = max(y, self.cover_browser.minimumHeight()) / self.height() else: - self.narrow_desires.cover_browser_width = max(self.cover_browser.minimumWidth(), w) / self.width() + x = int(pos.x()) + available_width = self.width() - self.left_handle.width() - self.right_handle.width() - self.min_central_width_narrow() + self.is_visible.cover_browser = True + w = min(available_width, self.width() - x - self.right_handle.width()) + if w < HIDE_THRESHOLD: + self.is_visible.cover_browser = False + self.narrow_desires.book_details_width = 0 + else: + self.narrow_desires.cover_browser_width = max(self.cover_browser.minimumWidth(), w) / self.width() elif handle is self.bottom_handle: y = int(pos.y()) h = self.height() - y - self.bottom_handle.height()