topinambour 1.0.16 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +15 -200
- data/bin/topinambour +2 -3
- data/data/gschemas.compiled +0 -0
- data/data/topinambour.gschema.xml +4 -4
- data/lib/actions.rb +25 -24
- data/lib/application.rb +14 -15
- data/lib/color_selector.rb +6 -5
- data/lib/font_selector.rb +2 -2
- data/lib/preferences.rb +1 -1
- data/lib/shortcuts.rb +2 -17
- data/lib/terminal.rb +10 -28
- data/lib/terminal_regex.rb +13 -8
- data/lib/window.rb +12 -110
- metadata +3 -6
- data/lib/notebook.rb +0 -109
- data/lib/searchbar.rb +0 -51
- data/lib/terminal_chooser.rb +0 -397
data/lib/notebook.rb
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
# Copyright 2015-2017 Cedric LE MOIGNE, cedlemo@gmx.com
|
2
|
-
# This file is part of Topinambour.
|
3
|
-
#
|
4
|
-
# Topinambour is free software: you can redistribute it and/or modify
|
5
|
-
# it under the terms of the GNU General Public License as published by
|
6
|
-
# the Free Software Foundation, either version 3 of the License, or
|
7
|
-
# any later version.
|
8
|
-
#
|
9
|
-
# Topinambour is distributed in the hope that it will be useful,
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
-
# GNU General Public License for more details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU General Public License
|
15
|
-
# along with Topinambour. If not, see <http://www.gnu.org/licenses/>.
|
16
|
-
class TopinambourNotebook < Gtk::Notebook
|
17
|
-
attr_reader :visible, :hidden
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
super()
|
21
|
-
@hidden = []
|
22
|
-
signal_connect("hide") { @visible = false }
|
23
|
-
|
24
|
-
signal_connect("show") { @visible = true }
|
25
|
-
|
26
|
-
signal_connect "switch-page" do |_widget, next_page, next_page_num|
|
27
|
-
toplevel.current_label.text = next_page.term.terminal_title
|
28
|
-
toplevel.current_tab.text = "#{next_page_num + 1}/#{n_pages}"
|
29
|
-
generate_tab_preview if page >= 0
|
30
|
-
end
|
31
|
-
|
32
|
-
signal_connect "page-reordered" do
|
33
|
-
toplevel.current_tab.text = "#{page + 1}/#{n_pages}"
|
34
|
-
end
|
35
|
-
|
36
|
-
signal_connect "page-removed" do |_widget, _child, page_num|
|
37
|
-
if toplevel.class == TopinambourWindow
|
38
|
-
toplevel.current_tab.text = "#{page + 1}/#{n_pages}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
set_name("topinambour-notebook")
|
42
|
-
set_show_tabs(false)
|
43
|
-
set_show_border(false)
|
44
|
-
end
|
45
|
-
|
46
|
-
def remove_all_pages
|
47
|
-
each do |widget|
|
48
|
-
index = page_num(widget)
|
49
|
-
remove_page(index)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def cycle_next_page
|
54
|
-
page < (n_pages - 1) ? next_page : set_page(0)
|
55
|
-
end
|
56
|
-
|
57
|
-
def cycle_prev_page
|
58
|
-
page > 0 ? prev_page : set_page(n_pages - 1)
|
59
|
-
end
|
60
|
-
|
61
|
-
def current
|
62
|
-
get_nth_page(page)
|
63
|
-
end
|
64
|
-
|
65
|
-
def remove_current_page
|
66
|
-
if n_pages == 1
|
67
|
-
if @hidden.empty?
|
68
|
-
toplevel.quit_gracefully
|
69
|
-
else
|
70
|
-
append_page(@hidden.pop)
|
71
|
-
remove_current_page
|
72
|
-
end
|
73
|
-
else
|
74
|
-
remove(current)
|
75
|
-
current.term.grab_focus
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def toggle_visibility
|
80
|
-
@visible ? hide : show
|
81
|
-
end
|
82
|
-
|
83
|
-
def generate_tab_preview
|
84
|
-
_x, _y, w, h = current.term.allocation.to_a
|
85
|
-
surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32,
|
86
|
-
w, h)
|
87
|
-
cr = Cairo::Context.new(surface)
|
88
|
-
current.term.draw(cr)
|
89
|
-
pix = surface.to_pixbuf(:src_x => 0, :src_y => 0, :width => w, :height => h)
|
90
|
-
current.term.preview = pix if pix
|
91
|
-
end
|
92
|
-
|
93
|
-
def send_to_all_terminals(method_name, values)
|
94
|
-
each do |tab|
|
95
|
-
tab.term.send(method_name, *values)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def hide(index)
|
100
|
-
child = get_nth_page(index)
|
101
|
-
@hidden << child
|
102
|
-
remove_page(index)
|
103
|
-
end
|
104
|
-
|
105
|
-
def unhide(index)
|
106
|
-
append_page(@hidden.delete_at(index))
|
107
|
-
toplevel.current_tab.text = "#{current_page + 1}/#{n_pages}"
|
108
|
-
end
|
109
|
-
end
|
data/lib/searchbar.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# Copyright 2016 Cedric LE MOIGNE, cedlemo@gmx.com
|
2
|
-
# This file is part of Topinambour.
|
3
|
-
#
|
4
|
-
# Topinambour is free software: you can redistribute it and/or modify
|
5
|
-
# it under the terms of the GNU General Public License as published by
|
6
|
-
# the Free Software Foundation, either version 3 of the License, or
|
7
|
-
# any later version.
|
8
|
-
#
|
9
|
-
# Topinambour is distributed in the hope that it will be useful,
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
-
# GNU General Public License for more details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU General Public License
|
15
|
-
# along with Topinambour. If not, see <http://www.gnu.org/licenses/>.
|
16
|
-
|
17
|
-
class TopinambourSearchBar < Gtk::SearchBar
|
18
|
-
def initialize(window)
|
19
|
-
super()
|
20
|
-
|
21
|
-
generate_search_entry(window)
|
22
|
-
set_halign(:center)
|
23
|
-
set_valign(:start)
|
24
|
-
set_hexpand(false)
|
25
|
-
set_vexpand(true)
|
26
|
-
connect_entry(@entry)
|
27
|
-
set_show_close_button = true
|
28
|
-
add(@entry)
|
29
|
-
end
|
30
|
-
|
31
|
-
def generate_search_entry(window)
|
32
|
-
@entry = Gtk::SearchEntry.new
|
33
|
-
term = window.notebook.current.term
|
34
|
-
@entry.signal_connect "next-match" do |entry|
|
35
|
-
term.search_find_next if @regex
|
36
|
-
end
|
37
|
-
|
38
|
-
@entry.signal_connect("previous-match") do |entry|
|
39
|
-
term.search_find_previous if @regex
|
40
|
-
end
|
41
|
-
|
42
|
-
@entry.signal_connect "search-changed" do |entry|
|
43
|
-
pattern = entry.buffer.text
|
44
|
-
if pattern != ""
|
45
|
-
@regex = GLib::Regex.new(pattern)
|
46
|
-
term.search_set_gregex(@regex, @regex.match_flags)
|
47
|
-
term.search_find_next
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
data/lib/terminal_chooser.rb
DELETED
@@ -1,397 +0,0 @@
|
|
1
|
-
# Copyright 2017 Cedric LE MOIGNE, cedlemo@gmx.com
|
2
|
-
# This file is part of Topinambour.
|
3
|
-
#
|
4
|
-
# Topinambour is free software: you can redistribute it and/or modify
|
5
|
-
# it under the terms of the GNU General Public License as published by
|
6
|
-
# the Free Software Foundation, either version 3 of the License, or
|
7
|
-
# any later version.
|
8
|
-
#
|
9
|
-
# Topinambour is distributed in the hope that it will be useful,
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
-
# GNU General Public License for more details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU General Public License
|
15
|
-
# along with Topinambour. If not, see <http://www.gnu.org/licenses/>.
|
16
|
-
class TopinambourTermChooser < Gtk::ScrolledWindow
|
17
|
-
def initialize(window)
|
18
|
-
super(nil, nil)
|
19
|
-
@window = window
|
20
|
-
@notebook = @window.notebook
|
21
|
-
@notebook.generate_tab_preview
|
22
|
-
initialize_list_box
|
23
|
-
initialize_hidden_list_box
|
24
|
-
initialize_main_box
|
25
|
-
configure_window
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def configure_window
|
31
|
-
set_halign(:end)
|
32
|
-
set_valign(:center)
|
33
|
-
set_policy(:never, :automatic)
|
34
|
-
set_name("terminal_chooser")
|
35
|
-
add(@box)
|
36
|
-
set_size_request(-1, @notebook.current.term.allocation.to_a[3] - 8)
|
37
|
-
end
|
38
|
-
|
39
|
-
def initialize_main_box
|
40
|
-
@box = Gtk::Box.new(:vertical, 4)
|
41
|
-
@box.name = "topinambour-overview-box"
|
42
|
-
@box.pack_start(main_title, :expand => false, :fill => true, :padding => 6)
|
43
|
-
@box.pack_start(@listbox, :expand => true, :fill => true, :padding => 12)
|
44
|
-
@box.pack_start(box_title("Hidden terminals"),
|
45
|
-
:expand => false, :fill => true, :padding => 6)
|
46
|
-
@box.pack_start(@listbox_hidden, :expand => true, :fill => true,
|
47
|
-
:padding => 12)
|
48
|
-
end
|
49
|
-
|
50
|
-
def main_title
|
51
|
-
hbox = Gtk::Box.new(:horizontal, 6)
|
52
|
-
hbox.pack_start(box_title("Terminals"),
|
53
|
-
:expand => true, :fill => true, :padding => 6)
|
54
|
-
hbox.pack_start(box_close_button,
|
55
|
-
:expand => false, :fill => false, :padding => 6)
|
56
|
-
hbox
|
57
|
-
end
|
58
|
-
|
59
|
-
def box_title(label)
|
60
|
-
title = Gtk::Label.new("> #{label} :")
|
61
|
-
title.halign = :start
|
62
|
-
title
|
63
|
-
end
|
64
|
-
|
65
|
-
def box_close_button
|
66
|
-
button = Gtk::Button.new(:icon_name => "window-close-symbolic",
|
67
|
-
:size => :button)
|
68
|
-
button.relief = :none
|
69
|
-
button.signal_connect("clicked") { @window.exit_overlay_mode }
|
70
|
-
button
|
71
|
-
end
|
72
|
-
|
73
|
-
def initialize_list_box
|
74
|
-
@listbox = Gtk::ListBox.new
|
75
|
-
@listbox.margin = 12
|
76
|
-
@listbox.selection_mode = :single
|
77
|
-
fill_list_box
|
78
|
-
end
|
79
|
-
|
80
|
-
def initialize_hidden_list_box
|
81
|
-
@listbox_hidden = Gtk::ListBox.new
|
82
|
-
@listbox_hidden.placeholder = Gtk::Label.new("Hidden terminals")
|
83
|
-
@listbox_hidden.margin = 12
|
84
|
-
@listbox_hidden.show_all
|
85
|
-
@listbox_hidden.selection_mode = :single
|
86
|
-
fill_hidden_list_box
|
87
|
-
end
|
88
|
-
|
89
|
-
def fill_list_box
|
90
|
-
@listbox.signal_connect "row-selected" do |_list, row|
|
91
|
-
@notebook.current_page = row.nil? ? @notebook.children.size : row.index
|
92
|
-
end
|
93
|
-
|
94
|
-
@notebook.children.each_with_index do |child, i|
|
95
|
-
row = generate_list_box_row(child.term, i)
|
96
|
-
@listbox.insert(row, i)
|
97
|
-
row.close_button.signal_connect "clicked" do |widget|
|
98
|
-
close_button_action(widget)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
current_row = @listbox.get_row_at_index(@notebook.current_page)
|
102
|
-
@listbox.select_row(current_row)
|
103
|
-
current_row.grab_focus
|
104
|
-
end
|
105
|
-
|
106
|
-
def fill_hidden_list_box
|
107
|
-
@notebook.hidden.each_with_index do |child, i|
|
108
|
-
row = generate_hidden_list_box_row(child.term, i)
|
109
|
-
@listbox_hidden.insert(row, i)
|
110
|
-
row.close_button.signal_connect "clicked" do |widget|
|
111
|
-
close_button_action(widget)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def close_button_action(button)
|
117
|
-
row = button.parent.parent
|
118
|
-
listbox = row.parent
|
119
|
-
if listbox == @listbox
|
120
|
-
tab = @notebook.get_nth_page(row.index)
|
121
|
-
@notebook.n_pages == 1 ? @window.quit_gracefully : @notebook.remove(tab)
|
122
|
-
row.destroy
|
123
|
-
update_tabs_num_labels
|
124
|
-
elsif listbox == @listbox_hidden
|
125
|
-
@notebook.hidden.delete_at(row.index)
|
126
|
-
row.destroy
|
127
|
-
update_tabs_num_labels
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def generate_list_box_row(term, index)
|
132
|
-
list_box_row = ChooserListRow.new(term, index, @notebook)
|
133
|
-
generate_hide_button(list_box_row)
|
134
|
-
end
|
135
|
-
|
136
|
-
def generate_hidden_list_box_row(term, index)
|
137
|
-
list_box_row = ChooserListRow.new(term, index, @notebook)
|
138
|
-
generate_show_button(list_box_row)
|
139
|
-
end
|
140
|
-
|
141
|
-
def generate_show_button(list_box_row)
|
142
|
-
list_box_row.generate_new_action_button("Show")
|
143
|
-
list_box_row.action_button.signal_connect "clicked" do
|
144
|
-
tab_num = list_box_row.index
|
145
|
-
@window.notebook.unhide(tab_num)
|
146
|
-
list_box_row_bkp = generate_hide_button(list_box_row)
|
147
|
-
@listbox_hidden.remove(list_box_row)
|
148
|
-
@listbox.insert(list_box_row_bkp, -1)
|
149
|
-
update_tabs_num_labels
|
150
|
-
end
|
151
|
-
list_box_row
|
152
|
-
end
|
153
|
-
|
154
|
-
def generate_hide_button(list_box_row)
|
155
|
-
list_box_row.generate_new_action_button("Hide")
|
156
|
-
list_box_row.action_button.signal_connect "clicked" do
|
157
|
-
num = list_box_row.index
|
158
|
-
@notebook.n_pages == 1 ? @window.quit_gracefully : @notebook.hide(num)
|
159
|
-
list_box_row_bkp = generate_show_button(list_box_row)
|
160
|
-
@listbox.remove(list_box_row)
|
161
|
-
@listbox_hidden.insert(list_box_row_bkp, -1)
|
162
|
-
update_tabs_num_labels
|
163
|
-
end
|
164
|
-
list_box_row
|
165
|
-
end
|
166
|
-
|
167
|
-
def update_tabs_num_labels
|
168
|
-
@listbox.children.each_with_index do |row, i|
|
169
|
-
hbox = row.children[0]
|
170
|
-
label = hbox.children[0]
|
171
|
-
label.text = "tab. #{i + 1}"
|
172
|
-
end
|
173
|
-
update_hidden_tabs_num_labels
|
174
|
-
end
|
175
|
-
|
176
|
-
def update_hidden_tabs_num_labels
|
177
|
-
@listbox_hidden.children.each_with_index do |row, i|
|
178
|
-
hbox = row.children[0]
|
179
|
-
label = hbox.children[0]
|
180
|
-
label.text = "tab. #{i + 1}"
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
class ChooserListRow < Gtk::ListBoxRow
|
186
|
-
attr_reader :close_button
|
187
|
-
def initialize(term, index, notebook)
|
188
|
-
super()
|
189
|
-
@notebook = notebook
|
190
|
-
@hbox = Gtk::Box.new(:horizontal, 6)
|
191
|
-
fill_hbox_list_box_row(term, index)
|
192
|
-
generate_action_button
|
193
|
-
add(@hbox)
|
194
|
-
end
|
195
|
-
|
196
|
-
def action_button
|
197
|
-
@hbox.children[4]
|
198
|
-
end
|
199
|
-
|
200
|
-
def generate_new_action_button(label)
|
201
|
-
button = Gtk::Button.new(:label => label)
|
202
|
-
button.valign = :center
|
203
|
-
button.vexpand = false
|
204
|
-
@hbox.remove(action_button)
|
205
|
-
@hbox.pack_start(button,
|
206
|
-
:expand => false, :fill => false, :padding => 6)
|
207
|
-
show_all
|
208
|
-
end
|
209
|
-
|
210
|
-
private
|
211
|
-
|
212
|
-
def fill_hbox_list_box_row(term, index)
|
213
|
-
label = leaning_label(index)
|
214
|
-
@hbox.pack_start(label, :expand => false, :fill => false, :padding => 6)
|
215
|
-
@prev_button = generate_preview_button(term)
|
216
|
-
add_drag_and_drop_functionalities
|
217
|
-
@hbox.pack_start(@prev_button, :expand => false, :fill => false, :padding => 6)
|
218
|
-
label = EditableLabel.new(term)
|
219
|
-
@hbox.pack_start(label, :expand => true, :fill => false, :padding => 6)
|
220
|
-
generate_close_button
|
221
|
-
@hbox.pack_start(@close_button, :expand => false, :fill => false, :padding => 6)
|
222
|
-
@hbox
|
223
|
-
end
|
224
|
-
|
225
|
-
def leaning_label(index)
|
226
|
-
label = Gtk::Label.new("tab. #{index + 1}")
|
227
|
-
label.angle = 45
|
228
|
-
label
|
229
|
-
end
|
230
|
-
|
231
|
-
def generate_preview_button(child)
|
232
|
-
button = Gtk::Button.new
|
233
|
-
button.image = generate_preview_image(child.preview)
|
234
|
-
button.signal_connect("clicked") do
|
235
|
-
@notebook.current_page = index if parent.class == Gtk::ListBox
|
236
|
-
end
|
237
|
-
button
|
238
|
-
end
|
239
|
-
|
240
|
-
def generate_preview_image(pixbuf)
|
241
|
-
# scaled_pix = pixbuf.scale(150, 75, :bilinear)
|
242
|
-
scaled_pix = pixbuf.scale(200, 100, :bilinear)
|
243
|
-
img = Gtk::Image.new(:pixbuf => scaled_pix)
|
244
|
-
img.show
|
245
|
-
img
|
246
|
-
end
|
247
|
-
|
248
|
-
def add_drag_and_drop_functionalities
|
249
|
-
add_dnd_source(@prev_button)
|
250
|
-
add_dnd_destination(@prev_button)
|
251
|
-
end
|
252
|
-
|
253
|
-
def add_dnd_source(button)
|
254
|
-
button.drag_source_set(Gdk::ModifierType::BUTTON1_MASK |
|
255
|
-
Gdk::ModifierType::BUTTON2_MASK,
|
256
|
-
[["drag_term", Gtk::TargetFlags::SAME_APP, 12_345]],
|
257
|
-
Gdk::DragAction::COPY |
|
258
|
-
Gdk::DragAction::MOVE)
|
259
|
-
# Drag source signals
|
260
|
-
# drag-begin User starts a drag Set-up drag icon
|
261
|
-
# drag-data-get When drag data is requested by the destination Transfer
|
262
|
-
# drag data from source to destination
|
263
|
-
# drag-data-delete When a drag with the action Gdk.DragAction.MOVE is
|
264
|
-
# completed Delete data from the source to complete the "move"
|
265
|
-
# drag-end When the drag is complete Undo anything done in drag-begin
|
266
|
-
|
267
|
-
button.signal_connect "drag-begin" do |widget|
|
268
|
-
widget.drag_source_set_icon_pixbuf(widget.image.pixbuf)
|
269
|
-
end
|
270
|
-
|
271
|
-
button.signal_connect("drag-data-get") do |widget, _, selection_data, _, _|
|
272
|
-
index = widget.parent.parent.index
|
273
|
-
selection_data.set(Gdk::Selection::TYPE_INTEGER, index.to_s)
|
274
|
-
end
|
275
|
-
# button.signal_connect "drag-data-delete" do
|
276
|
-
# puts "drag data delete for #{inex}"
|
277
|
-
# end
|
278
|
-
# button.signal_connect "drag-end" do
|
279
|
-
# puts "drag end for #{index}"
|
280
|
-
# end
|
281
|
-
end
|
282
|
-
|
283
|
-
def add_dnd_destination(button)
|
284
|
-
button.drag_dest_set(Gtk::DestDefaults::MOTION |
|
285
|
-
Gtk::DestDefaults::HIGHLIGHT,
|
286
|
-
[["drag_term", :same_app, 12_345]],
|
287
|
-
Gdk::DragAction::COPY |
|
288
|
-
Gdk::DragAction::MOVE)
|
289
|
-
|
290
|
-
# Drag destination signals
|
291
|
-
# drag-motion Drag icon moves over a drop area Allow only certain areas to
|
292
|
-
# be dropped onto drag-drop Icon is dropped onto a drag area Allow only
|
293
|
-
# certain areas to be dropped onto drag-data-received When drag data is
|
294
|
-
# received by the destination Transfer drag data from source to destination
|
295
|
-
# button.signal_connect "drag-motion" do
|
296
|
-
# puts "drag motion for #{index}"
|
297
|
-
# end
|
298
|
-
button.signal_connect("drag-drop") do |widget, context, _x, _y, time|
|
299
|
-
widget.drag_get_data(context, context.targets[0], time)
|
300
|
-
end
|
301
|
-
|
302
|
-
button.signal_connect("drag-data-received") do |widget, context, _x, _y, selection_data|
|
303
|
-
index = widget.parent.parent.index
|
304
|
-
index_of_dragged_object = index
|
305
|
-
context.targets.each do |target|
|
306
|
-
next unless target.name == "drag_term" ||
|
307
|
-
selection_data.type == :type_integer
|
308
|
-
data_len = selection_data.data.size
|
309
|
-
index_of_dragged_object = selection_data.data.pack("C#{data_len}").to_i
|
310
|
-
end
|
311
|
-
if index_of_dragged_object != index
|
312
|
-
drag_image_and_reorder_terms(index_of_dragged_object, index)
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
def drag_image_and_reorder_terms(src_index, dest_index)
|
318
|
-
dragged = @notebook.get_nth_page(src_index)
|
319
|
-
@notebook.reorder_child(dragged, dest_index)
|
320
|
-
@notebook.children.each_with_index do |child, i|
|
321
|
-
list_box_row = parent.get_row_at_index(i)
|
322
|
-
row_h_box = list_box_row.children[0]
|
323
|
-
row_h_box.children[1].image = generate_preview_image(child.term.preview)
|
324
|
-
row_h_box.children[2].text = child.term.terminal_title
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
def generate_close_button
|
329
|
-
@close_button = Gtk::Button.new(:icon_name => "window-close-symbolic",
|
330
|
-
:size => :button)
|
331
|
-
@close_button.relief = :none
|
332
|
-
end
|
333
|
-
|
334
|
-
def generate_action_button
|
335
|
-
action_button = Gtk::Button.new(:label => "")
|
336
|
-
action_button.valign = :center
|
337
|
-
action_button.vexpand = false
|
338
|
-
@hbox.pack_start(action_button,
|
339
|
-
:expand => false, :fill => false, :padding => 6)
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
class EditableLabel < Gtk::Label
|
344
|
-
def initialize(term)
|
345
|
-
super(term.terminal_title)
|
346
|
-
set_halign(:start)
|
347
|
-
set_selectable(true)
|
348
|
-
signal_connect "button-release-event" do |w, e|
|
349
|
-
generate_label_popup(w, e, term)
|
350
|
-
end
|
351
|
-
label
|
352
|
-
end
|
353
|
-
|
354
|
-
def generate_label_popup(label, event, term)
|
355
|
-
initialize_entry_popup(label)
|
356
|
-
@popup = Gtk::Popover.new
|
357
|
-
add_label_popup_entry_activate_signal(label, term)
|
358
|
-
add_label_popup_entry_icon_release(label, term)
|
359
|
-
@popup.add(@entry)
|
360
|
-
set_popup_position(label, event)
|
361
|
-
end
|
362
|
-
|
363
|
-
def initialize_entry_popup(label)
|
364
|
-
@entry = Gtk::Entry.new
|
365
|
-
@entry.max_width_chars = 50
|
366
|
-
@entry.buffer.text = label.text
|
367
|
-
@entry.set_icon_from_icon_name(:secondary, "edit-clear-symbolic")
|
368
|
-
end
|
369
|
-
|
370
|
-
def add_label_popup_entry_icon_release(label, term)
|
371
|
-
@entry.signal_connect "icon-release" do |widget, position|
|
372
|
-
if position == :secondary
|
373
|
-
term.custom_title = nil
|
374
|
-
label.text = term.window_title
|
375
|
-
term.toplevel.current_label.text = label.text
|
376
|
-
widget.buffer.text = label.text
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
def add_label_popup_entry_activate_signal(label, term)
|
382
|
-
@entry.signal_connect "activate" do |widget|
|
383
|
-
label.text = widget.buffer.text
|
384
|
-
term.custom_title = widget.buffer.text
|
385
|
-
@popup.destroy
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
|
-
def set_popup_position(label, event)
|
390
|
-
x, y = event.window.coords_to_parent(event.x, event.y)
|
391
|
-
rect = Gdk::Rectangle.new(x - label.allocation.x, y - label.allocation.y,
|
392
|
-
1, 1)
|
393
|
-
@popup.pointing_to = rect
|
394
|
-
@popup.relative_to = label
|
395
|
-
@popup.show_all
|
396
|
-
end
|
397
|
-
end
|