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,213 @@
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 TopinambourTermChooser < Gtk::ScrolledWindow
17
+ def initialize(window)
18
+ super(nil, nil)
19
+ @window = window
20
+ set_size_request(184, @window.notebook.current.allocation.to_a[3] - 8)
21
+ set_halign(:end)
22
+ set_valign(:center)
23
+ set_name("terminal_chooser")
24
+
25
+ generate_previews_pixbufs
26
+ generate_grid
27
+ fill_grid
28
+
29
+ @box = Gtk::Box.new(:vertical, 4)
30
+ @box.pack_start(@grid, :expand => true, :fill => true, :padding => 4)
31
+ add(@box)
32
+ end
33
+
34
+ private
35
+
36
+ def generate_grid
37
+ @grid = Gtk::Grid.new
38
+ @grid.valign = :start
39
+ @grid.halign = :center
40
+ @grid.row_spacing = 2
41
+ end
42
+
43
+ def fill_grid
44
+ @window.notebook.children.each_with_index do |child, i|
45
+ button = generate_preview_button(child, i)
46
+ @grid.attach(button, 0, i, 1, 1)
47
+ add_drag_and_drop_functionalities(button)
48
+ button = generate_close_tab_button
49
+ @grid.attach(button, 1, i, 1, 1)
50
+ end
51
+ @grid.attach(generate_separator, 0, @window.notebook.n_pages, 2, 1)
52
+ button = generate_quit_button
53
+ @grid.attach(button, 0, @window.notebook.n_pages + 1, 2, 1)
54
+ end
55
+
56
+ def generate_close_tab_button
57
+ button = Gtk::EventBox.new
58
+ button.tooltip_text = "Close Tab"
59
+ image = Gtk::Image.new(:icon_name => "window-close-symbolic", :size => :button)
60
+ button.add(image)
61
+ button.hexpand = false
62
+ button.vexpand = false
63
+ button.valign = :start
64
+ button.halign = :center
65
+ button.signal_connect "button_press_event" do
66
+ n = @grid.child_get_property(button, "top-attach")
67
+ tab = @window.notebook.get_nth_page(n)
68
+ if @window.notebook.n_pages == 1
69
+ @window.quit_gracefully
70
+ else
71
+ remove_tab(tab, n)
72
+ end
73
+ end
74
+ button
75
+ end
76
+
77
+ def remove_tab(tab, n)
78
+ @window.notebook.remove(tab)
79
+ @grid.remove_row(n)
80
+ last_tab = @window.notebook.n_pages - 1
81
+ update_preview_button_tooltip(n..last_tab)
82
+ end
83
+
84
+ def update_preview_button_tooltip(range)
85
+ (range).each do |j|
86
+ puts j
87
+ @grid.get_child_at(0, j).tooltip_text = j.to_s
88
+ end
89
+ end
90
+
91
+ def generate_preview_button(child, i)
92
+ button = Gtk::Button.new
93
+ button.add(generate_preview_image(child.preview))
94
+ button.set_tooltip_text(i.to_s)
95
+ button.signal_connect "clicked" do
96
+ @window.notebook.gen_preview = false
97
+ @window.notebook.set_current_page(i)
98
+ end
99
+ button
100
+ end
101
+
102
+ def generate_preview_image(pixbuf)
103
+ scaled_pix = pixbuf.scale(150, 75, Gdk::Pixbuf::INTERP_BILINEAR)
104
+ img = Gtk::Image.new(:pixbuf => scaled_pix)
105
+ img.show
106
+ img
107
+ end
108
+
109
+ def generate_separator
110
+ Gtk::Separator.new(:horizontal)
111
+ end
112
+
113
+ def generate_quit_button
114
+ button = Gtk::EventBox.new
115
+ button.tooltip_text = "Quit Topinambour"
116
+ image = Gtk::Image.new(:icon_name => "application-exit-symbolic", :size => :dialog)
117
+ button.add(image)
118
+ button.signal_connect "button_press_event" do
119
+ @window.quit_gracefully
120
+ end
121
+ button
122
+ end
123
+
124
+ def generate_previews_pixbufs
125
+ current_page = @window.notebook.page
126
+
127
+ if @window.notebook.children.size == 1
128
+ # If we have only one vte, just generate the preview
129
+ _x, _y, w, h = @window.notebook.current.allocation.to_a
130
+ @window.notebook.current.preview = @window.notebook.current.window.to_pixbuf(0, 0, w, h)
131
+ else
132
+ # If we have more terminals, just cycle through them
133
+ # the previews will be generated in the "switch-page" event of the notebook
134
+ begin
135
+ @window.notebook.cycle_next_page
136
+ end while @window.notebook.page == current_page
137
+ # Here I disable the preview generation in the notebook "switch-page" event
138
+ # before returning to the current page.
139
+ # This is a Hack, If I don't disable the preview, all the previews will be
140
+ # the same.
141
+ @window.notebook.gen_preview = false
142
+ @window.notebook.set_current_page(current_page)
143
+ end
144
+ end
145
+
146
+ def add_drag_and_drop_functionalities(button)
147
+ add_dnd_source(button)
148
+ add_dnd_destination(button)
149
+ end
150
+
151
+ def add_dnd_source(button)
152
+ button.drag_source_set(Gdk::ModifierType::BUTTON1_MASK |
153
+ Gdk::ModifierType::BUTTON2_MASK,
154
+ [["test", Gtk::TargetFlags::SAME_APP, 12_345]],
155
+ Gdk::DragAction::COPY |
156
+ Gdk::DragAction::MOVE)
157
+ button.drag_source_set_icon_name("grab")
158
+ # Drag source signals
159
+ # drag-begin User starts a drag Set-up drag icon
160
+ # drag-data-get When drag data is requested by the destination Transfer drag data from source to destination
161
+ # drag-data-delete When a drag with the action Gdk.DragAction.MOVE is completed Delete data from the source to complete the "move"
162
+ # drag-end When the drag is complete Undo anything done in drag-begin
163
+
164
+ # button.signal_connect "drag-begin" do
165
+ # puts "drag begin for #{index}"
166
+ # end
167
+ button.signal_connect("drag-data-get") do |_widget, _context, selection_data, _info, _time|
168
+ index = @grid.child_get_property(button, "top-attach")
169
+ selection_data.set(Gdk::Selection::TYPE_INTEGER, index.to_s)
170
+ end
171
+ # button.signal_connect "drag-data-delete" do
172
+ # puts "drag data delete for #{inex}"
173
+ # end
174
+ # button.signal_connect "drag-end" do
175
+ # puts "drag end for #{index}"
176
+ # end
177
+ end
178
+
179
+ def add_dnd_destination(button)
180
+ button.drag_dest_set(Gtk::DestDefaults::MOTION |
181
+ Gtk::DestDefaults::HIGHLIGHT,
182
+ [["test", :same_app, 12_345]],
183
+ Gdk::DragAction::COPY |
184
+ Gdk::DragAction::MOVE)
185
+
186
+ # Drag destination signals
187
+ # drag-motion Drag icon moves over a drop area Allow only certain areas to be dropped onto
188
+ # drag-drop Icon is dropped onto a drag area Allow only certain areas to be dropped onto
189
+ # drag-data-received When drag data is received by the destination Transfer drag data from source to destination
190
+ # button.signal_connect "drag-motion" do
191
+ # puts "drag motion for #{index}"
192
+ # end
193
+ button.signal_connect("drag-drop") do |widget, context, _x, _y, time|
194
+ widget.drag_get_data(context, context.targets[0], time)
195
+ end
196
+ button.signal_connect("drag-data-received") do |_widget, context, _x, _y, selection_data, _info, _time|
197
+ index = @grid.child_get_property(button, "top-attach")
198
+ index_of_dragged_object = index
199
+ context.targets.each do |target|
200
+ next unless target.name == "test" || selection_data.type == :type_integer
201
+ data_len = selection_data.data[1]
202
+ index_of_dragged_object = selection_data.data[0].pack("C#{data_len}").to_i
203
+ end
204
+ if index_of_dragged_object != index
205
+ dragged = @window.notebook.get_nth_page(index_of_dragged_object)
206
+ @window.notebook.reorder_child(dragged, index)
207
+ @window.notebook.children.each_with_index do |child, i|
208
+ @grid.get_child_at(0, i).image = generate_preview_image(child.preview)
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
data/lib/window.rb ADDED
@@ -0,0 +1,200 @@
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
+ class TopinambourWindow < Gtk::ApplicationWindow
18
+ extend TopinambourStyleProperties
19
+ attr_reader :notebook, :bar, :overlay, :current_label, :current_tab, :css_editor_style
20
+
21
+ type_register
22
+ install_style("string", "shell", "/usr/bin/fish")
23
+ install_style("int", "width", [-1, 2000, 1000])
24
+ install_style("int", "height", [-1, 2000, 500])
25
+ install_style("string", "css-editor-style", "classic")
26
+
27
+ def initialize(application)
28
+ super(:application => application)
29
+ set_icon_from_file("#{DATA_PATH}/germinal-icon.png")
30
+ load_css_properties
31
+ set_position(:center)
32
+ create_header_bar
33
+ create_containers
34
+ show_all
35
+ signal_connect "key-press-event" do |widget, event|
36
+ TopinambourShortcuts.handle_key_press(widget, event)
37
+ end
38
+ end
39
+
40
+ def add_terminal(cmd = @shell)
41
+ exit_overlay_mode
42
+ working_dir = nil
43
+ # Check if current tab is a TopinambourTerminal (can be TopinambourCssEditor)
44
+ if @notebook.current.class == TopinambourTerminal && @notebook.n_pages > 0
45
+ working_dir = @notebook.current.pid_dir
46
+ end
47
+
48
+ terminal = TopinambourTerminal.new(cmd, working_dir)
49
+ terminal.show
50
+ terminal.signal_connect "size-allocate" do |widget|
51
+ w = widget.column_count
52
+ h = widget.row_count
53
+ size_infos = "#{w}x#{h}"
54
+ if @overlay.children.size == 1
55
+ add_overlay(TopinambourResizeMessage.new(size_infos))
56
+ add_resize_timeout
57
+ elsif @overlay.children[1].class == TopinambourResizeMessage
58
+ GLib::Source.remove(@resize_timeout) if @resize_timeout
59
+ @overlay.children[1].text = size_infos
60
+ add_resize_timeout
61
+ end
62
+ end
63
+ @notebook.append_page(terminal, Gtk::Label.new)
64
+ @notebook.set_tab_reorderable(terminal, true)
65
+ @notebook.set_page(@notebook.n_pages - 1)
66
+ end
67
+
68
+ def quit_gracefully
69
+ exit_overlay_mode
70
+ @notebook.remove_all_pages
71
+ application.quit
72
+ end
73
+
74
+ def show_color_selector
75
+ toggle_overlay(TopinambourColorSelector) if @notebook.current.class == TopinambourTerminal
76
+ end
77
+
78
+ def show_prev_tab
79
+ exit_overlay_mode
80
+ @notebook.cycle_prev_page
81
+ end
82
+
83
+ def show_next_tab
84
+ exit_overlay_mode
85
+ @notebook.cycle_next_page
86
+ end
87
+
88
+ def show_terminal_chooser
89
+ toggle_overlay(TopinambourTermChooser)
90
+ end
91
+
92
+ def show_font_selector
93
+ toggle_overlay(TopinambourFontSelector) if @notebook.current.class == TopinambourTerminal
94
+ end
95
+
96
+ def show_css_editor
97
+ css_editor = TopinambourCssEditor.new(self)
98
+ @notebook.append_page(css_editor, Gtk::Label.new)
99
+ @notebook.set_page(@notebook.n_pages - 1)
100
+ end
101
+
102
+ def exit_overlay_mode
103
+ @overlay.children[1].destroy if in_overlay_mode?
104
+ end
105
+
106
+ def load_css_properties
107
+ @default_width = style_get_property("width")
108
+ @default_height = style_get_property("height")
109
+ set_default_size(@default_width, @default_height)
110
+ set_size_request(@default_width, @default_height)
111
+ @shell = style_get_property("shell")
112
+ @css_editor_style = style_get_property("css-editor-style")
113
+ end
114
+
115
+ def display_about
116
+ Gtk::AboutDialog.show(self,
117
+ "authors" => ["Cédric Le Moigne <cedlemo@gmx.com>"],
118
+ "comments" => "Terminal Emulator based on the ruby bindings of Gtk3 and Vte3",
119
+ "copyright" => "Copyright (C) 2015-2016 Cédric Le Moigne",
120
+ "license" => "This program is licenced under the licence GPL-3.0 and later.",
121
+ "logo" => Gdk::Pixbuf.new("#{DATA_PATH}/germinal-icon-128.png"),
122
+ "program_name" => "Topinambour",
123
+ "version" => "1.2.3",
124
+ "website" => "https://github.com/cedlemo/germinal",
125
+ "website_label" => "Topinambour github repository"
126
+ )
127
+ end
128
+
129
+ def close_current_tab
130
+ exit_overlay_mode
131
+ @notebook.remove_current_page
132
+ end
133
+
134
+ def in_overlay_mode?
135
+ @overlay.children.size > 1 ? true : false
136
+ end
137
+
138
+ private
139
+
140
+ def add_overlay(widget)
141
+ @overlay.add_overlay(widget)
142
+ @overlay.set_overlay_pass_through(widget, true)
143
+ end
144
+
145
+ def create_containers
146
+ @notebook = TopinambourNotebook.new
147
+ @overlay = Gtk::Overlay.new
148
+ @overlay.add(@notebook)
149
+ add(@overlay)
150
+ end
151
+
152
+ def create_header_bar
153
+ @bar = TopinambourHeaderBar.generate_header_bar(self)
154
+ @current_label = TopinambourHeaderBar.generate_current_label(self)
155
+ @current_tab = TopinambourHeaderBar.generate_current_tab
156
+ add_buttons_at_begining
157
+ add_buttons_at_end
158
+ end
159
+
160
+ def add_buttons_at_begining
161
+ button = TopinambourHeaderBar.generate_prev_button(self)
162
+ @bar.pack_start(button)
163
+ @bar.pack_start(@current_tab)
164
+ button = TopinambourHeaderBar.generate_next_button(self)
165
+ @bar.pack_start(button)
166
+ @bar.pack_start(@current_label)
167
+ button = TopinambourHeaderBar.generate_new_tab_button(self)
168
+ @bar.pack_start(button)
169
+ end
170
+
171
+ def add_buttons_at_end
172
+ button = TopinambourHeaderBar.generate_open_menu_button(self)
173
+ @bar.pack_end(button)
174
+ button = TopinambourHeaderBar.generate_font_sel_button(self)
175
+ @bar.pack_end(button)
176
+ button = TopinambourHeaderBar.generate_color_sel_button(self)
177
+ @bar.pack_end(button)
178
+ button = TopinambourHeaderBar.generate_term_overv_button(self)
179
+ @bar.pack_end(button)
180
+ end
181
+
182
+ def add_resize_timeout
183
+ @resize_timeout = GLib::Timeout.add_seconds(2) do
184
+ second_child = @overlay.children[1] || nil
185
+ if second_child && second_child.class == TopinambourResizeMessage
186
+ @overlay.children[1].hide
187
+ end
188
+ end
189
+ end
190
+
191
+ def toggle_overlay(klass)
192
+ if in_overlay_mode? && @overlay.children[1].class == klass
193
+ exit_overlay_mode
194
+ else
195
+ exit_overlay_mode
196
+ add_overlay(klass.new(self))
197
+ @overlay.children[1].show_all
198
+ end
199
+ end
200
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: topinambour
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Cédric LE MOIGNE
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: vte3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.0.7
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.7
33
+ - !ruby/object:Gem::Dependency
34
+ name: gtksourceview3
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 3.0.7
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 3.0.7
53
+ - !ruby/object:Gem::Dependency
54
+ name: sass
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.4'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 3.4.18
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.4'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 3.4.18
73
+ description: Terminal Emulator based on the libs vte3 and gtk3 from the ruby-gnome2
74
+ project
75
+ email: cedlemo@gmx.com
76
+ executables:
77
+ - topinambour
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - COPYING
82
+ - README.md
83
+ - bin/topinambour
84
+ - data/app-menu.ui
85
+ - data/application-exit-symbolic.svg
86
+ - data/color-select-symbolic.svg
87
+ - data/emblem-photos-symbolic.svg
88
+ - data/font-select-symbolic.svg
89
+ - data/germinal-icon-128.png
90
+ - data/germinal-icon-16.png
91
+ - data/germinal-icon-32.png
92
+ - data/germinal-icon-64.png
93
+ - data/germinal-icon.png
94
+ - data/germinal.css
95
+ - data/germinal.gresource.xml
96
+ - data/pan-end-symbolic.svg
97
+ - data/pan-start-symbolic.svg
98
+ - data/tab-new-symbolic.svg
99
+ - data/terminal-menu.ui
100
+ - data/window-close-symbolic.svg
101
+ - data/window-menu.ui
102
+ - data/window.ui
103
+ - lib/actions.rb
104
+ - lib/application.rb
105
+ - lib/color_selector.rb
106
+ - lib/css_editor.rb
107
+ - lib/css_handler.rb
108
+ - lib/font_selector.rb
109
+ - lib/headerbar.rb
110
+ - lib/notebook.rb
111
+ - lib/resize_message.rb
112
+ - lib/shortcuts.rb
113
+ - lib/style_properties.rb
114
+ - lib/terminal.rb
115
+ - lib/terminal_chooser.rb
116
+ - lib/window.rb
117
+ homepage: https://github.com/cedlemo/topinambour
118
+ licenses:
119
+ - GPL-3.0
120
+ metadata: {}
121
+ post_install_message: Have fun with topinambour
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.5.1
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Ruby-gnome2 Terminal emulator
141
+ test_files: []
142
+ has_rdoc: