forked from Mirrors/apostrophe
rework the autohiding mechanis for headerbars
parent
151809ae9b
commit
97e809a576
|
@ -6,7 +6,6 @@
|
||||||
<object class="GtkImage" id="edit-find-replace">
|
<object class="GtkImage" id="edit-find-replace">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="xpad">12</property>
|
|
||||||
<property name="icon_name">edit-find-replace-symbolic</property>
|
<property name="icon_name">edit-find-replace-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="go-up">
|
<object class="GtkImage" id="go-up">
|
||||||
|
@ -30,12 +29,12 @@
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-spell-check</property>
|
<property name="stock">gtk-spell-check</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkOverlay" id="FullscreenOverlay">
|
<object class="GtkOverlay" id="AppOverlay">
|
||||||
<property name="name">FullscreenOverlay</property>
|
<property name="name">FullscreenOverlay</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkGrid" id="grid1">
|
<object class="GtkGrid" id="app_grid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
|
@ -71,10 +70,9 @@
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="homogeneous">True</property>
|
<property name="homogeneous">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="editor">
|
<object class="GtkOverlay" id="editor">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="editor_scrolledwindow">
|
<object class="GtkScrolledWindow" id="editor_scrolledwindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -87,15 +85,15 @@
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="index">-1</property>
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child type="overlay">
|
||||||
<object class="GtkRevealer" id="editor_stats_revealer">
|
<object class="GtkRevealer" id="editor_stats_revealer">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="events">GDK_ENTER_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
<property name="transition_type">crossfade</property>
|
<property name="transition_type">crossfade</property>
|
||||||
<property name="transition_duration">750</property>
|
<property name="transition_duration">750</property>
|
||||||
<property name="reveal_child">True</property>
|
<property name="reveal_child">True</property>
|
||||||
|
@ -116,11 +114,6 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
|
@ -236,6 +229,7 @@
|
||||||
<object class="GtkBox" id="searchtools_box">
|
<object class="GtkBox" id="searchtools_box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkToggleButton" id="case_sensitive">
|
<object class="GtkToggleButton" id="case_sensitive">
|
||||||
<property name="label" translatable="yes">aA</property>
|
<property name="label" translatable="yes">aA</property>
|
||||||
|
@ -416,10 +410,28 @@
|
||||||
<property name="height_request">1</property>
|
<property name="height_request">1</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="valign">start</property>
|
<property name="valign">start</property>
|
||||||
|
<property name="visible_window">False</property>
|
||||||
|
<property name="above_child">True</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child type="overlay">
|
||||||
|
<object class="GtkEventBox" id="HeaderbarEventbox">
|
||||||
|
<property name="height_request">60</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="visible_window">False</property>
|
||||||
|
<property name="above_child">True</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="index">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
|
@ -74,7 +74,7 @@ class MainWindow(StyledWindow):
|
||||||
builder = Gtk.Builder()
|
builder = Gtk.Builder()
|
||||||
builder.add_from_resource(
|
builder.add_from_resource(
|
||||||
"/de/wolfvollprecht/UberWriter/ui/Window.ui")
|
"/de/wolfvollprecht/UberWriter/ui/Window.ui")
|
||||||
root = builder.get_object("FullscreenOverlay")
|
root = builder.get_object("AppOverlay")
|
||||||
self.connect("delete-event", self.on_delete_called)
|
self.connect("delete-event", self.on_delete_called)
|
||||||
self.add(root)
|
self.add(root)
|
||||||
|
|
||||||
|
@ -102,11 +102,6 @@ class MainWindow(StyledWindow):
|
||||||
self.title_end = " – UberWriter"
|
self.title_end = " – UberWriter"
|
||||||
self.set_headerbar_title("New File" + self.title_end)
|
self.set_headerbar_title("New File" + self.title_end)
|
||||||
|
|
||||||
self.timestamp_last_mouse_motion = 0
|
|
||||||
if self.settings.get_value("poll-motion"):
|
|
||||||
self.connect("motion-notify-event", self.on_motion_notify)
|
|
||||||
GObject.timeout_add(3000, self.poll_for_motion)
|
|
||||||
|
|
||||||
self.accel_group = Gtk.AccelGroup()
|
self.accel_group = Gtk.AccelGroup()
|
||||||
self.add_accel_group(self.accel_group)
|
self.add_accel_group(self.accel_group)
|
||||||
|
|
||||||
|
@ -131,9 +126,10 @@ class MainWindow(StyledWindow):
|
||||||
editor = builder.get_object('editor')
|
editor = builder.get_object('editor')
|
||||||
self.preview_handler = PreviewHandler(self, content, editor, self.text_view)
|
self.preview_handler = PreviewHandler(self, content, editor, self.text_view)
|
||||||
|
|
||||||
# Setup header/stats bar hide after 3 seconds
|
# Setup header/stats bar
|
||||||
self.top_bottom_bars_visible = True
|
self.headerbar_visible = True
|
||||||
self.was_motion = True
|
self.bottombar_visible = True
|
||||||
|
self.previewbars_visible = True
|
||||||
self.buffer_modified_for_status_bar = False
|
self.buffer_modified_for_status_bar = False
|
||||||
|
|
||||||
# some people seems to have performance problems with the overlay.
|
# some people seems to have performance problems with the overlay.
|
||||||
|
@ -163,6 +159,14 @@ class MainWindow(StyledWindow):
|
||||||
###
|
###
|
||||||
self.searchreplace = SearchAndReplace(self, self.text_view, builder)
|
self.searchreplace = SearchAndReplace(self, self.text_view, builder)
|
||||||
|
|
||||||
|
# EventBoxes
|
||||||
|
|
||||||
|
self.headerbar_eventbox = builder.get_object("HeaderbarEventbox")
|
||||||
|
self.headerbar_eventbox.connect('enter_notify_event',
|
||||||
|
self.reveal_headerbar_bottombar)
|
||||||
|
|
||||||
|
self.stats_revealer.connect('enter_notify_event', self.reveal_bottombar)
|
||||||
|
|
||||||
def header_size_allocate(self, widget, allocation):
|
def header_size_allocate(self, widget, allocation):
|
||||||
""" When the main hb starts to shrink its size, add that size
|
""" When the main hb starts to shrink its size, add that size
|
||||||
to the textview margin, so it stays in place
|
to the textview margin, so it stays in place
|
||||||
|
@ -192,6 +196,8 @@ class MainWindow(StyledWindow):
|
||||||
self.set_headerbar_title("* " + title)
|
self.set_headerbar_title("* " + title)
|
||||||
|
|
||||||
self.buffer_modified_for_status_bar = True
|
self.buffer_modified_for_status_bar = True
|
||||||
|
if self.settings.get_value("autohide-headerbar"):
|
||||||
|
self.hide_headerbar_bottombar()
|
||||||
|
|
||||||
def set_fullscreen(self, state):
|
def set_fullscreen(self, state):
|
||||||
"""Puts the application in fullscreen mode and show/hides
|
"""Puts the application in fullscreen mode and show/hides
|
||||||
|
@ -555,72 +561,62 @@ class MainWindow(StyledWindow):
|
||||||
return
|
return
|
||||||
self.load_file(data)
|
self.load_file(data)
|
||||||
|
|
||||||
def poll_for_motion(self):
|
|
||||||
"""check if the user has moved the cursor to show the headerbar
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True -- Gtk things
|
|
||||||
"""
|
|
||||||
|
|
||||||
if (not self.was_motion
|
|
||||||
and self.buffer_modified_for_status_bar
|
|
||||||
and self.text_view.props.has_focus):
|
|
||||||
self.reveal_top_bottom_bars(False)
|
|
||||||
|
|
||||||
self.was_motion = False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def on_motion_notify(self, _widget, event, _data=None):
|
|
||||||
"""check the motion of the mouse to fade in the headerbar
|
|
||||||
"""
|
|
||||||
now = event.get_time()
|
|
||||||
if now - self.timestamp_last_mouse_motion > 150:
|
|
||||||
# filter out accidental motions
|
|
||||||
self.timestamp_last_mouse_motion = now
|
|
||||||
return
|
|
||||||
if now - self.timestamp_last_mouse_motion < 100:
|
|
||||||
# filter out accidental motion
|
|
||||||
return
|
|
||||||
if now - self.timestamp_last_mouse_motion > 100:
|
|
||||||
# react on motion by fading in headerbar and statusbar
|
|
||||||
self.reveal_top_bottom_bars(True)
|
|
||||||
self.was_motion = True
|
|
||||||
|
|
||||||
def focus_out(self, _widget, _data=None):
|
def focus_out(self, _widget, _data=None):
|
||||||
"""events called when the window losses focus
|
"""events called when the window losses focus
|
||||||
"""
|
"""
|
||||||
self.reveal_top_bottom_bars(True)
|
self.reveal_headerbar_bottombar()
|
||||||
|
|
||||||
def reveal_top_bottom_bars(self, reveal):
|
def reveal_headerbar_bottombar(self, _widget=None, _data=None):
|
||||||
"""handles (in conjunction with header_size_allocate)
|
|
||||||
the fading in and out of the headerbar
|
|
||||||
"""
|
|
||||||
# The logic may seem confusing because similar things are
|
|
||||||
# handled in headerbars.py, but for convenience (adding classes
|
|
||||||
# to the main window, and delayed calls) some functions are split
|
|
||||||
# between here and there
|
|
||||||
|
|
||||||
# TODO: rework this logic?
|
def __reveal_hb():
|
||||||
|
|
||||||
def reveal_hb():
|
|
||||||
self.headerbar.hb_revealer.set_reveal_child(True)
|
self.headerbar.hb_revealer.set_reveal_child(True)
|
||||||
self.get_style_context().remove_class("focus")
|
self.get_style_context().remove_class("focus")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.top_bottom_bars_visible != reveal:
|
self.reveal_bottombar()
|
||||||
if reveal:
|
|
||||||
self.dm_headerbar.hide_dm_hb()
|
if not self.headerbar_visible:
|
||||||
GLib.timeout_add(400, reveal_hb)
|
self.dm_headerbar.hide_dm_hb()
|
||||||
else:
|
GLib.timeout_add(400, __reveal_hb)
|
||||||
self.headerbar.hb_revealer.set_reveal_child(False)
|
|
||||||
self.dm_headerbar.show_dm_hb()
|
self.headerbar_visible = True
|
||||||
self.get_style_context().add_class("focus")
|
|
||||||
|
if not self.previewbars_visible:
|
||||||
self.stats_revealer.set_reveal_child(reveal)
|
|
||||||
for revealer in self.preview_handler.get_top_bottom_bar_revealers():
|
for revealer in self.preview_handler.get_top_bottom_bar_revealers():
|
||||||
revealer.set_reveal_child(reveal)
|
revealer.set_reveal_child(True)
|
||||||
self.top_bottom_bars_visible = reveal
|
|
||||||
self.buffer_modified_for_status_bar = reveal
|
self.previewbars_visible = True
|
||||||
|
|
||||||
|
def reveal_bottombar(self, _widget=None, _data=None):
|
||||||
|
|
||||||
|
if not self.bottombar_visible:
|
||||||
|
self.stats_revealer.set_reveal_child(True)
|
||||||
|
|
||||||
|
self.bottombar_visible = True
|
||||||
|
|
||||||
|
self.buffer_modified_for_status_bar = True
|
||||||
|
|
||||||
|
def hide_headerbar_bottombar(self):
|
||||||
|
|
||||||
|
if self.headerbar_visible:
|
||||||
|
self.headerbar.hb_revealer.set_reveal_child(False)
|
||||||
|
self.dm_headerbar.show_dm_hb()
|
||||||
|
self.get_style_context().add_class("focus")
|
||||||
|
|
||||||
|
self.headerbar_visible = False
|
||||||
|
|
||||||
|
if self.bottombar_visible:
|
||||||
|
self.stats_revealer.set_reveal_child(False)
|
||||||
|
|
||||||
|
self.bottombar_visible = False
|
||||||
|
|
||||||
|
if self.previewbars_visible:
|
||||||
|
for revealer in self.preview_handler.get_top_bottom_bar_revealers():
|
||||||
|
revealer.set_reveal_child(False)
|
||||||
|
|
||||||
|
self.previewbars_visible = False
|
||||||
|
|
||||||
|
self.buffer_modified_for_status_bar = False
|
||||||
|
|
||||||
def draw_gradient(self, _widget, cr):
|
def draw_gradient(self, _widget, cr):
|
||||||
"""draw fading gradient over the top and the bottom of the
|
"""draw fading gradient over the top and the bottom of the
|
||||||
|
@ -668,13 +664,16 @@ class MainWindow(StyledWindow):
|
||||||
self.destroy()
|
self.destroy()
|
||||||
return
|
return
|
||||||
|
|
||||||
def set_headerbar_title(self, title, subtitle=""):
|
def set_headerbar_title(self, title, subtitle=None):
|
||||||
"""set the desired headerbar title
|
"""set the desired headerbar title
|
||||||
"""
|
"""
|
||||||
self.headerbar.hb.props.title = title
|
self.headerbar.hb.props.title = title
|
||||||
|
self.dm_headerbar.hb.props.title = title
|
||||||
self.fs_headerbar.hb.props.title = title
|
self.fs_headerbar.hb.props.title = title
|
||||||
self.headerbar.hb.props.subtitle = subtitle
|
if subtitle:
|
||||||
self.fs_headerbar.hb.props.subtitle = subtitle
|
self.headerbar.hb.props.subtitle = subtitle
|
||||||
|
self.dm_headerbar.hb.props.subtitle = subtitle
|
||||||
|
self.fs_headerbar.hb.props.subtitle = subtitle
|
||||||
self.set_title(title)
|
self.set_title(title)
|
||||||
|
|
||||||
def set_filename(self, filename=None):
|
def set_filename(self, filename=None):
|
||||||
|
|
Loading…
Reference in New Issue