Add setting to hide bottom toolbar

This commit is contained in:
Matthias Metelka 2023-01-14 01:55:33 +01:00
parent e5a946bb1a
commit ef54865a2c
6 changed files with 124 additions and 47 deletions

View file

@ -51,22 +51,20 @@ body {
-webkit-user-select: none; -webkit-user-select: none;
overflow: hidden; overflow: hidden;
&:not(.fancy).collapsed { &:not(.fancy).hidden {
opacity: 0; opacity: 0;
} }
transition: opacity var(--transition) ease-in-out; transition: opacity var(--transition) ease-in-out;
&.fancy { &.fancy {
&.collapsed { margin-bottom: 5px;
&.hidden {
transform: translateY(-100vh); transform: translateY(-100vh);
} }
transition: transform var(--transition) ease-in-out; transition: transform var(--transition) ease-in-out;
.header {
height: 41px;
}
.toolbar { .toolbar {
height: 31px;
overflow: hidden; overflow: hidden;
border-bottom-left-radius: prop(border-radius-medium); border-bottom-left-radius: prop(border-radius-medium);
border-bottom-right-radius: prop(border-radius-medium); border-bottom-right-radius: prop(border-radius-medium);

View file

@ -66,7 +66,7 @@ from aqt.qt import sip
from aqt.sync import sync_collection, sync_login from aqt.sync import sync_collection, sync_login
from aqt.taskman import TaskManager from aqt.taskman import TaskManager
from aqt.theme import Theme, theme_manager from aqt.theme import Theme, theme_manager
from aqt.toolbar import Toolbar, ToolbarWebView from aqt.toolbar import BottomWebView, Toolbar, TopWebView
from aqt.undo import UndoActionsInfo from aqt.undo import UndoActionsInfo
from aqt.utils import ( from aqt.utils import (
HelpPage, HelpPage,
@ -150,17 +150,17 @@ class MainWebView(AnkiWebView):
return handled return handled
if evt.type() == QEvent.Type.Leave: if evt.type() == QEvent.Type.Leave:
if self.mw.pm.collapse_toolbar(): if self.mw.pm.hide_top_bar():
# Expand toolbar when mouse moves above main webview # Show toolbar when mouse moves outside main webview
# and automatically collapse it with delay after mouse leaves # and automatically hide it with delay after mouse has entered again
if self.mapFromGlobal(QCursor.pos()).y() < self.geometry().y(): self.mw.toolbarWeb.show()
if self.mw.toolbarWeb.collapsed: self.mw.bottomWeb.show()
self.mw.toolbarWeb.expand()
return True return True
if evt.type() == QEvent.Type.Enter: if evt.type() == QEvent.Type.Enter:
if self.mw.pm.collapse_toolbar(): if self.mw.pm.hide_top_bar():
self.mw.toolbarWeb.hide_timer.start() self.mw.toolbarWeb.hide_timer.start()
self.mw.bottomWeb.hide_timer.start()
return True return True
return False return False
@ -729,16 +729,21 @@ class AnkiQt(QMainWindow):
def _reviewState(self, oldState: MainWindowState) -> None: def _reviewState(self, oldState: MainWindowState) -> None:
self.reviewer.show() self.reviewer.show()
if self.pm.collapse_toolbar():
self.toolbarWeb.collapse() if self.pm.hide_top_bar():
self.toolbarWeb.hide()
else: else:
self.toolbarWeb.flatten() self.toolbarWeb.flatten()
if self.pm.hide_bottom_bar():
self.bottomWeb.hide()
def _reviewCleanup(self, newState: MainWindowState) -> None: def _reviewCleanup(self, newState: MainWindowState) -> None:
if newState != "resetRequired" and newState != "review": if newState != "resetRequired" and newState != "review":
self.reviewer.cleanup() self.reviewer.cleanup()
self.toolbarWeb.elevate() self.toolbarWeb.elevate()
self.toolbarWeb.expand() self.toolbarWeb.show()
self.bottomWeb.show()
# Resetting state # Resetting state
########################################################################## ##########################################################################
@ -872,12 +877,12 @@ title="{}" {}>{}</button>""".format(
self.form = aqt.forms.main.Ui_MainWindow() self.form = aqt.forms.main.Ui_MainWindow()
self.form.setupUi(self) self.form.setupUi(self)
# toolbar # toolbar
tweb = self.toolbarWeb = ToolbarWebView(self, title="top toolbar") tweb = self.toolbarWeb = TopWebView(self, title="top toolbar")
self.toolbar = Toolbar(self, tweb) self.toolbar = Toolbar(self, tweb)
# main area # main area
self.web = MainWebView(self) self.web = MainWebView(self)
# bottom area # bottom area
sweb = self.bottomWeb = AnkiWebView(title="bottom toolbar") sweb = self.bottomWeb = BottomWebView(self, title="bottom toolbar")
sweb.setFocusPolicy(Qt.FocusPolicy.WheelFocus) sweb.setFocusPolicy(Qt.FocusPolicy.WheelFocus)
sweb.disable_zoom() sweb.disable_zoom()
# add in a layout # add in a layout
@ -1358,10 +1363,6 @@ title="{}" {}>{}</button>""".format(
window.windowState() ^ Qt.WindowState.WindowFullScreen window.windowState() ^ Qt.WindowState.WindowFullScreen
) )
def collapse_toolbar_if_allowed(self) -> None:
if self.pm.collapse_toolbar() and self.state == "review":
self.toolbarWeb.collapse()
# Auto update # Auto update
########################################################################## ##########################################################################

View file

@ -213,10 +213,11 @@ class Preferences(QDialog):
self.form.minimalist_mode.setChecked(self.mw.pm.minimalist_mode()) self.form.minimalist_mode.setChecked(self.mw.pm.minimalist_mode())
qconnect(self.form.minimalist_mode.stateChanged, self.mw.pm.set_minimalist_mode) qconnect(self.form.minimalist_mode.stateChanged, self.mw.pm.set_minimalist_mode)
self.form.collapse_toolbar.setChecked(self.mw.pm.collapse_toolbar()) self.form.hide_top_bar.setChecked(self.mw.pm.hide_top_bar())
qconnect( qconnect(self.form.hide_top_bar.stateChanged, self.mw.pm.set_hide_top_bar)
self.form.collapse_toolbar.stateChanged, self.mw.pm.set_collapse_toolbar
) self.form.hide_bottom_bar.setChecked(self.mw.pm.hide_bottom_bar())
qconnect(self.form.hide_bottom_bar.stateChanged, self.mw.pm.set_hide_bottom_bar)
self.form.uiScale.setValue(int(self.mw.pm.uiScale() * 100)) self.form.uiScale.setValue(int(self.mw.pm.uiScale() * 100))
themes = [ themes = [

View file

@ -532,13 +532,19 @@ create table if not exists profiles
self.meta["tatsumoto_mode"] = on self.meta["tatsumoto_mode"] = on
gui_hooks.body_classes_need_update() gui_hooks.body_classes_need_update()
def collapse_toolbar(self) -> bool: def hide_top_bar(self) -> bool:
return self.meta.get("collapse_toolbar", False) return self.meta.get("hide_top_bar", False)
def set_collapse_toolbar(self, on: bool) -> None: def set_hide_top_bar(self, on: bool) -> None:
self.meta["collapse_toolbar"] = on self.meta["hide_top_bar"] = on
gui_hooks.body_classes_need_update() gui_hooks.body_classes_need_update()
def hide_bottom_bar(self) -> bool:
return self.meta.get("hide_bottom_bar", False)
def set_hide_bottom_bar(self, on: bool) -> None:
self.meta["hide_bottom_bar"] = on
def last_addon_update_check(self) -> int: def last_addon_update_check(self) -> int:
return self.meta.get("last_addon_update_check", 0) return self.meta.get("last_addon_update_check", 0)

View file

@ -706,7 +706,6 @@ time = %(time)d;
else: else:
maxTime = 0 maxTime = 0
self.bottom.web.eval("showQuestion(%s,%d);" % (json.dumps(middle), maxTime)) self.bottom.web.eval("showQuestion(%s,%d);" % (json.dumps(middle), maxTime))
self.bottom.web.adjustHeightToFit()
def _showEaseButtons(self) -> None: def _showEaseButtons(self) -> None:
middle = self._answerButtons() middle = self._answerButtons()

View file

@ -3,13 +3,14 @@
from __future__ import annotations from __future__ import annotations
import re import re
from typing import Any, Optional from typing import Any, Optional, cast
import aqt import aqt
from anki.sync import SyncStatus from anki.sync import SyncStatus
from aqt import gui_hooks from aqt import gui_hooks, props
from aqt.qt import * from aqt.qt import *
from aqt.sync import get_sync_status from aqt.sync import get_sync_status
from aqt.theme import theme_manager
from aqt.utils import tr from aqt.utils import tr
from aqt.webview import AnkiWebView from aqt.webview import AnkiWebView
@ -32,13 +33,10 @@ class ToolbarWebView(AnkiWebView):
self.mw = mw self.mw = mw
self.setFocusPolicy(Qt.FocusPolicy.WheelFocus) self.setFocusPolicy(Qt.FocusPolicy.WheelFocus)
self.disable_zoom() self.disable_zoom()
self.collapsed = False self.hidden = False
self.web_height = 0
# collapse timer
self.hide_timer = QTimer() self.hide_timer = QTimer()
self.hide_timer.setSingleShot(True) self.hide_timer.setSingleShot(True)
self.hide_timer.setInterval(1000) self.hide_timer.setInterval(1000)
qconnect(self.hide_timer.timeout, self.mw.collapse_toolbar_if_allowed)
def eventFilter(self, obj, evt): def eventFilter(self, obj, evt):
if handled := super().eventFilter(obj, evt): if handled := super().eventFilter(obj, evt):
@ -52,29 +50,58 @@ class ToolbarWebView(AnkiWebView):
return False return False
def hide(self) -> None:
self.hidden = True
def show(self) -> None:
self.hidden = False
def hide_if_allowed(self) -> None:
if self.mw.state != "review":
return
if self.hide_condition():
self.hide()
class TopWebView(ToolbarWebView):
def __init__(self, mw: aqt.AnkiQt, title: str) -> None:
super().__init__(mw, title=title)
self.web_height = 0
self.hide_condition = self.mw.pm.hide_top_bar
qconnect(self.hide_timer.timeout, self.hide_if_allowed)
def on_body_classes_need_update(self) -> None: def on_body_classes_need_update(self) -> None:
super().on_body_classes_need_update() super().on_body_classes_need_update()
super().adjustHeightToFit() self.adjustHeightToFit()
if self.mw.state == "review": if self.mw.state == "review":
if self.mw.pm.collapse_toolbar(): if self.mw.pm.hide_top_bar():
self.eval("""document.body.classList.remove("flat"); """) self.eval("""document.body.classList.remove("flat"); """)
else: else:
self.flatten() self.flatten()
self.expand() self.show()
def _onHeight(self, qvar: Optional[int]) -> None: def _onHeight(self, qvar: Optional[int]) -> None:
super()._onHeight(qvar) super()._onHeight(qvar)
self.web_height = int(qvar) self.web_height = int(qvar)
def collapse(self) -> None: def hide(self) -> None:
self.collapsed = True super().hide()
self.eval("""document.body.classList.add("collapsed"); """)
def expand(self) -> None: self.hidden = True
self.collapsed = False self.eval(
self.eval("""document.body.classList.remove("collapsed"); """) """document.body.classList.add("hidden"); """,
)
self.mw.web.eval(
f"""document.body.style.setProperty("--toolbar-height", "0px"); """
)
def show(self) -> None:
super().show()
self.eval("""document.body.classList.remove("hidden"); """)
def flatten(self) -> None: def flatten(self) -> None:
self.eval("""document.body.classList.add("flat"); """) self.eval("""document.body.classList.add("flat"); """)
@ -108,6 +135,51 @@ class ToolbarWebView(AnkiWebView):
) )
class BottomWebView(ToolbarWebView):
def __init__(self, mw: aqt.AnkiQt, title: str) -> None:
super().__init__(mw, title=title)
self.hide_condition = self.mw.pm.hide_bottom_bar
qconnect(self.hide_timer.timeout, self.hide_if_allowed)
def on_body_classes_need_update(self) -> None:
super().on_body_classes_need_update()
self.adjustHeightToFit()
self.show()
def _onHeight(self, qvar: Optional[int]) -> None:
self.web_height = int(qvar)
if qvar is None:
self.mw.progress.single_shot(1000, self.mw.reset)
return
if self.mw.pm.reduce_motion():
self.setFixedHeight(int(qvar))
else:
# Collapse/Expand animation
self.setMinimumHeight(0)
self.animation = QPropertyAnimation(
self, cast(QByteArray, b"maximumHeight")
)
self.animation.setDuration(int(theme_manager.var(props.TRANSITION)))
self.animation.setStartValue(self.height())
self.animation.setEndValue(int(qvar))
qconnect(self.animation.finished, lambda: self.setFixedHeight(int(qvar)))
self.animation.start()
def hide(self) -> None:
super().hide()
self._onHeight(1)
def show(self) -> None:
super().show()
self.hidden = False
self.adjustHeightToFit()
class Toolbar: class Toolbar:
def __init__(self, mw: aqt.AnkiQt, web: AnkiWebView) -> None: def __init__(self, mw: aqt.AnkiQt, web: AnkiWebView) -> None:
self.mw = mw self.mw = mw