vimamsa 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,3 @@
1
-
2
1
  # Following this example:
3
2
  # https://gabmus.org/posts/create_an_auto-resizing_image_widget_with_gtk3_and_python/
4
3
  class ResizableImage < Gtk::DrawingArea
@@ -18,26 +17,33 @@ class ResizableImage < Gtk::DrawingArea
18
17
  def scale_image()
19
18
  pb = @pixbuf
20
19
  view = @view
21
- imglimit = view.visible_rect.width - 10
20
+ if view.visible_rect.width > 0
21
+ imglimit = view.visible_rect.width - 50
22
+ else
23
+ imglimit = 500
24
+ end
22
25
 
23
26
  if @oldimg.width > imglimit or @oldimg.width < imglimit - 10
24
27
  nwidth = imglimit
25
28
  nwidth = pb.width if pb.width < imglimit
26
29
  nheight = (pb.height * (nwidth.to_f / pb.width)).to_i
30
+ # Ripl.start :binding => binding
31
+
27
32
  pb = pb.scale_simple(nwidth, nheight, GdkPixbuf::InterpType::HYPER)
28
33
  else
29
34
  pb = @oldimg
30
35
  end
31
36
  @draw_image = pb
32
37
  @oldimg = pb
33
- self.set_size_request(pb.width, pb.height)
34
-
38
+ #TODO: Should be better way to compensate for the gutter
39
+ self.set_size_request(pb.width+@view.gutter_width, pb.height)
35
40
  end
36
41
 
37
42
  def do_draw(da, cr)
38
43
  # puts @fpath
39
- cr.set_source_pixbuf(@draw_image, 0, 0)
44
+ # Ripl.start :binding => binding
45
+
46
+ cr.set_source_pixbuf(@draw_image, @view.gutter_width, 0)
40
47
  cr.paint
41
48
  end
42
49
  end
43
-
@@ -16,7 +16,6 @@ module Vimamsa
16
16
  end
17
17
 
18
18
  def add_menu_items()
19
-
20
19
  add_to_menu "File.Example", { :label => "<span foreground='#888888'>Action, [mode] key binding</span>", :action => nil }
21
20
  add_to_menu "File.Save", { :label => "Save", :action => :buf_save }
22
21
  add_to_menu "File.Save as", { :label => "Save As...", :action => :buf_save_as }
@@ -40,14 +39,13 @@ module Vimamsa
40
39
  add_to_menu "Actions.FileHistoryFinder", { :label => "Search files in history", :action => :gui_file_history_finder }
41
40
 
42
41
  add_to_menu "Actions.experimental.Diff", { :label => "Show Diff of\nunsaved changes", :action => :diff_buffer }
43
-
42
+
44
43
  add_to_menu "Actions.experimental.EnableDebug", { :label => "Enable debug", :action => :enable_debug }
45
44
  add_to_menu "Actions.experimental.DisableDebug", { :label => "Disable debug", :action => :disable_debug }
46
45
  add_to_menu "Actions.experimental.ShowImages", { :label => "Show images ⟦img:path⟧", :action => :show_images }
47
-
46
+
48
47
  add_to_menu "Actions.EncryptFile", { :label => "Encrypt file", :action => :encrypt_file }
49
48
  add_to_menu "Help.KeyBindings", { :label => "Show key bindings", :action => :show_key_bindings }
50
-
51
49
 
52
50
  #TODO: :auto_indent_buffer
53
51
 
@@ -55,26 +53,19 @@ module Vimamsa
55
53
 
56
54
  end
57
55
 
58
- def initialize(menubar)
59
- # nfo["file"] = { :items => {}, :label => "File" }
60
- # nfo["actions"] = { :items => {}, :label => "Actions" }
61
- # nfo["help"] = { :items => {}, :label => "Help" }
62
-
56
+ def initialize(menubar, _app)
57
+ @app = _app
63
58
  @nfo = {}
64
59
 
65
60
  add_menu_items
66
61
 
67
- # add_to_menu("help.extra.keybindings", { :label => "Show keybindings" })
68
- # add_to_menu("help.extra.nfo.keybindings", { :label => "Show keybindings" })
69
- # add_to_menu("help.keybindings", { :label => "Show keybindings <span foreground='#888888' >C ? k</span>" }) #font='12' weight='ultrabold'
70
-
71
62
  for k, v in @nfo
