forked from Mirrors/apostrophe
parent
bc23fa9b0b
commit
5e770510ee
|
@ -76,6 +76,13 @@
|
|||
Maximum number of characters per line within the editor.
|
||||
</description>
|
||||
</key>
|
||||
<key name='preview-side-by-side' type='b'>
|
||||
<default>false</default>
|
||||
<summary>Side-by-side preview</summary>
|
||||
<description>
|
||||
Show the preview side by side, instead of full-width.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
</schema>
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.stats-counter {
|
||||
.stats-button {
|
||||
color: alpha(@theme_fg_color, 0.6);
|
||||
background-color: @theme_base_color;
|
||||
text-shadow: inherit;
|
||||
|
@ -116,8 +116,8 @@
|
|||
transition: 100ms ease-in;
|
||||
}
|
||||
|
||||
.stats-counter:hover,
|
||||
.stats-counter:checked {
|
||||
.stats-button :hover,
|
||||
.stats-button :checked {
|
||||
color: @theme_fg_color;
|
||||
background-color: mix(@theme_base_color, @theme_bg_color, 0.5);
|
||||
}
|
||||
|
|
|
@ -8,32 +8,32 @@
|
|||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="amunt">
|
||||
<object class="GtkImage" id="edit-find-replace">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">edit-find-replace-symbolic</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="go-up">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">go-up-symbolic</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="avall">
|
||||
<object class="GtkImage" id="go_down">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">go-down-symbolic</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="ortografia1">
|
||||
<object class="GtkImage" id="pan-down">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">pan-down-symbolic</property>
|
||||
<property name="icon_size">2</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="spell-check">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-spell-check</property>
|
||||
</object>
|
||||
<object class="GtkRecentFilter" id="recentfilter1">
|
||||
<mime-types>
|
||||
<mime-type>text/plain</mime-type>
|
||||
<mime-type>text/x-markdown</mime-type>
|
||||
</mime-types>
|
||||
</object>
|
||||
<object class="GtkImage" id="reemplaza">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">edit-find-replace-symbolic</property>
|
||||
</object>
|
||||
<object class="GtkOverlay" id="FullscreenOverlay">
|
||||
<property name="name">FullscreenOverlay</property>
|
||||
<property name="visible">True</property>
|
||||
|
@ -43,10 +43,10 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkPaned" id="main_pained">
|
||||
<object class="GtkPaned" id="main_paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="app_paintable">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="sidebar_box">
|
||||
<property name="width_request">200</property>
|
||||
|
@ -70,45 +70,17 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid2">
|
||||
<object class="GtkBox" id="content">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="stats_counter_revealer">
|
||||
<object class="GtkBox" id="editor">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">crossfade</property>
|
||||
<property name="transition_duration">750</property>
|
||||
<property name="reveal_child">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="stats_counter">
|
||||
<property name="label" translatable="yes">0 Words</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Show Statistics</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkViewport" id="editor_viewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="hscroll_policy">natural</property>
|
||||
<property name="vscroll_policy">natural</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="editor_scrolledwindow">
|
||||
<property name="height_request">500</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
@ -119,16 +91,52 @@
|
|||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="editor_stats_revealer">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">crossfade</property>
|
||||
<property name="transition_duration">750</property>
|
||||
<property name="reveal_child">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="editor_stats_button">
|
||||
<property name="label" translatable="yes">0 Words</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Show Statistics</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="image">pan-down</property>
|
||||
<property name="image_position">right</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -191,7 +199,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Previous Match</property>
|
||||
<property name="image">amunt</property>
|
||||
<property name="image">go-up</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -205,7 +213,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Next Match</property>
|
||||
<property name="image">avall</property>
|
||||
<property name="image">go_down</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -264,7 +272,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Open Replace</property>
|
||||
<property name="image">reemplaza</property>
|
||||
<property name="image">edit-find-replace</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -345,7 +353,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">ortografia1</property>
|
||||
<property name="image">spell-check</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
|
@ -12,6 +12,7 @@ gi.require_version('Gspell', '1')
|
|||
from gi.repository import Gtk, Gdk, GObject, GLib, Gspell
|
||||
|
||||
import logging
|
||||
|
||||
LOGGER = logging.getLogger('uberwriter')
|
||||
|
||||
|
||||
|
@ -53,8 +54,8 @@ class TextView(Gtk.TextView):
|
|||
|
||||
# Text sizing
|
||||
self.props.halign = Gtk.Align.FILL
|
||||
self.font_size = 16
|
||||
self.line_chars = line_chars
|
||||
self.font_size = 16
|
||||
self.get_style_context().add_class('size16')
|
||||
|
||||
# General behavior
|
||||
|
@ -133,10 +134,8 @@ class TextView(Gtk.TextView):
|
|||
def on_parent_set(self, *_):
|
||||
parent = self.get_parent()
|
||||
if parent:
|
||||
parent.set_size_request(self.get_min_width(), 500)
|
||||
self.scroller = TextViewScroller(self, parent)
|
||||
# Request a size that fits the minimum font size comfortably.
|
||||
parent.set_size_request(
|
||||
self.pad_chars(self.font_sizes[-1]) * self.font_width(self.font_sizes[-1]), 500)
|
||||
else:
|
||||
self.scroller = None
|
||||
|
||||
|
@ -169,18 +168,17 @@ class TextView(Gtk.TextView):
|
|||
width = self.get_allocation().width
|
||||
|
||||
# Ensure the appropriate font size is being used
|
||||
for size in self.font_sizes:
|
||||
min_width = (self.line_chars + self.pad_chars(size) + 1) * self.font_width(size) - 1
|
||||
if width >= min_width:
|
||||
if size != self.font_size:
|
||||
self.font_size = size
|
||||
for s in self.font_sizes:
|
||||
self.get_style_context().remove_class("size{}".format(s))
|
||||
self.get_style_context().add_class("size{}".format(size))
|
||||
for font_size in self.font_sizes:
|
||||
if width >= self.get_min_width(font_size) or font_size == self.font_sizes[-1]:
|
||||
if font_size != self.font_size:
|
||||
self.font_size = font_size
|
||||
for fs in self.font_sizes:
|
||||
self.get_style_context().remove_class("size{}".format(fs))
|
||||
self.get_style_context().add_class("size{}".format(font_size))
|
||||
break
|
||||
|
||||
# Apply margin with the remaining space to allow for markup
|
||||
line_width = (self.line_chars + 1) * int(self.font_width(self.font_size)) - 1
|
||||
line_width = (self.line_chars + 1) * int(self.get_char_width(self.font_size)) - 1
|
||||
horizontal_margin = (width - line_width) / 2
|
||||
self.props.left_margin = horizontal_margin
|
||||
self.props.right_margin = horizontal_margin
|
||||
|
@ -224,15 +222,23 @@ class TextView(Gtk.TextView):
|
|||
mark = self.get_buffer().get_insert()
|
||||
GLib.idle_add(self.scroller.smooth_scroll_to_mark, mark, self.focus_mode)
|
||||
|
||||
def pad_chars(self, font_size):
|
||||
def get_min_width(self, font_size=None):
|
||||
"""Returns the minimum width of this text view."""
|
||||
|
||||
if font_size is None:
|
||||
font_size = self.font_sizes[-1]
|
||||
return (self.line_chars + self.get_pad_chars(font_size) + 1) \
|
||||
* self.get_char_width(font_size) - 1
|
||||
|
||||
def get_pad_chars(self, font_size):
|
||||
"""Returns the amount of character padding for font_size.
|
||||
|
||||
Markup can use up to 6 in normal conditions."""
|
||||
Markup can use up to 7 in normal conditions."""
|
||||
|
||||
return 8 * (1 + font_size - self.font_sizes[-1])
|
||||
|
||||
@staticmethod
|
||||
def font_width(font_size):
|
||||
"""Returns the font width for a given size. Specific to Fira Mono."""
|
||||
def get_char_width(font_size):
|
||||
"""Returns the font width for a given size. Note: specific to Fira Mono!"""
|
||||
|
||||
return font_size * 1 / 1.6
|
||||
|
|
|
@ -101,29 +101,29 @@ class Window(Gtk.ApplicationWindow):
|
|||
self.accel_group = Gtk.AccelGroup()
|
||||
self.add_accel_group(self.accel_group)
|
||||
|
||||
self.content = self.builder.get_object('content')
|
||||
|
||||
self.scrolled_window = self.builder.get_object('editor_scrolledwindow')
|
||||
self.scrolled_window.get_style_context().add_class('uberwriter-scrolled-window')
|
||||
|
||||
# Setup text editor
|
||||
self.text_view = TextView()
|
||||
self.text_view.props.halign = Gtk.Align.CENTER
|
||||
self.text_view = TextView(self.settings.get_int("characters-per-line"))
|
||||
self.text_view.connect('focus-out-event', self.focus_out)
|
||||
self.text_view.get_buffer().connect('changed', self.on_text_changed)
|
||||
self.text_view.show()
|
||||
self.text_view.grab_focus()
|
||||
self.scrolled_window.add(self.text_view)
|
||||
|
||||
# Stats stats counter
|
||||
self.stats_revealer = self.builder.get_object('editor_stats_revealer')
|
||||
self.stats_button = self.builder.get_object('editor_stats_button')
|
||||
self.stats_button.get_style_context().add_class('stats-button')
|
||||
self.stats_handler = StatsHandler(self.stats_button, self.text_view)
|
||||
|
||||
# Setup preview webview
|
||||
self.web_view = None
|
||||
self.web_view_scroller = None
|
||||
|
||||
self.scrolled_window = self.builder.get_object('editor_scrolledwindow')
|
||||
self.scrolled_window.get_style_context().add_class('uberwriter-scrolled-window')
|
||||
self.scrolled_window.add(self.text_view)
|
||||
self.editor_viewport = self.builder.get_object('editor_viewport')
|
||||
|
||||
# Stats counter
|
||||
self.stats_counter_revealer = self.builder.get_object('stats_counter_revealer')
|
||||
self.stats_button = self.builder.get_object('stats_counter')
|
||||
self.stats_button.get_style_context().add_class('stats-counter')
|
||||
self.stats_handler = StatsHandler(self.stats_button, self.text_view)
|
||||
|
||||
# Setup header/stats bar hide after 3 seconds
|
||||
self.top_bottom_bars_visible = True
|
||||
self.was_motion = True
|
||||
|
@ -145,7 +145,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
###
|
||||
# Sidebar initialization test
|
||||
###
|
||||
self.paned_window = self.builder.get_object("main_pained")
|
||||
self.paned_window = self.builder.get_object("main_paned")
|
||||
self.sidebar_box = self.builder.get_object("sidebar_box")
|
||||
self.sidebar = Sidebar(self)
|
||||
self.sidebar_box.hide()
|
||||
|
@ -466,10 +466,14 @@ class Window(Gtk.ApplicationWindow):
|
|||
return True
|
||||
|
||||
def show_text_editor(self):
|
||||
# Swap web view with text view
|
||||
self.scrolled_window.remove(self.scrolled_window.get_child())
|
||||
self.scrolled_window.add(self.text_view)
|
||||
self.text_view.show()
|
||||
# Remove web view
|
||||
if self.settings.get_boolean("preview-side-by-side"):
|
||||
self.set_size_request(-1, -1)
|
||||
self.content.remove(self.web_view)
|
||||
else:
|
||||
self.scrolled_window.remove(self.scrolled_window.get_child())
|
||||
self.scrolled_window.add(self.text_view)
|
||||
self.text_view.show()
|
||||
self.queue_draw()
|
||||
|
||||
# Sync scroll between web view and text view
|
||||
|
@ -485,9 +489,13 @@ class Window(Gtk.ApplicationWindow):
|
|||
# Sync scroll between text view and web view
|
||||
self.web_view_scroller.set_scroll_scale(self.text_view.get_scroll_scale())
|
||||
|
||||
# Swap text view with web view
|
||||
self.scrolled_window.remove(self.scrolled_window.get_child())
|
||||
self.scrolled_window.add(self.web_view)
|
||||
# Show web view
|
||||
if self.settings.get_boolean("preview-side-by-side"):
|
||||
self.content.add(self.web_view)
|
||||
self.set_size_request(self.text_view.get_min_width() * 2, -1)
|
||||
else:
|
||||
self.scrolled_window.remove(self.scrolled_window.get_child())
|
||||
self.scrolled_window.add(self.web_view)
|
||||
self.web_view.show()
|
||||
self.queue_draw()
|
||||
else:
|
||||
|
@ -590,7 +598,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
and self.buffer_modified_for_status_bar
|
||||
and self.text_view.props.has_focus): # pylint: disable=no-member
|
||||
# self.status_bar.set_state_flags(Gtk.StateFlags.INSENSITIVE, True)
|
||||
self.stats_counter_revealer.set_reveal_child(False)
|
||||
self.stats_revealer.set_reveal_child(False)
|
||||
self.headerbar.hb_revealer.set_reveal_child(False)
|
||||
self.top_bottom_bars_visible = False
|
||||
self.buffer_modified_for_status_bar = False
|
||||
|
@ -612,7 +620,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
if now - self.timestamp_last_mouse_motion > 100:
|
||||
# react on motion by fading in headerbar and statusbar
|
||||
if self.top_bottom_bars_visible is False:
|
||||
self.stats_counter_revealer.set_reveal_child(True)
|
||||
self.stats_revealer.set_reveal_child(True)
|
||||
self.headerbar.hb_revealer.set_reveal_child(True)
|
||||
self.headerbar.hb.props.opacity = 1
|
||||
self.top_bottom_bars_visible = True
|
||||
|
@ -624,7 +632,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
"""events called when the window losses focus
|
||||
"""
|
||||
if self.top_bottom_bars_visible is False:
|
||||
self.stats_counter_revealer.set_reveal_child(True)
|
||||
self.stats_revealer.set_reveal_child(True)
|
||||
self.headerbar.hb_revealer.set_reveal_child(True)
|
||||
self.headerbar.hb.props.opacity = 1
|
||||
self.top_bottom_bars_visible = True
|
||||
|
|
Loading…
Reference in New Issue