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
4 changes: 4 additions & 0 deletions pympress/share/defaults.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ show_annotations = off
scroll_number = off
slide_ratio = 0.75
next_slide_count = 1
hide_menu = off
compact_mode = off

[deck-overview]
max-slides-per-row = 6
Expand Down Expand Up @@ -196,6 +198,8 @@ presenter-fullscreen = <ctrl>f
zoom = z
unzoom = u
notes-mode = n
compact-mode = c
hide-menu = <ctrl>m
annotations = a
highlight = h
deck-overview = d
Expand Down
5 changes: 5 additions & 0 deletions pympress/share/locale/de/LC_MESSAGES/pympress.po
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ msgstr "Inhalt _ausrichten"
msgid "_Annotations"
msgstr "_Anmerkungen"

#:
msgid "_Compact mode"
msgstr "_Kompakter Modus"


#:
msgid "_Blank screen"
msgstr "_Schwarzer Bildschirm"
Expand Down
3 changes: 3 additions & 0 deletions pympress/share/locale/pympress.pot
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,9 @@ msgstr ""
msgid "_Annotations"
msgstr ""

msgid "_Compact mode"
msgstr ""

msgid "_Automatic navigation"
msgstr ""

Expand Down
144 changes: 79 additions & 65 deletions pympress/share/xml/menu_bar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,80 @@
<attribute name="label" translatable="yes">Set talk _Time</attribute>
<attribute name="action">app.edit-talk-time</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Notes mode</attribute>
<attribute name="action">app.notes-mode</attribute>
</item>
<submenu>
<attribute name="label" translatable="yes">Notes position</attribute>
<item>
<attribute name="label" translatable="yes">_Right half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">right</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Bottom half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">bottom</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Left half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">left</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Top half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">top</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_After slide pages</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">after</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Every second page</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">odd</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Prefixed labels</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">map</attribute>
</item>
</submenu>

<item>
<attribute name="label" translatable="yes">Timing breakdown</attribute>
<attribute name="action">app.timing-report</attribute>
</item>
</submenu>

<submenu>
<attribute name="label" translatable="yes">_View</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Fullscreen</attribute>
<attribute name="action">app.content-fullscreen</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Swap screens</attribute>
<attribute name="action">app.swap-screens</attribute>
<attribute name="label" translatable="yes">_Highlight</attribute>
<attribute name="action">app.highlight</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Notes mode</attribute>
<attribute name="action">app.notes-mode</attribute>
<attribute name="label" translatable="yes">_Deck overview</attribute>
<attribute name="action">app.deck-overview</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Blank screen</attribute>
<attribute name="action">app.blank-screen</attribute>
<attribute name="label" translatable="yes">_Zoom in</attribute>
<attribute name="action">app.zoom</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Align _content</attribute>
<attribute name="action">app.align-content</attribute>
<attribute name="label" translatable="yes">_Undo zoom</attribute>
<attribute name="action">app.unzoom</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Annotations</attribute>
<attribute name="action">app.annotations</attribute>
Expand All @@ -75,12 +129,24 @@
<attribute name="action">app.big-buttons</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Highlight</attribute>
<attribute name="action">app.highlight</attribute>
<attribute name="label" translatable="yes">_Compact mode</attribute>
<attribute name="action">app.compact-mode</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Deck overview</attribute>
<attribute name="action">app.deck-overview</attribute>
<attribute name="label" translatable="yes">_Hide menu</attribute>
<attribute name="action">app.hide-menu</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Blank screen</attribute>
<attribute name="action">app.blank-screen</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Swap screens</attribute>
<attribute name="action">app.swap-screens</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Align _content</attribute>
<attribute name="action">app.align-content</attribute>
</item>
<submenu>
<attribute name="label" translatable="yes">_Pointer</attribute>
Expand Down Expand Up @@ -150,59 +216,7 @@
</item>
</section>
</submenu>

<item>
<attribute name="label" translatable="yes">_Zoom in</attribute>
<attribute name="action">app.zoom</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Undo zoom</attribute>
<attribute name="action">app.unzoom</attribute>
</item>

<submenu>
<attribute name="label" translatable="yes">Notes position</attribute>
<item>
<attribute name="label" translatable="yes">_Right half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">right</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Bottom half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">bottom</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Left half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">left</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Top half of slide</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">top</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_After slide pages</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">after</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Every second page</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">odd</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Prefixed labels</attribute>
<attribute name="action">app.notes-pos</attribute>
<attribute name="target">map</attribute>
</item>
</submenu>

<item>
<attribute name="label" translatable="yes">Timing breakdown</attribute>
<attribute name="action">app.timing-report</attribute>
</item>
</section>
</submenu>

<submenu>
Expand Down
16 changes: 16 additions & 0 deletions pympress/share/xml/shortcuts.glade
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,22 @@
</object>
</child>

<child>
<object class="GtkShortcutsShortcut" id="shortcut_compact_mode">
<property name="visible">1</property>
<property name="accelerator">c</property>
<property name="title" translatable="yes">Toggle compact mode</property>
</object>
</child>

<child>
<object class="GtkShortcutsShortcut" id="shortcut_hide_menu">
<property name="visible">1</property>
<property name="accelerator">&lt;ctrl&gt;m</property>
<property name="title" translatable="yes">Toggle menu visibility</property>
</object>
</child>

<child>
<object class="GtkShortcutsShortcut" id="shortcut_cancel_input">
<property name="visible">1</property>
Expand Down
98 changes: 97 additions & 1 deletion pympress/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import logging
logger = logging.getLogger(__name__)

import collections
import pathlib
import math
import sys
Expand Down Expand Up @@ -99,6 +100,10 @@ class UI(builder.Builder):
#: Current choice of mode to toggle notes
chosen_notes_mode = document.PdfPage.RIGHT