72
63
  build_menu(v, menubar)
73
64
  end
74
65
  end
75
66
 
76
67
  def build_menu(nfo, parent)
77
- menu = Gtk::Menu.new
68
+ menu = Gio::Menu.new
78
69
  if nfo[:action]
79
70
  kbd_str = ""
80
71
  for mode_str in ["C", "V"]
@@ -86,24 +77,38 @@ module Vimamsa
86
77
  end
87
78
 
88
79
  label_str = nfo[:label] + kbd_str
89
- menuitem = Gtk::MenuItem.new(:label => label_str)
90
- menuitem.children[0].set_markup(label_str)
91
-
92
- menuitem.signal_connect("activate") do
80
+ actkey = nfo[:action].to_s
81
+ menuitem = Gio::MenuItem.new(label_str, "app.#{actkey}")
82
+
83
+ # This worked in GTK3:
84
+ # But seems there is no way to access the Label object in GTK4
85
+ # menuitem.children[0].set_markup(label_str)
86
+
87
+ act = Gio::SimpleAction.new(actkey)
88
+ @app.add_action(act)
89
+ act.signal_connect "activate" do |_simple_action, _parameter|
93
90
  call_action(nfo[:action])
94
91
  end
95
92
  else
96
- menuitem = Gtk::MenuItem.new(:label => nfo[:label])
97
- menuitem.children[0].set_markup(nfo[:label])
93
+ menuitem = Gio::MenuItem.new(nfo[:label], nil)
98
94
  end
99
95
 
96
+ # Apparently requires Gtk 4.6 to work.
97
+ # According to instructions in: https://discourse.gnome.org/t/gtk4-and-pango-markup-in-menu-items/16082
98
+ # Boolean true here should work but doesn't yet in GTK 4.6. The string version does work.
99
+ menuitem.set_attribute_value("use-markup", "true")
100
+ # menuitem.set_attribute_value("use-markup", true)
101
+ # This might change in the future(?), but the string version still works in gtk-4.13.0 (gtk/gtkmenutrackeritem.c)
102
+
103
+
100
104
  if !nfo[:items].nil? and !nfo[:items].empty?
101
105
  for k2, item in nfo[:items]
102
106
  build_menu(item, menu)
103
107
  end
104
108
  menuitem.submenu = menu
105
109
  end
106
- parent.append(menuitem)
110
+ o = parent.append_item(menuitem)
111
+
107
112
  end
108
113
  end #end class
109
114
  end
@@ -1,4 +1,4 @@
1
- def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt={})
1
+ def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt = {})
2
2
  $selup = SelectUpdateWindow.new(nil, item_list, jump_keys, select_callback, update_callback, opt)
3
3
  $selup.run
4
4
  # opt fields:
@@ -39,7 +39,7 @@ class SelectUpdateWindow
39
39
  end
40
40
 
41
41
  def initialize(main_window, item_list, jump_keys, select_callback, update_callback, opt = {})
42
- @window = Gtk::Window.new(:toplevel)
42
+ @window = Gtk::Window.new()
43
43
  # @window.screen = main_window.screen
44
44
  @window.title = ""
45
45
  if !opt[:title].nil?
@@ -50,12 +50,23 @@ class SelectUpdateWindow
50
50
  @opt = opt
51
51
 
52
52
  debug item_list.inspect
53
- @update_callback = method(update_callback)
54
- @select_callback = method(select_callback)
53
+
54
+ if select_callback.class == Method
55
+ @select_callback = select_callback
56
+ else
57
+ @select_callback = method(select_callback)
58
+ end
59
+ if update_callback.class == Method
60
+ @update_callback = update_callback
61
+ else
62
+ @update_callback = method(update_callback)
63
+ end
55
64
  # debug @update_callback_m.call("").inspect
56
65
 
57
66
  vbox = Gtk::Box.new(:vertical, 8)
58
- vbox.margin = 8
67
+ vbox.margin_bottom = 8
68
+ vbox.margin_top = 8
69
+
59
70
  @window.add(vbox)
