topinambour 1.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.
@@ -0,0 +1,59 @@
1
+ # Copyright 2015-2016 Cédric 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 TopinambourFontSelector < Gtk::Box
17
+ attr_reader :font
18
+ def initialize(window)
19
+ @window = window
20
+ @font = @window.notebook.current.font
21
+ super(:horizontal, 0)
22
+
23
+ reset_button = Gtk::Button.new(:label => "Reset")
24
+ reset_button.signal_connect "clicked" do
25
+ font_desc = Pango::FontDescription.new(@font)
26
+ @window.notebook.current.set_font(font_desc)
27
+ end
28
+ pack_start(reset_button, :expand => false, :fill => false, :padding => 0)
29
+
30
+ font_button = Gtk::FontButton.new
31
+ font_button.set_font(@font)
32
+ font_button.set_show_style(true)
33
+ font_button.set_show_size(true)
34
+ font_button.set_use_font(true)
35
+ font_button.set_use_size(false)
36
+ font_button.signal_connect "font-set" do
37
+ font_desc = Pango::FontDescription.new(font_button.font_name)
38
+ @window.notebook.current.set_font(font_desc)
39
+ end
40
+ pack_start(font_button, :expand => false, :fill => false, :padding => 0)
41
+
42
+ save_button = Gtk::Button.new(:label => "Save")
43
+ save_button.signal_connect "clicked" do
44
+ new_props = {}
45
+ font = @window.notebook.current.font
46
+ new_props["-TopinambourTerminal-font"] = font.to_s
47
+ toplevel.application.update_css(new_props)
48
+ toplevel.notebook.each do |tab|
49
+ tab.set_font(font) if tab.class == TopinambourTerminal
50
+ end
51
+ toplevel.exit_overlay_mode
52
+ end
53
+ pack_start(save_button, :expand => false, :fill => false, :padding => 0)
54
+ set_name("font_selector")
55
+ show_all
56
+ set_halign(:center)
57
+ set_valign(:end)
58
+ end
59
+ end
data/lib/headerbar.rb ADDED
@@ -0,0 +1,127 @@
1
+ # Copyright 2016 Cédric 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
+ module TopinambourHeaderBar
18
+ def self.generate_header_bar(window)
19
+ bar = Gtk::HeaderBar.new
20
+ bar.title = "Topinambour"
21
+ bar.has_subtitle = false
22
+ bar.show_close_button = true
23
+ window.set_titlebar(bar)
24
+ bar
25
+ end
26
+
27
+ def self.generate_current_label_tooltips(label)
28
+ label.tooltip_text = <<-TOOLTIP
29
+ Change the name of the tab and hit
30
+ enter in order to validate
31
+ TOOLTIP
32
+ label.set_icon_tooltip_text(:secondary, <<-SECTOOLTIP)
33
+ Reset your changes and use the
34
+ default label for the current tab
35
+ SECTOOLTIP
36
+ end
37
+
38
+ def self.generate_current_label_signals(label, window)
39
+ label.signal_connect "activate" do |entry|
40
+ window.notebook.current.tab_label = entry.text
41
+ end
42
+
43
+ label.signal_connect "icon-release" do |entry, position|
44
+ if position == :secondary
45
+ window.notebook.current.tab_label = nil
46
+ entry.text = window.notebook.current.window_title
47
+ end
48
+ end
49
+ end
50
+
51
+ def self.generate_current_label(window)
52
+ label = Gtk::Entry.new
53
+ label.has_frame = false
54
+ label.width_chars = 35
55
+ label.set_icon_from_icon_name(:secondary, "edit-clear")
56
+
57
+ generate_current_label_tooltips(label)
58
+ generate_current_label_signals(label, window)
59
+ label
60
+ end
61
+
62
+ def self.generate_prev_button(window)
63
+ gen_icon_button("pan-start-symbolic", "prev") do
64
+ window.show_prev_tab
65
+ end
66
+ end
67
+
68
+ def self.generate_current_tab
69
+ Gtk::Label.new("1/1")
70
+ end
71
+
72
+ def self.generate_next_button(window)
73
+ gen_icon_button("pan-end-symbolic", "next") do
74
+ window.show_next_tab
75
+ end
76
+ end
77
+
78
+ def self.generate_new_tab_button(window)
79
+ gen_icon_button("tab-new-symbolic", "New terminal") do
80
+ window.add_terminal
81
+ end
82
+ end
83
+
84
+ def self.generate_open_menu_button(window)
85
+ gen_icon_button("open-menu-symbolic", "Main Menu") do |button|
86
+ builder = Gtk::Builder.new(:resource => "/com/github/cedlemo/germinal/window-menu.ui")
87
+ menu = Gtk::Menu.new(builder["winmenu"])
88
+ menu.attach_to_widget(button)
89
+ menu.children[0].signal_connect("activate") { window.show_css_editor }
90
+
91
+ menu.show_all
92
+ event = Gtk.current_event
93
+ menu.popup(nil, nil, event.button, event.time)
94
+ end
95
+ end
96
+
97
+ def self.generate_font_sel_button(window)
98
+ gen_icon_button("font-select-symbolic", "Set font") do
99
+ window.show_font_selector
100
+ end
101
+ end
102
+
103
+ def self.generate_color_sel_button(window)
104
+ gen_icon_button("color-select-symbolic", "Set colors") do
105
+ window.show_color_selector
106
+ end
107
+ end
108
+
109
+ def self.generate_term_overv_button(window)
110
+ gen_icon_button("emblem-photos-symbolic", "Terminals overview") do
111
+ window.show_terminal_chooser
112
+ end
113
+ end
114
+
115
+ def self.gen_icon_button(icon_name, tooltip)
116
+ button = Gtk::Button.new
117
+ image = Gtk::Image.new(:icon_name => icon_name, :size => :button)
118
+ button.add(image)
119
+ button.tooltip_text = tooltip
120
+ if block_given?
121
+ button.signal_connect "clicked" do |widget|
122
+ yield(widget)
123
+ end
124
+ end
125
+ button
126
+ end
127
+ end
data/lib/notebook.rb ADDED
@@ -0,0 +1,85 @@
1
+ # Copyright 2015-2016 Cédric 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
18
+ attr_accessor :gen_preview
19
+ def initialize
20
+ super()
21
+ @gen_preview = true
22
+ signal_connect "hide" do
23
+ @visible = false
24
+ end
25
+ signal_connect "show" do
26
+ @visible = true
27
+ end
28
+
29
+ signal_connect "switch-page" do |_widget, next_page, next_page_num|
30
+ toplevel.current_label.text = next_page.tab_label || get_tab_label(next_page).text
31
+ toplevel.current_tab.text = "#{next_page_num + 1}/#{n_pages}"
32
+
33
+ if page >= 0 && @gen_preview
34
+ current.queue_draw
35
+ _x, _y, w, h = current.allocation.to_a
36
+ pix = current.window.to_pixbuf(0, 0, w, h)
37
+ current.preview = pix if pix
38
+ elsif !@gen_preview
39
+ @gen_preview = true
40
+ end
41
+ end
42
+
43
+ signal_connect "page-reordered" do
44
+ toplevel.current_tab.text = "#{page + 1}/#{n_pages}"
45
+ end
46
+
47
+ signal_connect "page-removed" do
48
+ toplevel.current_tab.text = "#{page + 1}/#{n_pages}" if toplevel.class == TopinambourWindow
49
+ end
50
+
51
+ set_show_tabs(false)
52
+ end
53
+
54
+ def remove_all_pages
55
+ each do |widget|
56
+ index = page_num(widget)
57
+ remove_page(index)
58
+ end
59
+ end
60
+
61
+ def cycle_next_page
62
+ page < (n_pages - 1) ? next_page : set_page(0)
63
+ end
64
+
65
+ def cycle_prev_page
66
+ page > 0 ? prev_page : set_page(n_pages - 1)
67
+ end
68
+
69
+ def current
70
+ get_nth_page(page)
71
+ end
72
+
73
+ def remove_current_page
74
+ if n_pages == 1
75
+ toplevel.quit_gracefully
76
+ else
77
+ remove(current)
78
+ current.grab_focus
79
+ end
80
+ end
81
+
82
+ def toggle_visibility
83
+ @visible ? hide : show
84
+ end
85
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright 2015-2016 Cédric 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 TopinambourResizeMessage < Gtk::Box
17
+ def initialize(text)
18
+ super(:vertical)
19
+ text ||= ""
20
+ add(Gtk::Label.new(text))
21
+ set_halign(:end)
22
+ set_valign(:end)
23
+ set_border_width(4)
24
+ show_all
25
+ set_name("resize_box")
26
+ end
27
+
28
+ def text=(text)
29
+ children[0].text = text
30
+ show_all
31
+ end
32
+ end
data/lib/shortcuts.rb ADDED
@@ -0,0 +1,76 @@
1
+ # Copyright 2016 Cédric 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
+ module TopinambourShortcuts
18
+ def self.ctrl_shift?(event)
19
+ (event.state & (Gdk::ModifierType::CONTROL_MASK |
20
+ Gdk::ModifierType::SHIFT_MASK)) ==
21
+ (Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::SHIFT_MASK)
22
+ end
23
+
24
+ def self.handle_simple(keyval, window)
25
+ case keyval
26
+ when Gdk::Keyval::KEY_Escape # escape from overlay mode
27
+ if window.in_overlay_mode?
28
+ window.exit_overlay_mode
29
+ window.notebook.current.grab_focus
30
+ true
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.handle_ctrl_shift(keyval, window)
36
+ case keyval
37
+ when Gdk::Keyval::KEY_W # close the current tab
38
+ window.close_current_tab
39
+ true
40
+ when Gdk::Keyval::KEY_Q # Quit
41
+ window.quit_gracefully
42
+ true
43
+ when Gdk::Keyval::KEY_T # New tab
44
+ window.add_terminal
45
+ true
46
+ when Gdk::Keyval::KEY_C
47
+ window.show_color_selector
48
+ true
49
+ when Gdk::Keyval::KEY_F
50
+ window.show_font_selector
51
+ true
52
+ when Gdk::Keyval::KEY_Left # previous tab
53
+ window.show_prev_tab
54
+ true
55
+ when Gdk::Keyval::KEY_Right # next tab
56
+ window.show_next_tab
57
+ true
58
+ when Gdk::Keyval::KEY_O # next tab
59
+ window.show_terminal_chooser
60
+ true
61
+ when Gdk::Keyval::KEY_E
62
+ window.show_css_editor
63
+ true
64
+ end
65
+ end
66
+
67
+ def self.handle_key_press(window, event)
68
+ keyval = event.keyval
69
+ #puts "#{Gdk::Keyval.to_name(keyval)} = #{keyval}"
70
+ if ctrl_shift?(event)
71
+ handle_ctrl_shift(keyval, window)
72
+ else
73
+ handle_simple(keyval, window)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright 2016 Cédric 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
+ module TopinambourStyleProperties
18
+ def generate_string_rw_property(name, args)
19
+ GLib::Param::String.new(name.downcase,
20
+ name.capitalize,
21
+ name.upcase,
22
+ args,
23
+ GLib::Param::READABLE |
24
+ GLib::Param::WRITABLE)
25
+ end
26
+
27
+ def generate_int_rw_property(name, args)
28
+ GLib::Param::Int.new(name.downcase,
29
+ name.capitalize,
30
+ name.upcase,
31
+ *args,
32
+ GLib::Param::READABLE |
33
+ GLib::Param::WRITABLE)
34
+ end
35
+
36
+ def generate_boxed_rw_property(name, args)
37
+ GLib::Param::Boxed.new(name.downcase,
38
+ name.capitalize,
39
+ name.upcase,
40
+ args,
41
+ GLib::Param::READABLE |
42
+ GLib::Param::WRITABLE)
43
+ end
44
+
45
+ def generate_rw_property(type, name, args)
46
+ type = type.to_s.downcase
47
+ method_name = "generate_#{type}_rw_property"
48
+ return false unless methods.include?(method_name.to_sym)
49
+ method(method_name.to_sym).call(name, args)
50
+ end
51
+
52
+ def install_style(type, name, args)
53
+ property = generate_rw_property(type, name, args)
54
+ install_style_property(property) if property
55
+ end
56
+ end
data/lib/terminal.rb ADDED
@@ -0,0 +1,148 @@
1
+ # Copyright 2015-2016 Cédric 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
+ TERMINAL_COLOR_NAMES = [:foreground, :background, :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white,
18
+ :brightblack, :brightred, :brightgreen, :brightyellow, :brightblue, :brightmagenta, :brightcyan, :brightwhite]
19
+ DEFAULT_TERMINAL_COLORS = %w(#aeafad #323232 #000000 #b9214f #A6E22E #ff9800 #3399ff #8e33ff #06a2dc
20
+ #B0B0B0 #5D5D5D #ff5c8d #CDEE69 #ffff00 #9CD9F0 #FBB1F9 #77DFD8 #F7F7F7)
21
+ DEFAULT_TERMINAL_FONT = "Monospace 11"
22
+ ##
23
+ # The default vte terminal customized
24
+ class TopinambourTerminal < Vte::Terminal
25
+ extend TopinambourStyleProperties
26
+ attr_reader :pid, :menu
27
+ attr_accessor :preview, :colors, :tab_label
28
+ type_register
29
+ TERMINAL_COLOR_NAMES.each_with_index do |c|
30
+ name = c.to_s
31
+ self.install_style("boxed",
32
+ name,
33
+ GLib::Type["GdkRGBA"])
34
+ end
35
+ self.install_style("boxed",
36
+ "font",
37
+ GLib::Type["PangoFontDescription"])
38
+
39
+ ##
40
+ # Create a new TopinambourTerminal instance that runs command_string
41
+ def initialize(command_string, working_dir = nil)
42
+ super()
43
+ # TODO: make a begin/rescue like in glib2-2.2.4/sample/shell.rb
44
+ command_array = GLib::Shell.parse(command_string)
45
+ @pid = spawn(:argv => command_array,
46
+ :working_directory => working_dir,
47
+ :spawn_flags => GLib::Spawn::SEARCH_PATH)
48
+
49
+ signal_connect "child-exited" do |widget|
50
+ notebook = widget.parent
51
+ current_page = notebook.page_num(widget)
52
+ if notebook.n_pages > 1
53
+ notebook.remove_page(current_page)
54
+ notebook.get_nth_page(notebook.page).grab_focus
55
+ else
56
+ notebook.remove_page(current_page)
57
+ notebook.toplevel.application.quit
58
+ end
59
+ end
60
+
61
+ signal_connect "window-title-changed" do |widget|
62
+ if parent && parent.current == self
63
+ current_label = parent.get_tab_label(widget)
64
+ if @tab_label.class == String
65
+ current_label.text = @tab_label
66
+ else
67
+ current_label.text = window_title
68
+ parent.toplevel.current_label.text = window_title
69
+ end
70
+ end
71
+ end
72
+
73
+ builder = Gtk::Builder.new(:resource => "/com/github/cedlemo/germinal/terminal-menu.ui")
74
+ @menu = Gtk::Popover.new(self, builder["termmenu"])
75
+
76
+ signal_connect "button-press-event" do |widget, event|
77
+ if event.type == Gdk::EventType::BUTTON_PRESS &&
78
+ event.button == Gdk::BUTTON_SECONDARY
79
+
80
+ x, y = event.window.coords_to_parent(event.x,
81
+ event.y)
82
+ rect = Gdk::Rectangle.new(x - allocation.x,
83
+ y - allocation.y,
84
+ 1,
85
+ 1)
86
+ widget.menu.set_pointing_to(rect)
87
+ widget.menu.show
88
+ true
89
+ else
90
+ false
91
+ end
92
+ end
93
+ configure
94
+ end
95
+
96
+ def pid_dir
97
+ File.readlink("/proc/#{@pid}/cwd")
98
+ end
99
+
100
+ def get_css_colors
101
+ background = nil
102
+ foreground = nil
103
+ colors = []
104
+ background = parse_css_color(TERMINAL_COLOR_NAMES[0].to_s)
105
+ foreground = parse_css_color(TERMINAL_COLOR_NAMES[1].to_s)
106
+ TERMINAL_COLOR_NAMES[2..-1].each do |c|
107
+ color = parse_css_color(c.to_s)
108
+ colors << color
109
+ end
110
+ [background, foreground] + colors
111
+ end
112
+
113
+ def get_css_font
114
+ font = style_get_property("font")
115
+ unless font
116
+ font = Pango::FontDescription.new(DEFAULT_TERMINAL_FONT)
117
+ end
118
+ font
119
+ end
120
+
121
+ def apply_colors
122
+ set_colors(@colors[0], @colors[1], @colors[2..-1])
123
+ end
124
+
125
+ private
126
+
127
+ def parse_css_color(color_name)
128
+ default_color = Gdk::RGBA.parse(DEFAULT_TERMINAL_COLORS[TERMINAL_COLOR_NAMES.index(color_name.to_sym)])
129
+ color_from_css = style_get_property(color_name)
130
+ color = color_from_css ? color_from_css : default_color
131
+ color
132
+ end
133
+
134
+ def configure
135
+ set_rewrap_on_resize(true)
136
+ set_scrollback_lines(-1)
137
+ @colors = get_css_colors
138
+ set_font(get_css_font)
139
+ apply_colors
140
+ #add_matches
141
+ end
142
+
143
+ def add_matches
144
+ puts methods.grep(/rege/)
145
+ match_add_gregex("cedlemo")
146
+ end
147
+ end
148
+