#: Whether to be in compact mode or not
compact_mode = False
#: Whether to hide or show the menu
hide_menu = False
#: Whether to display annotations or not
show_annotations = True
#: Whether to display big buttons or not
Expand All @@ -124,6 +129,8 @@ class UI(builder.Builder):
placeable_widgets = {}
#: Map of :class:`~Gtk.Paned` to the relative position (`float` between 0 and 1) of its handle
pane_handle_pos = {}
#: Map of :class:`~Gtk.Widget` to the tuple of margins (4 `float`s)
widget_margins = {}

#: :class:`~pympress.config.Config` to remember preferences
config = None
Expand Down Expand Up @@ -204,6 +211,8 @@ def __init__(self, app, config):
self.show_annotations = self.config.getboolean('presenter', 'show_annotations')
self.chosen_notes_mode = document.PdfPage[self.config.get('notes position', 'horizontal').upper()]
self.show_bigbuttons = self.config.getboolean('presenter', 'show_bigbuttons')
self.compact_mode = self.config.getboolean('presenter', 'compact_mode')
self.hide_menu = self.config.getboolean('presenter', 'hide_menu')

# Surface cache
self.cache = surfacecache.SurfaceCache(self.doc, self.config.getint('cache', 'maxpages'))
Expand Down Expand Up @@ -233,6 +242,8 @@ def __init__(self, app, config):
'notes-pos': dict(activate=self.change_notes_pos, parameter_type=str,
state=self.chosen_notes_mode.name.lower()),
'annotations': dict(activate=self.switch_annotations, state=self.show_annotations),
'compact-mode': dict(activate=self.switch_compact_mode, state=self.compact_mode),
'hide-menu': dict(activate=self.switch_menu, state=self.hide_menu),
'validate-input': dict(activate=self.validate_current_input),
'cancel-input': dict(activate=self.cancel_current_input),
'align-content': dict(activate=self.adjust_frame_position),
Expand Down Expand Up @@ -307,6 +318,9 @@ def __init__(self, app, config):
self.laser_button.set_visible(self.show_bigbuttons)
self.highlight_button.set_visible(self.show_bigbuttons)
self.p_frame_annot.set_visible(self.show_annotations)
self.p_win.set_show_menubar(not self.hide_menu)
self.adjust_margins()
self.adjust_bottom_bar_font()
self.laser.activate_pointermode()

# Setup screens and show all windows
Expand Down Expand Up @@ -673,7 +687,7 @@ def adjust_bottom_bar_font(self):
""" Scale baseline font size of bottom bar, clipped to 6px..13px. Fonts are then scaled by CSS em indications.
"""
ww, wh = self.p_win.get_size()
font_size = max(6, min(13, ww / 120 if self.show_bigbuttons else ww / 75))
font_size = max(6, min(9 if self.compact_mode else 13, ww / 120 if self.show_bigbuttons else ww / 75))
self.css_provider.load_from_data('#bottom {{ font-size: {:.1f}px; }}'.format(font_size).encode())


Expand Down Expand Up @@ -1853,6 +1867,88 @@ def switch_mode(self, gaction, target_mode=None, force=False):
return True


def switch_menu(self, gaction, target):
""" Toggle menu bar visibility.

Returns:
gaction (:class:`~Gio.Action`): the action triggering the call
target (:class:`~GLib.Variant`): the parameter as a variant, or None

Returns:
`bool`: whether the mode has been toggled.
"""
self.hide_menu = not self.hide_menu
self.config.set('presenter', 'hide_menu', 'on' if self.hide_menu else 'off')

self.p_win.set_show_menubar(not self.hide_menu)
GLib.idle_add(self.redraw_panes)

gaction.change_state(GLib.Variant.new_boolean(self.hide_menu))

return True


def switch_compact_mode(self, gaction, target):
""" Toggle compact mode.

Returns:
gaction (:class:`~Gio.Action`): the action triggering the call
target (:class:`~GLib.Variant`): the parameter as a variant, or None

Returns:
`bool`: whether the mode has been toggled.
"""
self.compact_mode = not self.compact_mode
self.config.set('presenter', 'compact_mode', 'on' if self.compact_mode else 'off')

self.adjust_margins()
self.adjust_bottom_bar_font()
GLib.idle_add(self.redraw_panes)

gaction.change_state(GLib.Variant.new_boolean(self.compact_mode))

return True


def adjust_margins(self):
""" Adjust all presenter window margins and visibilities according to compact mode. """
for frame_next in self.p_frames_next:
frame_next.get_label_widget().set_visible(not self.compact_mode)

self.p_frame_cur.get_label_widget().set_visible(not self.compact_mode)
self.p_frame_annot.get_label_widget().set_visible(not self.compact_mode)
self.p_frame_notes.get_label_widget().set_visible(not self.compact_mode)

for handle in self.pane_handle_pos:
handle.set_wide_handle(not self.compact_mode)

queue = collections.deque([self.p_central])
while queue:
children = queue.popleft().get_children()
for child in children:
try:
if self.compact_mode:
self.widget_margins[child] = (
child.get_margin_top(),
child.get_margin_bottom(),
child.get_margin_start(),
child.get_margin_end(),
)
top, bot, start, end = 0, 0, 0, 0
else:
top, bot, start, end = self.widget_margins.pop(child)
except KeyError:
pass
else:
child.set_margin_top(top)
child.set_margin_bottom(bot)
child.set_margin_start(start)
child.set_margin_end(end)

if isinstance(child, Gtk.Container):
queue.append(child)


def switch_annotations(self, gaction, target):
""" Switch the display to show annotations or to hide them.

Expand Down