60
71
 
61
72
  @entry = Gtk::SearchEntry.new
@@ -74,24 +85,31 @@ class SelectUpdateWindow
74
85
  # item_list = @update_callback.call("")
75
86
  update_item_list(item_list)
76
87
 
77
- @window.signal_connect("key-press-event") do |_widget, event|
78
- # debug "KEYPRESS 1"
79
- @entry.handle_event(event)
80
- end
88
+ # @window.signal_connect("key-press-event") do |_widget, event| #TODO:gtk4
89
+ # debug "KEYPRESS 1"
90
+ # @entry.handle_event(event)
91
+ # end
92
+
93
+ press = Gtk::EventControllerKey.new
94
+ press.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
81
95
 
82
- @entry.signal_connect("key_press_event") do |widget, event|
83
- # debug "KEYPRESS 2"
84
- if event.keyval == Gdk::Keyval::KEY_Down
96
+ @entry.add_controller(press)
97
+ # @window.add_controller(press)
98
+ press.signal_connect "key-pressed" do |gesture, keyval, keycode, y|
99
+ name = Gdk::Keyval.to_name(keyval)
100
+ uki = Gdk::Keyval.to_unicode(keyval)
101
+ keystr = uki.chr("UTF-8")
102
+ debug "keyval=#{keyval}"
103
+
104
+ if keyval == Gdk::Keyval::KEY_Down
85
105
  debug "DOWN"
86
106
  set_selected_row(@selected_row + 1)
87
- # fixed = iter[COLUMN_FIXED]
88
-
89
107
  true
90
- elsif event.keyval == Gdk::Keyval::KEY_Up
108
+ elsif keyval == Gdk::Keyval::KEY_Up
91
109
  set_selected_row(@selected_row - 1)
92
110
  debug "UP"
93
111
  true
94
- elsif event.keyval == Gdk::Keyval::KEY_Return
112
+ elsif keyval == Gdk::Keyval::KEY_Return
95
113
  path = Gtk::TreePath.new(@selected_row.to_s)
96
114
  iter = @model.get_iter(path)
97
115
  ret = iter[1]
@@ -99,7 +117,7 @@ class SelectUpdateWindow
99
117
  @window.destroy
100
118
  # debug iter[1].inspect
101
119
  true
102
- elsif event.keyval == Gdk::Keyval::KEY_Escape
120
+ elsif keyval == Gdk::Keyval::KEY_Escape
103
121
  @window.destroy
104
122
  true
105
123
  else
@@ -131,11 +149,12 @@ class SelectUpdateWindow
131
149
 
132
150
  vbox.pack_start(container, :expand => false, :fill => false, :padding => 0)
133
151
  sw = Gtk::ScrolledWindow.new(nil, nil)
134
- sw.shadow_type = :etched_in
152
+ # sw.shadow_type = :etched_in #TODO:gtk4
135
153
  sw.set_policy(:never, :automatic)
136
- vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
154
+ vbox.pack_end(sw, :expand => true, :fill => true, :padding => 0)
137
155
 
138
- sw.add(treeview)
156
+ # sw.add(treeview) #TODO:gtk4
157
+ sw.set_child(treeview)
139
158
 
140
159
  if !opt[:columns].nil?
141
160
  for col in opt[:columns]
@@ -168,7 +187,7 @@ class SelectUpdateWindow
168
187
 
169
188
  def run
170
189
  if !@window.visible?
171
- @window.show_all
190
+ @window.show
172
191
  # add_spinner
173
192
  else
174
193
  @window.destroy
@@ -1,73 +1,56 @@
1
-
2
-
3
1
  # class VSourceView < Gtk::TextView
4
2
  class VSourceView < GtkSource::View
5
- attr_accessor :bufo
3
+ attr_accessor :bufo
6
4
  # :highlight_matching_brackets
7
-
5
+
8
6
  # def set_highlight_current_line(vbool)
9
7
  # end
10
-
8
+
11
9
  # def set_show_line_numbers(vbool)
12
10
  # end
13
-
11
+
14
12
  # def highlight_matching_brackets=(vbool)
15
13
  # end
