topinambour 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+