topinambour 1.0.0

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