16
-
17
14
 
18
15
  # def initialize(title = nil,bufo=nil)
19
- def initialize(title,bufo)
16
+ def initialize(title, bufo)
20
17
  # super(:toplevel)
21
18
  @highlight_matching_brackets = true
19
+ @idle_func_running = false
22
20
  super()
23
21
  @bufo = bufo #object of Buffer class buffer.rb
24
22
  debug "vsource init"
25
23
  @last_keyval = nil
26
24
  @last_event = [nil, nil]
27
- self.drag_dest_add_image_targets
28
- self.drag_dest_add_uri_targets
29
-
30
- signal_connect "button-press-event" do |_widget, event|
31
- if event.button == Gdk::BUTTON_PRIMARY
32
- # debug "Gdk::BUTTON_PRIMARY"
33
- false
34
- elsif event.button == Gdk::BUTTON_SECONDARY
35
- # debug "Gdk::BUTTON_SECONDARY"
36
- true
37
- else
38
- true
39
- end
40
- end
41
-
42
- signal_connect("drag-data-received") do |widget, event, x, y, data, info, time|
43
- puts "drag-data-received"
44
- puts
45
- if data.uris.size >= 1
46
- imgpath = CGI.unescape(data.uris[0])
47
- m = imgpath.match(/^file:\/\/(.*)/)
48
- if m
49
- fp = m[1]
50
- handle_drag_and_drop(fp)
51
- end
52
- end
53
- true
54
- end
55
-
56
- signal_connect("key_press_event") do |widget, event|
57
- handle_key_event(event, :key_press_event)
58
- true
59
- end
60
-
61
- signal_connect("key_release_event") do |widget, event|
62
- handle_key_event(event, :key_release_event)
63
- true
64
- end
25
+ @removed_controllers = []
26
+ self.highlight_current_line = true
27
+
28
+ # self.drag_dest_add_image_targets #TODO:gtk4
29
+ # self.drag_dest_add_uri_targets #TODO:gtk4
30
+
31
+ # signal_connect("drag-data-received") do |widget, event, x, y, data, info, time| #TODO:gtk4
32
+ # puts "drag-data-received"
33
+ # puts
34
+ # if data.uris.size >= 1
35
+ # imgpath = CGI.unescape(data.uris[0])
36
+ # m = imgpath.match(/^file:\/\/(.*)/)
37
+ # if m
38
+ # fp = m[1]
39
+ # handle_drag_and_drop(fp)
40
+ # end
41
+ # end
42
+ # true
43
+ # end
65
44
 
66
45
  signal_connect("move-cursor") do |widget, event|
46
+ debug("MOVE-CURSOR",2)
67
47
  $update_cursor = true
68
48
  false
69
49
  end
70
50
 
51
+ return
52
+
53
+ #TODO:gtk4
71
54
  signal_connect "button-release-event" do |widget, event|
72
55
  vma.buf.set_pos(buffer.cursor_position)
73
56
  false
@@ -75,7 +58,78 @@ class VSourceView < GtkSource::View
75
58
  @curpos_mark = nil
76
59
  end
77
60
 
