generated from itdominator/Python-With-Gtk-Template
Refactoring notebook and sourceview; embedding keybindings for time being
This commit is contained in:
parent
d09a6e063e
commit
3b2fab0f4c
|
@ -3,10 +3,12 @@
|
|||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
from .key_input_controller import KeyInputController
|
||||
from .editor_events import EditorEventsMixin
|
||||
|
||||
|
||||
|
||||
class EditorControllerMixin:
|
||||
class EditorControllerMixin(KeyInputController, EditorEventsMixin):
|
||||
def get_active_view(self):
|
||||
page_num = self.get_current_page()
|
||||
container = self.get_nth_page( page_num )
|
||||
|
@ -19,47 +21,13 @@ class EditorControllerMixin:
|
|||
return
|
||||
|
||||
page_num, container, source_view = self.get_active_view()
|
||||
if action == "close_tab":
|
||||
self.close_tab(None, container, source_view)
|
||||
if action == "keyboard_prev_tab":
|
||||
self.keyboard_prev_tab(page_num)
|
||||
if action == "keyboard_next_tab":
|
||||
self.keyboard_next_tab(page_num)
|
||||
if action == "keyboard_move_tab_left":
|
||||
self.keyboard_move_tab_left(page_num)
|
||||
if action == "keyboard_move_tab_right":
|
||||
self.keyboard_move_tab_right(page_num)
|
||||
if action == "keyboard_move_tab_to_1":
|
||||
self.keyboard_move_tab_to_1(page_num)
|
||||
if action == "keyboard_move_tab_to_2":
|
||||
self.keyboard_move_tab_to_2(page_num)
|
||||
|
||||
|
||||
# NOTE: These feel bad being here man...
|
||||
if action == "scale_up_text":
|
||||
self.scale_up_text(source_view)
|
||||
if action == "keyboard_undo":
|
||||
self.keyboard_undo(source_view)
|
||||
if action == "keyboard_redo":
|
||||
self.keyboard_redo(source_view)
|
||||
if action == "scale_down_text":
|
||||
self.scale_down_text(source_view)
|
||||
if action == "toggle_highlight_line":
|
||||
self.toggle_highlight_line(source_view)
|
||||
if action == "keyboard_insert_mark":
|
||||
self.keyboard_insert_mark(source_view)
|
||||
if action == "keyboard_clear_marks":
|
||||
self.keyboard_clear_marks(source_view)
|
||||
if action == "keyboard_move_lines_up":
|
||||
self.keyboard_move_lines_up(source_view)
|
||||
if action == "keyboard_move_lines_down":
|
||||
self.keyboard_move_lines_down(source_view)
|
||||
if action == "set_buffer_language":
|
||||
self.set_buffer_language(source_view, query)
|
||||
if action == "set_buffer_style":
|
||||
self.set_buffer_style(source_view, query)
|
||||
if action == "save_file":
|
||||
return source_view.save_file()
|
||||
if action == "save_file_as":
|
||||
return source_view.save_file_as()
|
||||
|
||||
self.set_buffer_style(source_view, query)
|
|
@ -101,36 +101,17 @@ class EditorEventsMixin:
|
|||
|
||||
|
||||
# NOTE: These feel bad being here man...
|
||||
def keyboard_undo(self, source_view):
|
||||
source_view.keyboard_undo()
|
||||
|
||||
def keyboard_redo(self, source_view):
|
||||
source_view.keyboard_redo()
|
||||
|
||||
def scale_up_text(self, source_view):
|
||||
source_view.scale_up_text()
|
||||
|
||||
def scale_down_text(self, source_view):
|
||||
source_view.scale_down_text()
|
||||
|
||||
def toggle_highlight_line(self, source_view):
|
||||
source_view.toggle_highlight_line()
|
||||
|
||||
def keyboard_insert_mark(self, source_view):
|
||||
source_view.keyboard_insert_mark()
|
||||
|
||||
def keyboard_clear_marks(self, source_view):
|
||||
source_view.keyboard_clear_marks()
|
||||
|
||||
def keyboard_move_lines_up(self, source_view):
|
||||
source_view.keyboard_move_lines_up()
|
||||
|
||||
def keyboard_move_lines_down(self, source_view):
|
||||
source_view.keyboard_move_lines_down()
|
||||
|
||||
def set_buffer_language(self, source_view, language = "python3"):
|
||||
source_view.set_buffer_language(language)
|
||||
|
||||
def set_buffer_style(self, source_view, style = settings.theming.syntax_theme):
|
||||
buffer = source_view.get_buffer()
|
||||
source_view.set_buffer_style(buffer, style)
|
||||
source_view.set_buffer_style(buffer, style)
|
||||
|
||||
|
||||
|
|
|
@ -10,13 +10,11 @@ from gi.repository import Gio
|
|||
|
||||
# Application imports
|
||||
from .editor_controller import EditorControllerMixin
|
||||
from .editor_events import EditorEventsMixin
|
||||
|
||||
|
||||
|
||||
# NOTE: https://github.com/Axel-Erfurt/TextEdit/tree/b65f09be945196eb05bef83d81a6abcd129b4eb0
|
||||
|
||||
class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook):
|
||||
class EditorNotebook(EditorControllerMixin, Gtk.Notebook):
|
||||
ccount = 0
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
|
@ -35,7 +33,6 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook):
|
|||
self.set_group_name("editor_widget")
|
||||
self.builder.expose_object(self.NAME, self)
|
||||
|
||||
self._add_action_widgets()
|
||||
self._setup_styling()
|
||||
self._setup_signals()
|
||||
self._subscribe_to_events()
|
||||
|
@ -57,35 +54,30 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook):
|
|||
|
||||
def _setup_signals(self):
|
||||
self.connect("switch-page", self._switch_page_update)
|
||||
self.connect("key-press-event", self._key_press_event)
|
||||
self.connect("key-release-event", self._key_release_event)
|
||||
|
||||
def _subscribe_to_events(self):
|
||||
event_system.subscribe("create_view", self._create_view)
|
||||
event_system.subscribe("set_buffer_style", self.action_controller)
|
||||
event_system.subscribe("set_buffer_language", self.action_controller)
|
||||
|
||||
event_system.subscribe("focused_target_changed", self._focused_target_changed)
|
||||
event_system.subscribe("keyboard_create_tab", self._keyboard_create_tab)
|
||||
event_system.subscribe("keyboard_open_file", self._keyboard_open_file)
|
||||
event_system.subscribe("keyboard_close_tab", self._keyboard_close_tab)
|
||||
event_system.subscribe("keyboard_prev_tab", self._keyboard_prev_tab)
|
||||
event_system.subscribe("keyboard_next_tab", self._keyboard_next_tab)
|
||||
event_system.subscribe("keyboard_move_tab_left", self._keyboard_move_tab_left)
|
||||
event_system.subscribe("keyboard_move_tab_right", self._keyboard_move_tab_right)
|
||||
event_system.subscribe("keyboard_move_tab_to_1", self._keyboard_move_tab_to_1)
|
||||
event_system.subscribe("keyboard_move_tab_to_2", self._keyboard_move_tab_to_2)
|
||||
|
||||
event_system.subscribe("toggle_highlight_line", self._toggle_highlight_line)
|
||||
event_system.subscribe("keyboard_move_lines_up", self._keyboard_move_lines_up)
|
||||
event_system.subscribe("keyboard_move_lines_down", self._keyboard_move_lines_down)
|
||||
event_system.subscribe("keyboard_undo", self._keyboard_undo)
|
||||
event_system.subscribe("keyboard_redo", self._keyboard_redo)
|
||||
event_system.subscribe("keyboard_insert_mark", self._keyboard_insert_mark)
|
||||
event_system.subscribe("keyboard_clear_marks", self._keyboard_clear_marks)
|
||||
event_system.subscribe("keyboard_open_file", self._keyboard_open_file)
|
||||
event_system.subscribe("keyboard_scale_up_text", self._keyboard_scale_up_text)
|
||||
event_system.subscribe("keyboard_scale_down_text", self._keyboard_scale_down_text)
|
||||
event_system.subscribe("keyboard_save_file", self._keyboard_save_file)
|
||||
event_system.subscribe("keyboard_save_file_as", self._keyboard_save_file_as)
|
||||
|
||||
# event_system.subscribe("keyboard_save_file_as", self._keyboard_save_file_as)
|
||||
|
||||
|
||||
def _load_widgets(self):
|
||||
self._add_action_widgets()
|
||||
if self.NAME == "notebook_1" and not settings_manager.is_starting_with_file():
|
||||
self.create_view()
|
||||
|
||||
def _dbl_click_create_view(self, notebook, eve):
|
||||
if eve.type == Gdk.EventType.DOUBLE_BUTTON_PRESS and eve.button == 1: # l-click
|
||||
...
|
||||
|
||||
def _focused_target_changed(self, target):
|
||||
self.is_editor_focused = True if target == self.NAME else False
|
||||
|
@ -108,14 +100,6 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook):
|
|||
self.set_action_widget(start_box, 0)
|
||||
self.set_action_widget(end_box, 1)
|
||||
|
||||
def _load_widgets(self):
|
||||
if self.NAME == "notebook_1" and not settings_manager.is_starting_with_file():
|
||||
self.create_view()
|
||||
|
||||
def _dbl_click_create_view(self, notebook, eve):
|
||||
if eve.type == Gdk.EventType.DOUBLE_BUTTON_PRESS and eve.button == 1: # l-click
|
||||
...
|
||||
|
||||
def _switch_page_update(self, notebook, page, page_num):
|
||||
source_view = page.get_source_view()
|
||||
gfile = source_view.get_current_file()
|
||||
|
@ -150,66 +134,8 @@ class EditorNotebook(EditorEventsMixin, EditorControllerMixin, Gtk.Notebook):
|
|||
|
||||
self.open_file(gfile)
|
||||
|
||||
def _keyboard_create_tab(self, _gfile = None):
|
||||
if not self.is_editor_focused: # TODO: Find way to converge this
|
||||
return
|
||||
|
||||
self.create_view(gfile = _gfile)
|
||||
|
||||
|
||||
def _keyboard_close_tab(self):
|
||||
self.action_controller("close_tab")
|
||||
|
||||
def _keyboard_move_tab_right(self):
|
||||
self.action_controller("keyboard_move_tab_right")
|
||||
|
||||
def _keyboard_move_tab_left(self):
|
||||
self.action_controller("keyboard_move_tab_left")
|
||||
|
||||
def _keyboard_move_tab_to_1(self):
|
||||
self.action_controller("keyboard_move_tab_to_1")
|
||||
|
||||
def _keyboard_move_tab_to_2(self):
|
||||
self.action_controller("keyboard_move_tab_to_2")
|
||||
|
||||
def _keyboard_prev_tab(self):
|
||||
self.action_controller("keyboard_prev_tab")
|
||||
|
||||
def _keyboard_next_tab(self):
|
||||
self.action_controller("keyboard_next_tab")
|
||||
|
||||
|
||||
# NOTE: These feel bad being here man...
|
||||
def _keyboard_undo(self):
|
||||
self.action_controller("keyboard_undo")
|
||||
|
||||
def _keyboard_redo(self):
|
||||
self.action_controller("keyboard_redo")
|
||||
|
||||
def _toggle_highlight_line(self):
|
||||
self.action_controller("toggle_highlight_line")
|
||||
|
||||
|
||||
def _keyboard_insert_mark(self):
|
||||
self.action_controller("keyboard_insert_mark")
|
||||
|
||||
def _keyboard_move_lines_up(self):
|
||||
self.action_controller("keyboard_move_lines_up")
|
||||
|
||||
def _keyboard_move_lines_down(self):
|
||||
self.action_controller("keyboard_move_lines_down")
|
||||
|
||||
def _keyboard_clear_marks(self):
|
||||
self.action_controller("keyboard_clear_marks")
|
||||
|
||||
def _keyboard_scale_up_text(self):
|
||||
self.action_controller("scale_up_text")
|
||||
|
||||
def _keyboard_scale_down_text(self):
|
||||
self.action_controller("scale_down_text")
|
||||
|
||||
def _keyboard_save_file(self):
|
||||
self.action_controller("save_file")
|
||||
|
||||
def _keyboard_save_file_as(self):
|
||||
self.action_controller("save_file_as")
|
||||
self.action_controller("scale_down_text")
|
|
@ -0,0 +1,68 @@
|
|||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
gi.require_version('Gdk', '3.0')
|
||||
from gi.repository import Gdk
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
class KeyInputController:
|
||||
def _key_press_event(self, widget, eve):
|
||||
keyname = Gdk.keyval_name(eve.keyval)
|
||||
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||
is_control = True if modifiers & Gdk.ModifierType.CONTROL_MASK else False
|
||||
is_shift = True if modifiers & Gdk.ModifierType.SHIFT_MASK else False
|
||||
|
||||
try:
|
||||
is_alt = True if modifiers & Gdk.ModifierType.ALT_MASK else False
|
||||
except Exception:
|
||||
is_alt = True if modifiers & Gdk.ModifierType.MOD1_MASK else False
|
||||
|
||||
|
||||
def _key_release_event(self, widget, eve):
|
||||
keyname = Gdk.keyval_name(eve.keyval)
|
||||
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||
is_control = True if modifiers & Gdk.ModifierType.CONTROL_MASK else False
|
||||
is_shift = True if modifiers & Gdk.ModifierType.SHIFT_MASK else False
|
||||
|
||||
try:
|
||||
is_alt = True if modifiers & Gdk.ModifierType.ALT_MASK else False
|
||||
except Exception:
|
||||
is_alt = True if modifiers & Gdk.ModifierType.MOD1_MASK else False
|
||||
|
||||
page_num, container, source_view = self.get_active_view()
|
||||
if is_control:
|
||||
if is_shift:
|
||||
if keyname in ["Up", "Down"]:
|
||||
if keyname == "Up":
|
||||
self.keyboard_move_tab_to_1(page_num)
|
||||
if keyname == "Down":
|
||||
self.keyboard_move_tab_to_2(page_num)
|
||||
|
||||
return True
|
||||
|
||||
if keyname in ["w", "t", "o"]:
|
||||
if keyname == "w":
|
||||
self.close_tab(None, container, source_view)
|
||||
if keyname == "t":
|
||||
self._create_view()
|
||||
if keyname == "o":
|
||||
event_system.emit("open_files")
|
||||
|
||||
return True
|
||||
|
||||
if is_alt:
|
||||
if keyname in ["Up", "Down", "Left", "Right"]:
|
||||
if keyname == "Up":
|
||||
self.keyboard_prev_tab(page_num)
|
||||
if keyname == "Down":
|
||||
self.keyboard_next_tab(page_num)
|
||||
if keyname == "Left":
|
||||
self.keyboard_move_tab_left(page_num)
|
||||
if keyname == "Right":
|
||||
self.keyboard_move_tab_right(page_num)
|
||||
|
||||
return True
|
|
@ -1,23 +0,0 @@
|
|||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
gi.require_version('GtkSource', '4')
|
||||
from gi.repository import GtkSource
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
# NOTE: GtkSource 5 allows for smart indent action by allowing us to override the default auto indent logic...
|
||||
# In the long run this will be better because we can check not only for :, ;, { or other things but apply per language such as bash where
|
||||
# there isn't a special char but words...
|
||||
# class AutoIndenter(GtkSource.Indenter):
|
||||
# def __init__(self):
|
||||
# ...
|
||||
#
|
||||
# def indent(self, view, iter):
|
||||
# ...
|
||||
#
|
||||
# def is_trigger(self, view, iter, modifier, keyval):
|
||||
# print(iter.get_char())
|
|
@ -27,14 +27,10 @@ class KeyInputController:
|
|||
|
||||
if is_control:
|
||||
if is_shift:
|
||||
if keyname in [ "z", "Up", "Down", "Left", "Right" ]:
|
||||
# NOTE: For now do like so for completion sake above.
|
||||
if keyname in ["Left", "Right"]:
|
||||
return False
|
||||
|
||||
if keyname in [ "Up", "Down" ]:
|
||||
return True
|
||||
|
||||
if keyname in [ "slash", "Up", "Down", "z" ]:
|
||||
if keyname in [ "slash", "Up", "Down", "m", "z", "y" ]:
|
||||
return True
|
||||
|
||||
if is_alt:
|
||||
|
@ -52,10 +48,12 @@ class KeyInputController:
|
|||
self.end_user_action(buffer)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
# NOTE: if a plugin recieves the call and handles, it will be the final decider for propigation
|
||||
return event_system.emit_and_await("autopairs", (keyname, is_control, is_alt, is_shift))
|
||||
|
||||
|
||||
|
||||
def _key_release_event(self, widget, eve):
|
||||
if self.freeze_multi_line_insert: return
|
||||
|
||||
|
@ -65,6 +63,57 @@ class KeyInputController:
|
|||
is_shift = True if modifiers & Gdk.ModifierType.SHIFT_MASK else False
|
||||
buffer = self.get_buffer()
|
||||
|
||||
try:
|
||||
is_alt = True if modifiers & Gdk.ModifierType.ALT_MASK else False
|
||||
except Exception:
|
||||
is_alt = True if modifiers & Gdk.ModifierType.MOD1_MASK else False
|
||||
|
||||
can_continue = self.can_proceed(keyname, is_control, is_shift, is_alt)
|
||||
if not can_continue:
|
||||
return can_continue
|
||||
|
||||
|
||||
if is_control:
|
||||
if is_shift:
|
||||
if keyname in ["S"]:
|
||||
if keyname == "S":
|
||||
self.save_file_as()
|
||||
|
||||
return True
|
||||
|
||||
if keyname in ["z", "y", "m", "s", "h", "equal", "minus", "Up", "Down"]:
|
||||
if keyname == "z":
|
||||
self.keyboard_undo()
|
||||
if keyname == "y":
|
||||
self.keyboard_redo()
|
||||
if keyname == "m":
|
||||
self.keyboard_insert_mark()
|
||||
if keyname == "s":
|
||||
self.save_file()
|
||||
if keyname == "h":
|
||||
self.toggle_highlight_line()
|
||||
|
||||
if keyname == "equal":
|
||||
self.scale_up_text()
|
||||
if keyname == "minus":
|
||||
self.scale_down_text()
|
||||
|
||||
if keyname == "Up":
|
||||
self.keyboard_move_lines_up()
|
||||
if keyname == "Down":
|
||||
self.keyboard_move_lines_down()
|
||||
|
||||
return True
|
||||
|
||||
# Note: Sink these requets
|
||||
if keyname in ["Slash"]:
|
||||
return True
|
||||
|
||||
if is_alt:
|
||||
if keyname == "m":
|
||||
self.keyboard_clear_marks()
|
||||
|
||||
|
||||
if keyname in {"Return", "Enter"}:
|
||||
if len(self._multi_insert_marks) > 0:
|
||||
self.begin_user_action(buffer)
|
||||
|
@ -75,4 +124,20 @@ class KeyInputController:
|
|||
|
||||
has_selection = buffer.get_has_selection()
|
||||
if not has_selection:
|
||||
return self.insert_indent_handler(buffer)
|
||||
return self.insert_indent_handler(buffer)
|
||||
|
||||
|
||||
def can_proceed(self, keyname, is_control, is_shift, is_alt):
|
||||
if is_control:
|
||||
if is_shift:
|
||||
if keyname in ["Up", "Down"]:
|
||||
return False
|
||||
|
||||
if keyname in ["w", "t", "o"]:
|
||||
return False
|
||||
|
||||
if is_alt:
|
||||
if keyname in ["Up", "Down", "Left", "Right"]:
|
||||
return False
|
||||
|
||||
return True
|
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
SourceView Mixins Module
|
||||
"""
|
|
@ -130,3 +130,34 @@ class FileEventsMixin:
|
|||
|
||||
buffer.set_modified(False)
|
||||
return gfile
|
||||
|
||||
|
||||
def _document_loaded(self, line: int = 0):
|
||||
for provider in self._completion.get_providers():
|
||||
self._completion.remove_provider(provider)
|
||||
|
||||
file = self._current_file.get_path()
|
||||
buffer = self.get_buffer()
|
||||
|
||||
word_completion = GtkSource.CompletionWords.new("word_completion")
|
||||
word_completion.register(buffer)
|
||||
self._completion.add_provider(word_completion)
|
||||
|
||||
# TODO: actually load a meaningful provider based on file type...
|
||||
# example_completion_provider = ExampleCompletionProvider()
|
||||
# self._completion.add_provider(example_completion_provider)
|
||||
|
||||
# py_completion_provider = PythonCompletionProvider(file)
|
||||
# self._completion.add_provider(py_completion_provider)
|
||||
self.got_to_line(buffer, line)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ from gi.repository import Gtk
|
|||
|
||||
|
||||
class MarkEventsMixin:
|
||||
|
||||
|
||||
def keyboard_insert_mark(self, target_iter = None, is_keyboard_insert = True):
|
||||
buffer = self.get_buffer()
|
||||
|
|
@ -12,15 +12,14 @@ from gi.repository import Gio
|
|||
from gi.repository import GtkSource
|
||||
|
||||
# Application imports
|
||||
# from .auto_indenter import AutoIndenter
|
||||
from .key_input_controller import KeyInputController
|
||||
from .source_view_events import SourceViewEventsMixin
|
||||
from .source_view_controller import SourceViewControllerMixin
|
||||
|
||||
from .custom_completion_providers.example_completion_provider import ExampleCompletionProvider
|
||||
from .custom_completion_providers.python_completion_provider import PythonCompletionProvider
|
||||
|
||||
|
||||
|
||||
class SourceView(KeyInputController, SourceViewEventsMixin, GtkSource.View):
|
||||
class SourceView(SourceViewControllerMixin, GtkSource.View):
|
||||
def __init__(self):
|
||||
super(SourceView, self).__init__()
|
||||
|
||||
|
@ -46,7 +45,6 @@ class SourceView(KeyInputController, SourceViewEventsMixin, GtkSource.View):
|
|||
|
||||
self._setup_styling()
|
||||
self._setup_signals()
|
||||
self._set_up_dnd()
|
||||
self._subscribe_to_events()
|
||||
self._load_widgets()
|
||||
|
||||
|
@ -99,109 +97,4 @@ class SourceView(KeyInputController, SourceViewEventsMixin, GtkSource.View):
|
|||
...
|
||||
|
||||
def _load_widgets(self):
|
||||
...
|
||||
|
||||
|
||||
def _document_loaded(self, line: int = 0):
|
||||
for provider in self._completion.get_providers():
|
||||
self._completion.remove_provider(provider)
|
||||
|
||||
file = self._current_file.get_path()
|
||||
buffer = self.get_buffer()
|
||||
|
||||
word_completion = GtkSource.CompletionWords.new("word_completion")
|
||||
word_completion.register(buffer)
|
||||
self._completion.add_provider(word_completion)
|
||||
|
||||
# TODO: actually load a meaningful provider based on file type...
|
||||
# example_completion_provider = ExampleCompletionProvider()
|
||||
# self._completion.add_provider(example_completion_provider)
|
||||
|
||||
# py_completion_provider = PythonCompletionProvider(file)
|
||||
# self._completion.add_provider(py_completion_provider)
|
||||
self.got_to_line(buffer, line)
|
||||
|
||||
|
||||
def _create_default_tag(self, buffer):
|
||||
general_style_tag = buffer.create_tag('general_style')
|
||||
general_style_tag.set_property('size', 100)
|
||||
general_style_tag.set_property('scale', 100)
|
||||
|
||||
def _is_modified(self, *args):
|
||||
buffer = self.get_buffer()
|
||||
|
||||
if not self._loading_file:
|
||||
event_system.emit("buffer_changed", (buffer, ))
|
||||
else:
|
||||
event_system.emit("buffer_changed_first_load", (buffer, ))
|
||||
|
||||
self.update_cursor_position(buffer)
|
||||
|
||||
def _insert_text(self, buffer, location_itr, text_str, len_int):
|
||||
if self.freeze_multi_line_insert: return
|
||||
|
||||
self.begin_user_action(buffer)
|
||||
with buffer.freeze_notify():
|
||||
GLib.idle_add(self._update_multi_line_markers, *(buffer, text_str,))
|
||||
|
||||
def _buffer_modified_changed(self, buffer):
|
||||
tab_widget = self.get_parent().get_tab_widget()
|
||||
tab_widget.set_status(changed = True if buffer.get_modified() else False)
|
||||
|
||||
|
||||
def _button_press_event(self, widget = None, eve = None, user_data = None):
|
||||
if eve.type == Gdk.EventType.BUTTON_PRESS and eve.button == 1 : # l-click
|
||||
if eve.state & Gdk.ModifierType.CONTROL_MASK:
|
||||
self.button_press_insert_mark(eve)
|
||||
return True
|
||||
else:
|
||||
self.keyboard_clear_marks()
|
||||
elif eve.type == Gdk.EventType.BUTTON_RELEASE and eve.button == 3: # r-click
|
||||
...
|
||||
|
||||
def _scroll_event(self, widget, eve):
|
||||
accel_mask = Gtk.accelerator_get_default_mod_mask()
|
||||
x, y, z = eve.get_scroll_deltas()
|
||||
if eve.state & accel_mask == Gdk.ModifierType.CONTROL_MASK:
|
||||
buffer = self.get_buffer()
|
||||
if z > 0:
|
||||
self.scale_down_text(buffer)
|
||||
else:
|
||||
self.scale_up_text(buffer)
|
||||
|
||||
return True
|
||||
|
||||
if eve.state & accel_mask == Gdk.ModifierType.SHIFT_MASK:
|
||||
adjustment = self.get_hadjustment()
|
||||
current_val = adjustment.get_value()
|
||||
step_val = adjustment.get_step_increment()
|
||||
|
||||
if z > 0: # NOTE: scroll left
|
||||
adjustment.set_value(current_val - step_val * 2)
|
||||
else: # NOTE: scroll right
|
||||
adjustment.set_value(current_val + step_val * 2)
|
||||
|
||||
return True
|
||||
|
||||
def _focus_in_event(self, widget, eve = None):
|
||||
event_system.emit("set_active_src_view", (self,))
|
||||
self.get_parent().get_parent().is_editor_focused = True
|
||||
|
||||
def _on_widget_focus(self, widget, eve = None):
|
||||
tab_view = self.get_parent().get_parent()
|
||||
path = self._current_file if self._current_file else ""
|
||||
|
||||
event_system.emit('focused_target_changed', (tab_view.NAME,))
|
||||
event_system.emit("set_path_label", (path,))
|
||||
event_system.emit("set_encoding_label")
|
||||
event_system.emit("set_file_type_label", (self._current_filetype,))
|
||||
|
||||
return False
|
||||
|
||||
def _on_cursor_move(self, buffer, cursor_iter, mark, user_data = None):
|
||||
if mark != buffer.get_insert(): return
|
||||
|
||||
self.update_cursor_position(buffer)
|
||||
|
||||
# NOTE: Not sure but this might not be efficient if the map reloads the same view...
|
||||
event_system.emit(f"set_source_view", (self,))
|
||||
self._set_up_dnd()
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
# Application imports
|
||||
from .key_input_controller import KeyInputController
|
||||
from .source_view_events import SourceViewEvents
|
||||
|
||||
|
||||
|
||||
class SourceViewControllerMixin(KeyInputController, SourceViewEvents):
|
||||
def get_current_filepath(self):
|
||||
return self._current_file
|
||||
|
||||
def get_filetype(self):
|
||||
return self._current_filetype
|
||||
|
||||
def set_buffer_language(self, buffer, language = "python3"):
|
||||
buffer.set_language( self._language_manager.get_language(language) )
|
||||
|
||||
def set_buffer_style(self, buffer, style = settings.theming.syntax_theme):
|
||||
buffer.set_style_scheme( self._style_scheme_manager.get_scheme(style) )
|
||||
|
||||
|
||||
def update_cursor_position(self, buffer = None):
|
||||
buffer = self.get_buffer() if not buffer else buffer
|
||||
iter = buffer.get_iter_at_mark( buffer.get_insert() )
|
||||
chars = iter.get_offset()
|
||||
row = iter.get_line() + 1
|
||||
col = self.get_visual_column(iter) + 1
|
||||
|
||||
event_system.emit("set_line_char_label", (f"{row}:{col}",))
|
||||
|
||||
def update_labels(self, gfile = None):
|
||||
if not gfile: return
|
||||
|
||||
tab_widget = self.get_parent().get_tab_widget()
|
||||
tab_widget.set_tab_label(self._current_filename)
|
||||
self.set_bottom_labels(gfile)
|
||||
|
||||
def set_bottom_labels(self, gfile = None):
|
||||
if not gfile: return
|
||||
|
||||
event_system.emit("set_bottom_labels", (gfile, None, self._current_filetype, None))
|
||||
self.update_cursor_position()
|
||||
|
||||
def got_to_line(self, buffer = None, line: int = 0):
|
||||
buffer = self.get_buffer() if not buffer else buffer
|
||||
line_itr = buffer.get_iter_at_line(line)
|
||||
char_iter = buffer.get_iter_at_line_offset(line, line_itr.get_bytes_in_line())
|
||||
|
||||
buffer.place_cursor(char_iter)
|
||||
if not buffer.get_mark("starting_cursor"):
|
||||
buffer.create_mark("starting_cursor", char_iter, True)
|
||||
self.scroll_to_mark( buffer.get_mark("starting_cursor"), 0.0, True, 0.0, 0.0 )
|
||||
|
||||
def toggle_highlight_line(self, widget = None, eve = None):
|
||||
self.set_highlight_current_line( not self.get_highlight_current_line() )
|
||||
|
||||
def scale_up_text(self, buffer = None, scale_step = 10):
|
||||
if not buffer:
|
||||
buffer = self.get_buffer()
|
||||
|
||||
ctx = self.get_style_context()
|
||||
|
||||
if self._px_value < 99:
|
||||
self._px_value += 1
|
||||
ctx.add_class(f"px{self._px_value}")
|
||||
|
||||
# NOTE: Hope to bring this or similar back after we decouple scaling issues coupled with the miniview.
|
||||
# tag_table = buffer.get_tag_table()
|
||||
# start_itr = buffer.get_start_iter()
|
||||
# end_itr = buffer.get_end_iter()
|
||||
# tag = tag_table.lookup('general_style')
|
||||
#
|
||||
# tag.set_property('scale', tag.get_property('scale') + scale_step)
|
||||
# buffer.apply_tag(tag, start_itr, end_itr)
|
||||
|
||||
def scale_down_text(self, buffer = None, scale_step = 10):
|
||||
if not buffer:
|
||||
buffer = self.get_buffer()
|
||||
|
||||
ctx = self.get_style_context()
|
||||
|
||||
if self._px_value > 1:
|
||||
ctx.remove_class(f"px{self._px_value}")
|
||||
self._px_value -= 1
|
||||
ctx.add_class(f"px{self._px_value}")
|
||||
|
||||
# NOTE: Hope to bring this or similar back after we decouple scaling issues coupled with the miniview.
|
||||
# tag_table = buffer.get_tag_table()
|
||||
# start_itr = buffer.get_start_iter()
|
||||
# end_itr = buffer.get_end_iter()
|
||||
# tag = tag_table.lookup('general_style')
|
||||
#
|
||||
# tag.set_property('scale', tag.get_property('scale') - scale_step)
|
||||
# buffer.apply_tag(tag, start_itr, end_itr)
|
||||
|
||||
def keyboard_undo(self):
|
||||
buffer = self.get_buffer()
|
||||
buffer.undo()
|
||||
|
||||
def keyboard_redo(self):
|
||||
buffer = self.get_buffer()
|
||||
buffer.redo()
|
||||
|
||||
def keyboard_move_lines_up(self):
|
||||
buffer = self.get_buffer()
|
||||
|
||||
self.begin_user_action(buffer)
|
||||
|
||||
self.emit("move-lines", *(False,))
|
||||
# unindent_lines
|
||||
# self.emit("move-words", *(self, 4,))
|
||||
|
||||
self.end_user_action(buffer)
|
||||
|
||||
def keyboard_move_lines_down(self):
|
||||
buffer = self.get_buffer()
|
||||
|
||||
self.begin_user_action(buffer)
|
||||
|
||||
self.emit("move-lines", *(True,))
|
||||
# self.emit("move-words", *(self, -4,))
|
||||
|
||||
self.end_user_action(buffer)
|
|
@ -3,121 +3,98 @@
|
|||
# Lib imports
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version('Gdk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
|
||||
# Application imports
|
||||
from .source_view_dnd_mixin import SourceViewDnDMixin
|
||||
from .source_file_events_mixin import FileEventsMixin
|
||||
from .source_mark_events_mixin import MarkEventsMixin
|
||||
from .mixins.source_view_dnd_mixin import SourceViewDnDMixin
|
||||
from .mixins.source_file_events_mixin import FileEventsMixin
|
||||
from .mixins.source_mark_events_mixin import MarkEventsMixin
|
||||
|
||||
|
||||
class SourceViewEvents(SourceViewDnDMixin, MarkEventsMixin, FileEventsMixin):
|
||||
def _create_default_tag(self, buffer):
|
||||
general_style_tag = buffer.create_tag('general_style')
|
||||
general_style_tag.set_property('size', 100)
|
||||
general_style_tag.set_property('scale', 100)
|
||||
|
||||
class SourceViewEventsMixin(SourceViewDnDMixin, MarkEventsMixin, FileEventsMixin):
|
||||
def get_current_filepath(self):
|
||||
return self._current_file
|
||||
|
||||
def get_filetype(self):
|
||||
return self._current_filetype
|
||||
|
||||
def set_buffer_language(self, buffer, language = "python3"):
|
||||
buffer.set_language( self._language_manager.get_language(language) )
|
||||
|
||||
def set_buffer_style(self, buffer, style = settings.theming.syntax_theme):
|
||||
buffer.set_style_scheme( self._style_scheme_manager.get_scheme(style) )
|
||||
|
||||
def toggle_highlight_line(self, widget = None, eve = None):
|
||||
self.set_highlight_current_line( not self.get_highlight_current_line() )
|
||||
|
||||
def scale_up_text(self, buffer, scale_step = 10):
|
||||
ctx = self.get_style_context()
|
||||
|
||||
if self._px_value < 99:
|
||||
self._px_value += 1
|
||||
ctx.add_class(f"px{self._px_value}")
|
||||
|
||||
# NOTE: Hope to bring this or similar back after we decouple scaling issues coupled with the miniview.
|
||||
# tag_table = buffer.get_tag_table()
|
||||
# start_itr = buffer.get_start_iter()
|
||||
# end_itr = buffer.get_end_iter()
|
||||
# tag = tag_table.lookup('general_style')
|
||||
#
|
||||
# tag.set_property('scale', tag.get_property('scale') + scale_step)
|
||||
# buffer.apply_tag(tag, start_itr, end_itr)
|
||||
|
||||
def scale_down_text(self, buffer, scale_step = 10):
|
||||
ctx = self.get_style_context()
|
||||
|
||||
if self._px_value > 1:
|
||||
ctx.remove_class(f"px{self._px_value}")
|
||||
self._px_value -= 1
|
||||
ctx.add_class(f"px{self._px_value}")
|
||||
|
||||
# NOTE: Hope to bring this or similar back after we decouple scaling issues coupled with the miniview.
|
||||
# tag_table = buffer.get_tag_table()
|
||||
# start_itr = buffer.get_start_iter()
|
||||
# end_itr = buffer.get_end_iter()
|
||||
# tag = tag_table.lookup('general_style')
|
||||
#
|
||||
# tag.set_property('scale', tag.get_property('scale') - scale_step)
|
||||
# buffer.apply_tag(tag, start_itr, end_itr)
|
||||
|
||||
def update_cursor_position(self, buffer = None):
|
||||
buffer = self.get_buffer() if not buffer else buffer
|
||||
iter = buffer.get_iter_at_mark( buffer.get_insert() )
|
||||
chars = iter.get_offset()
|
||||
row = iter.get_line() + 1
|
||||
col = self.get_visual_column(iter) + 1
|
||||
|
||||
event_system.emit("set_line_char_label", (f"{row}:{col}",))
|
||||
|
||||
def got_to_line(self, buffer = None, line: int = 0):
|
||||
buffer = self.get_buffer() if not buffer else buffer
|
||||
line_itr = buffer.get_iter_at_line(line)
|
||||
char_iter = buffer.get_iter_at_line_offset(line, line_itr.get_bytes_in_line())
|
||||
|
||||
buffer.place_cursor(char_iter)
|
||||
if not buffer.get_mark("starting_cursor"):
|
||||
buffer.create_mark("starting_cursor", char_iter, True)
|
||||
self.scroll_to_mark( buffer.get_mark("starting_cursor"), 0.0, True, 0.0, 0.0 )
|
||||
|
||||
def keyboard_undo(self):
|
||||
def _is_modified(self, *args):
|
||||
buffer = self.get_buffer()
|
||||
buffer.undo()
|
||||
|
||||
def keyboard_redo(self):
|
||||
buffer = self.get_buffer()
|
||||
buffer.redo()
|
||||
if not self._loading_file:
|
||||
event_system.emit("buffer_changed", (buffer, ))
|
||||
else:
|
||||
event_system.emit("buffer_changed_first_load", (buffer, ))
|
||||
|
||||
def keyboard_move_lines_up(self):
|
||||
buffer = self.get_buffer()
|
||||
self.update_cursor_position(buffer)
|
||||
|
||||
def _insert_text(self, buffer, location_itr, text_str, len_int):
|
||||
if self.freeze_multi_line_insert: return
|
||||
|
||||
self.begin_user_action(buffer)
|
||||
with buffer.freeze_notify():
|
||||
GLib.idle_add(self._update_multi_line_markers, *(buffer, text_str,))
|
||||
|
||||
self.emit("move-lines", *(False,))
|
||||
# unindent_lines
|
||||
# self.emit("move-words", *(self, 4,))
|
||||
|
||||
self.end_user_action(buffer)
|
||||
|
||||
def keyboard_move_lines_down(self):
|
||||
buffer = self.get_buffer()
|
||||
|
||||
self.begin_user_action(buffer)
|
||||
|
||||
self.emit("move-lines", *(True,))
|
||||
# self.emit("move-words", *(self, -4,))
|
||||
|
||||
self.end_user_action(buffer)
|
||||
|
||||
def update_labels(self, gfile = None):
|
||||
if not gfile: return
|
||||
|
||||
def _buffer_modified_changed(self, buffer):
|
||||
tab_widget = self.get_parent().get_tab_widget()
|
||||
tab_widget.set_tab_label(self._current_filename)
|
||||
self.set_bottom_labels(gfile)
|
||||
tab_widget.set_status(changed = True if buffer.get_modified() else False)
|
||||
|
||||
def set_bottom_labels(self, gfile = None):
|
||||
if not gfile: return
|
||||
|
||||
event_system.emit("set_bottom_labels", (gfile, None, self._current_filetype, None))
|
||||
self.update_cursor_position()
|
||||
def _button_press_event(self, widget = None, eve = None, user_data = None):
|
||||
if eve.type == Gdk.EventType.BUTTON_PRESS and eve.button == 1 : # l-click
|
||||
if eve.state & Gdk.ModifierType.CONTROL_MASK:
|
||||
self.button_press_insert_mark(eve)
|
||||
return True
|
||||
else:
|
||||
self.keyboard_clear_marks()
|
||||
elif eve.type == Gdk.EventType.BUTTON_RELEASE and eve.button == 3: # r-click
|
||||
...
|
||||
|
||||
def _scroll_event(self, widget, eve):
|
||||
accel_mask = Gtk.accelerator_get_default_mod_mask()
|
||||
x, y, z = eve.get_scroll_deltas()
|
||||
if eve.state & accel_mask == Gdk.ModifierType.CONTROL_MASK:
|
||||
buffer = self.get_buffer()
|
||||
if z > 0:
|
||||
self.scale_down_text(buffer)
|
||||
else:
|
||||
self.scale_up_text(buffer)
|
||||
|
||||
return True
|
||||
|
||||
if eve.state & accel_mask == Gdk.ModifierType.SHIFT_MASK:
|
||||
adjustment = self.get_hadjustment()
|
||||
current_val = adjustment.get_value()
|
||||
step_val = adjustment.get_step_increment()
|
||||
|
||||
if z > 0: # NOTE: scroll left
|
||||
adjustment.set_value(current_val - step_val * 2)
|
||||
else: # NOTE: scroll right
|
||||
adjustment.set_value(current_val + step_val * 2)
|
||||
|
||||
return True
|
||||
|
||||
def _focus_in_event(self, widget, eve = None):
|
||||
event_system.emit("set_active_src_view", (self,))
|
||||
self.get_parent().get_parent().is_editor_focused = True
|
||||
|
||||
def _on_widget_focus(self, widget, eve = None):
|
||||
tab_view = self.get_parent().get_parent()
|
||||
path = self._current_file if self._current_file else ""
|
||||
|
||||
event_system.emit('focused_target_changed', (tab_view.NAME,))
|
||||
event_system.emit("set_path_label", (path,))
|
||||
event_system.emit("set_encoding_label")
|
||||
event_system.emit("set_file_type_label", (self._current_filetype,))
|
||||
|
||||
return False
|
||||
|
||||
def _on_cursor_move(self, buffer, cursor_iter, mark, user_data = None):
|
||||
if mark != buffer.get_insert(): return
|
||||
|
||||
self.update_cursor_position(buffer)
|
||||
|
||||
# NOTE: Not sure but this might not be efficient if the map reloads the same view...
|
||||
event_system.emit(f"set_source_view", (self,))
|
Loading…
Reference in New Issue