78
- def handle_key_event(event, sig)
61
+ def gutter_width()
62
+ winwidth = width
63
+ view_width = visible_rect.width
64
+ gutter_width = winwidth - view_width
65
+ end
66
+
67
+ def show_controllers
68
+ clist = self.observe_controllers
69
+ (0..(clist.n_items - 1)).each { |x|
70
+ ctr = clist.get_item(x)
71
+ pp ctr
72
+ }
73
+ end
74
+
75
+ def check_controllers
76
+ clist = self.observe_controllers
77
+ to_remove = []
78
+ (0..(clist.n_items - 1)).each { |x|
79
+ ctr = clist.get_item(x)
80
+ # Sometimes a GestureClick EventController appears from somewhere
81
+ # not initiated from this file.
82
+
83
+ # if ctr.class == Gtk::EventControllerKey or ctr.class == Gtk::GestureClick
84
+ if ctr != @click
85
+ # to_remove << ctr if ctr.class != Gtk::GestureDrag
86
+ to_remove << ctr
87
+ end
88
+ }
89
+ if to_remove.size > 0
90
+ debug "Removing controllers:"
91
+ pp to_remove
92
+ to_remove.each { |x|
93
+ # To avoid GC. https://github.com/ruby-gnome/ruby-gnome/issues/15790
94
+ @removed_controllers << x
95
+ self.remove_controller(x)
96
+ }
97
+ end
98
+ end
99
+
100
+ def register_signals()
101
+
102
+ #TODO: Doesn't seem to catch "move-cursor" signal since upgrade to gtk4
103
+ # self.signal_connect("move-cursor") do |widget, event|
104
+ # $update_cursor = true
105
+ # false
106
+ # end
107
+
108
+ check_controllers
109
+ click = Gtk::GestureClick.new
110
+ click.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
111
+ self.add_controller(click)
112
+ # Detect mouse click
113
+ @click = click
114
+ click.signal_connect "pressed" do |gesture, n_press, x, y, z|
115
+ debug "SourceView, GestureClick x=#{x} y=#{y}"
116
+ pp visible_rect
117
+ winw = width
118
+ view_width = visible_rect.width
119
+ gutter_width = winw - view_width
120
+
121
+ i = get_iter_at_location((x - gutter_width).to_i, (y + visible_rect.y).to_i)
122
+ if !i.nil?
123
+ @bufo.set_pos(i.offset)
124
+ else
125
+ debug "iter nil 0000"
126
+ end
127
+ true
128
+ end
129
+ end
130
+
131
+ # def handle_key_event(event, sig)
132
+ def handle_key_event(keyval, keyname, sig)
79
133
  if $update_cursor
80
134
  curpos = buffer.cursor_position
81
135
  debug "MOVE CURSOR: #{curpos}"
@@ -85,13 +139,14 @@ class VSourceView < GtkSource::View
85
139
  debug $view.visible_rect.inspect
86
140
 
87
141
  debug "key event"
88
- debug event
142
+ # debug event
89
143
 
90
- key_name = event.string
91
- if event.state.control_mask?
92
- key_name = Gdk::Keyval.to_name(event.keyval)
93
- # Gdk::Keyval.to_name()
94
- end
144
+ # key_name = event.string
145
+ #TODO:??
146
+ # if event.state.control_mask?
147
+ # key_name = Gdk::Keyval.to_name(event.keyval)
148
+ # Gdk::Keyval.to_name()
149
+ # end
95
150
 
96
151
  keyval_trans = {}
97
152
  keyval_trans[Gdk::Keyval::KEY_Control_L] = "ctrl"
@@ -122,29 +177,48 @@ class VSourceView < GtkSource::View
122
177
 
123
178
  key_trans = {}
124
179
  key_trans["\e"] = "esc"
125
- tk = keyval_trans[event.keyval]
126
- key_name = tk if !tk.nil?
180
+ tk = keyval_trans[keyval]
181
+ keyname = tk if !tk.nil?
127
182
 
128
183
  key_str_parts = []
129
- key_str_parts << "ctrl" if event.state.control_mask? and key_name != "ctrl"
130
- key_str_parts << "alt" if event.state.mod1_mask? and key_name != "alt"
184
+ key_str_parts << "ctrl" if vma.kbd.modifiers[:ctrl]
185
+ key_str_parts << "alt" if vma.kbd.modifiers[:alt]
186
+ key_str_parts << "shift" if vma.kbd.modifiers[:shift]
187
+ key_str_parts << "meta" if vma.kbd.modifiers[:meta]
188
+ key_str_parts << "super" if vma.kbd.modifiers[:super]
189
+ key_str_parts << keyname
190
+
191
+ if key_str_parts[0] == key_str_parts[1]
192
+ # We don't want "ctrl-ctrl" or "alt-alt"
193
+ # TODO:There should be a better way to do this
194
+ key_str_parts.delete_at(0)
195
+ end
196
+
197
+ if key_str_parts[0] == "shift" and key_str_parts[1].class == String
198
+ #"shift-P" to just "P"
199
+ # key_str_parts.delete_at(0) if key_str_parts[1].match(/^[[:upper:]]$/)
200
+ key_str_parts.delete_at(0)
201
+ end
131
202
 
132
- key_str_parts << key_name
133
203
  key_str = key_str_parts.join("-")
134
- keynfo = { :key_str => key_str, :key_name => key_name, :keyval => event.keyval }
204
+ if key_str == "\u0000"
205
+ key_str = ""
206
+ end
207
+
208
+ keynfo = { :key_str => key_str, :key_name => keyname, :keyval => keyval }
135
209
  debug keynfo.inspect
136
210
  # $kbd.match_key_conf(key_str, nil, :key_press)
137
211
  # debug "key_str=#{key_str} key_"
138
212
 
139
213
  if key_str != "" # or prefixed_key_str != ""
140
- if sig == :key_release_event and event.keyval == @last_keyval
214
+ if sig == :key_release and keyval == @last_keyval
141
215
  $kbd.match_key_conf(key_str + "!", nil, :key_release)
142
- @last_event = [event, :key_release]
143
- elsif sig == :key_press_event
216
+ @last_event = [keynfo, :key_release]
217
+ elsif sig == :key_press
144
218
  $kbd.match_key_conf(key_str, nil, :key_press)
145
- @last_event = [event, key_str, :key_press]
219
+ @last_event = [keynfo, key_str, :key_press]
146
220
  end
147
- @last_keyval = event.keyval #TODO: outside if?
221
+ @last_keyval = keyval #TODO: outside if?
148
222
  end
149
223
 
150
224
  handle_deltas
@@ -158,7 +232,9 @@ class VSourceView < GtkSource::View
158
232
  b = buffer
159
233
  iter = b.get_iter_at(:offset => i)
160
234
  iterxy = get_iter_location(iter)
161
- winw = parent_window.width
235
+ # winw = parent_window.width #TODO:gtk4
236
+ winw = width #TODO
237
+
162
238
  view_width = visible_rect.width
163
239
  gutter_width = winw - view_width
164
240
 
@@ -168,7 +244,6 @@ class VSourceView < GtkSource::View
168
244
  # buffer_to_window_coords(Gtk::TextWindowType::TEXT, iterxy.x, iterxy.y).inspect
169
245
  # debug buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y).inspect
170
246
  (x, y) = buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y)
171
- # Ripl.start :binding => binding
172
247
 
173
248
  return [x, y]
174
249
  end
@@ -191,7 +266,8 @@ class VSourceView < GtkSource::View
191
266
  end
192
267
  end
193
268
  if any_change
194
- gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
269
+ # gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
270
+ self.set_cursor_pos(pos)
195
271
  end
196
272
 
197
273
  # sanity_check #TODO
@@ -237,7 +313,6 @@ class VSourceView < GtkSource::View
237
313
  # scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
238
314
 
239
315
  # $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
240
- # Ripl.start :binding => binding
241
316
  draw_cursor
242
317
 
243
318
  return true
@@ -252,6 +327,9 @@ class VSourceView < GtkSource::View
252
327
  # iter = buffer.get_iter_at(:offset => buffer.cursor_position)
253
328
  # iterxy = get_iter_location(iter)
254
329
 
330
+ # This is not the current buffer
331
+ return false if vma.gui.view != self
332
+
255
333
  sleep(0.01)
256
334
  # intr = iterxy.intersect(vr)
257
335
  if is_cursor_visible == false
@@ -266,8 +344,9 @@ class VSourceView < GtkSource::View
266
344
 
267
345
  scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
268
346
 
269
- # return true # Call this func again
347
+ return true # Call this func again
270
348
  else
349
+ @idle_func_running = false
271
350
  return false # Don't call this idle func again
272
351
  end
273
352
  end
@@ -283,9 +362,6 @@ class VSourceView < GtkSource::View
283
362
  if intr.nil?
284
363
  debug iterxy.inspect
285
364
  debug vr.inspect
286
- # Ripl.start :binding => binding
287
-
288
- # exit!
289
365
  return false
290
366
  else
291
367
  return true
@@ -293,7 +369,12 @@ class VSourceView < GtkSource::View
293
369
  end
294
370
 
295
371
  def ensure_cursor_visible
372
+ return #TODO:gtk4
373
+ debug "@idle_func_running=#{@idle_func_running}"
374
+ return if @idle_func_running
296
375
  if is_cursor_visible == false
376
+ @idle_func_running = true
377
+ debug "Starting idle func"
297
378
  Thread.new {
298
379
  sleep 0.01
299
380
  GLib::Idle.add(proc { cursor_visible_idle_func })
@@ -302,21 +383,33 @@ class VSourceView < GtkSource::View
302
383
  end
303
384
 
304
385
  def draw_cursor
305
- if is_command_mode
386
+ mode = vma.kbd.get_mode
387
+ ctype = vma.kbd.get_cursor_type
388
+ # if is_command_mode
389
+ if ctype == :command
306
390
  itr = buffer.get_iter_at(:offset => @bufo.pos)
307
391
  itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
308
- $view.buffer.select_range(itr, itr2)
309
- elsif @bufo.visual_mode?
392
+ buffer.select_range(itr, itr2)
393
+ # elsif @bufo.visual_mode?
394
+ elsif ctype == :visual
310
395
  debug "VISUAL MODE"
311
396
  (_start, _end) = @bufo.get_visual_mode_range2
312
397
  debug "#{_start}, #{_end}"
313
398
  itr = buffer.get_iter_at(:offset => _start)
314
399
  itr2 = buffer.get_iter_at(:offset => _end + 1)
315
- $view.buffer.select_range(itr, itr2)
316
- else # Insert mode
400
+ # Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
401
+ buffer.select_range(itr, itr2)
402
+ elsif ctype == :insert
403
+ # Not sure why this is needed
317
404
  itr = buffer.get_iter_at(:offset => @bufo.pos)
318
- $view.buffer.select_range(itr, itr)
405
+ buffer.select_range(itr, itr)
406
+
407
+ # Via trial and error, this combination is only thing that seems to work:
408
+ vma.gui.sw.child.toggle_cursor_visible
409
+ vma.gui.sw.child.cursor_visible = true
410
+
319
411
  debug "INSERT MODE"
412
+ else # TODO
320
413
  end
321
414
  end
322
415
  end
@@ -51,6 +51,35 @@ def translate_path(fn, bf)
51
51
  return outfn
52
52
  end
53
53
 
54
+ # Scan audio files inserted with ⟦audio:filepath⟧ syntax
55
+ #TODO: merge code with hpt_scan_images
56
+ def hpt_scan_audio(bf = nil)
57
+ bf = buf() if bf.nil?
58
+ return if bf.nil?
59
+ return if !bf.fname
60
+ return if !bf.fname.match(/.*txt$/)
61
+ imgpos = scan_indexes(bf, /⟦audio:.+?⟧/)
62
+ imgtags = bf.scan(/(⟦audio:(.+?)⟧)/)
63
+ c = 0
64
+ imgpos.each.with_index { |x, i|
65
+ a = imgpos[i]
66
+ t = imgtags[i]
67
+ insert_pos = a + t[0].size + c
68
+ fn = t[1]
69
+ imgfn = translate_path(fn, bf)
70
+ next if !File.exist?(imgfn)
71
+ # Show as image in gui, handle as empty space in txt file
72
+
73
+ if bf[insert_pos..(insert_pos + 2)] != "\n \n"
74
+ bf.insert_txt_at("\n \n", insert_pos)
75
+ bf.view.handle_deltas
76
+ c += 3
77
+ end
78
+ bf.add_audio(imgfn, insert_pos + 1)
79
+ }
80
+ # vma.gui.delex.run #TODO:gtk4
81
+ end
82
+
54
83
  # Scan images inserted with ⟦img:filepath⟧ syntax
55
84
  def hpt_scan_images(bf = nil)
56
85
  bf = buf() if bf.nil?
@@ -76,5 +105,9 @@ def hpt_scan_images(bf = nil)
76
105
  end
77
106
  bf.add_image(imgfn, insert_pos + 1)
78
107
  }
79
- vma.gui.delex.run
108
+
109
+ # Need to scale after buffer loaded
110
+ GLib::Idle.add(proc { vma.gui.scale_all_images })
111
+
112
+ # vma.gui.delex.run #TODO:gtk4
80
113
  end