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.
- checksums.yaml +7 -0
- data/COPYING +674 -0
- data/README.md +177 -0
- data/bin/topinambour +62 -0
- data/data/app-menu.ui +23 -0
- data/data/application-exit-symbolic.svg +32 -0
- data/data/color-select-symbolic.svg +34 -0
- data/data/emblem-photos-symbolic.svg +33 -0
- data/data/font-select-symbolic.svg +33 -0
- data/data/germinal-icon-128.png +0 -0
- data/data/germinal-icon-16.png +0 -0
- data/data/germinal-icon-32.png +0 -0
- data/data/germinal-icon-64.png +0 -0
- data/data/germinal-icon.png +0 -0
- data/data/germinal.css +56 -0
- data/data/germinal.gresource.xml +28 -0
- data/data/pan-end-symbolic.svg +31 -0
- data/data/pan-start-symbolic.svg +31 -0
- data/data/tab-new-symbolic.svg +34 -0
- data/data/terminal-menu.ui +18 -0
- data/data/window-close-symbolic.svg +28 -0
- data/data/window-menu.ui +26 -0
- data/data/window.ui +58 -0
- data/lib/actions.rb +73 -0
- data/lib/application.rb +131 -0
- data/lib/color_selector.rb +94 -0
- data/lib/css_editor.rb +159 -0
- data/lib/css_handler.rb +47 -0
- data/lib/font_selector.rb +59 -0
- data/lib/headerbar.rb +127 -0
- data/lib/notebook.rb +85 -0
- data/lib/resize_message.rb +32 -0
- data/lib/shortcuts.rb +76 -0
- data/lib/style_properties.rb +56 -0
- data/lib/terminal.rb +148 -0
- data/lib/terminal_chooser.rb +213 -0
- data/lib/window.rb +200 -0
- metadata +142 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='tab-new-symbolic.svg' height='16' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.4 r9939' version='1.1' width='16.000004' xmlns='http://www.w3.org/2000/svg'>
|
5
|
+
<metadata id='metadata90'>
|
6
|
+
<rdf:RDF>
|
7
|
+
<cc:Work rdf:about=''>
|
8
|
+
<dc:format>image/svg+xml</dc:format>
|
9
|
+
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
|
10
|
+
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
11
|
+
</cc:Work>
|
12
|
+
</rdf:RDF>
|
13
|
+
</metadata>
|
14
|
+
<sodipodi:namedview inkscape:bbox-nodes='false' inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer12' inkscape:cx='61.6001' inkscape:cy='484.11648' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#3a3b39' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-nodes='true' inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='702' inkscape:window-maximized='1' inkscape:window-width='1366' inkscape:window-x='0' inkscape:window-y='27' inkscape:zoom='1'>
|
15
|
+
<inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='121px' originy='589px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
|
16
|
+
<inkscape:grid color='#000000' empcolor='#000000' empopacity='0' empspacing='4' enabled='true' id='grid5968' opacity='0.1254902' originx='121px' originy='589px' snapvisiblegridlinesonly='true' spacingx='0.5px' spacingy='0.5px' type='xygrid' visible='true'/>
|
17
|
+
</sodipodi:namedview>
|
18
|
+
<title id='title9167'>Gnome Symbolic Icon Theme</title>
|
19
|
+
<defs id='defs7386'/>
|
20
|
+
<g inkscape:groupmode='layer' id='layer9' inkscape:label='status' style='display:inline' transform='translate(-120.0002,-806)'/>
|
21
|
+
<g inkscape:groupmode='layer' id='layer10' inkscape:label='devices' transform='translate(-120.0002,-806)'/>
|
22
|
+
<g inkscape:groupmode='layer' id='layer11' inkscape:label='apps' transform='translate(-120.0002,-806)'/>
|
23
|
+
<g inkscape:groupmode='layer' id='layer13' inkscape:label='places' transform='translate(-120.0002,-806)'/>
|
24
|
+
<g inkscape:groupmode='layer' id='layer14' inkscape:label='mimetypes' transform='translate(-120.0002,-806)'/>
|
25
|
+
<g inkscape:groupmode='layer' id='layer15' inkscape:label='emblems' style='display:inline' transform='translate(-120.0002,-806)'/>
|
26
|
+
<g inkscape:groupmode='layer' id='g71291' inkscape:label='emotes' style='display:inline' transform='translate(-120.0002,-806)'/>
|
27
|
+
<g inkscape:groupmode='layer' id='g4953' inkscape:label='categories' style='display:inline' transform='translate(-120.0002,-806)'/>
|
28
|
+
<g inkscape:groupmode='layer' id='layer12' inkscape:label='actions' style='display:inline' transform='translate(-120.0002,-806)'>
|
29
|
+
<path inkscape:connector-curvature='0' d='m 123.0002,808 c 0,0 -2,0 -2,2 l 0,8 -1,0 0,2 3,0 0,-10 10,0 0,10 3,0 0,-2 -1,0 0,-8 c 0,0 0,-2 -2,-2 z' id='rect11749-5-0-1-3' sodipodi:nodetypes='cscccccccccccsc' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible'/>
|
30
|
+
|
31
|
+
<rect height='2' id='rect3764' style='fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none' width='5.99998' x='125.00022' y='814'/>
|
32
|
+
<rect height='2' id='rect3766' style='fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none' transform='matrix(0,1,-1,0,0,0)' width='6' x='812' y='-129.00021'/>
|
33
|
+
</g>
|
34
|
+
</svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<interface>
|
3
|
+
<!-- interface-requires gtk+ 3.0 -->
|
4
|
+
<menu id="termmenu">
|
5
|
+
<section>
|
6
|
+
<item>
|
7
|
+
<attribute name="label">Copy</attribute>
|
8
|
+
<attribute name="action">app.term_copy</attribute>
|
9
|
+
<attribute name="verb-icon">edit-copy-symbolic</attribute>
|
10
|
+
</item>
|
11
|
+
<item>
|
12
|
+
<attribute name="label">Paste</attribute>
|
13
|
+
<attribute name="action">app.term_paste</attribute>
|
14
|
+
<attribute name="verb-icon">edit-paste-symbolic</attribute>
|
15
|
+
</item>
|
16
|
+
</section>
|
17
|
+
</menu>
|
18
|
+
</interface>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:svg='http://www.w3.org/2000/svg' id='svg7384' version='1.1' height='16' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns='http://www.w3.org/2000/svg' width='16'>
|
5
|
+
<title id='title9167'>Gnome Symbolic Icon Theme</title>
|
6
|
+
<metadata id='metadata90'>
|
7
|
+
<rdf:RDF>
|
8
|
+
<cc:Work rdf:about=''>
|
9
|
+
<dc:format>image/svg+xml</dc:format>
|
10
|
+
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
|
11
|
+
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
12
|
+
</cc:Work>
|
13
|
+
</rdf:RDF>
|
14
|
+
</metadata>
|
15
|
+
<defs id='defs7386'/>
|
16
|
+
<g transform='translate(-60,-518)' id='layer9' style='display:inline'/>
|
17
|
+
<g transform='translate(-60,-518)' id='layer10'/>
|
18
|
+
<g transform='translate(-60,-518)' id='layer11'/>
|
19
|
+
<g transform='translate(-60,-518)' id='layer12'>
|
20
|
+
<g transform='translate(19,-242)' id='layer4-4-1' style='display:inline'>
|
21
|
+
|
22
|
+
<path inkscape:connector-curvature='0' d='m 45,764 1,0 c 0.01037,-1.2e-4 0.02079,-4.6e-4 0.03125,0 0.254951,0.0112 0.50987,0.12858 0.6875,0.3125 L 49,766.59375 51.3125,764.3125 C 51.578125,764.082 51.759172,764.007 52,764 l 1,0 0,1 c 0,0.28647 -0.03434,0.55065 -0.25,0.75 l -2.28125,2.28125 2.25,2.25 C 52.906938,770.46942 52.999992,770.7347 53,771 l 0,1 -1,0 c -0.265301,-10e-6 -0.530586,-0.0931 -0.71875,-0.28125 L 49,769.4375 46.71875,771.71875 C 46.530586,771.90694 46.26529,772 46,772 l -1,0 0,-1 c -3e-6,-0.26529 0.09306,-0.53058 0.28125,-0.71875 l 2.28125,-2.25 L 45.28125,765.75 C 45.070508,765.55537 44.97809,765.28075 45,765 l 0,-1 z' id='path10839-9' style='font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.78124988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Andale Mono;-inkscape-font-specification:Andale Mono'/>
|
23
|
+
</g>
|
24
|
+
</g>
|
25
|
+
<g transform='translate(-60,-518)' id='layer13'/>
|
26
|
+
<g transform='translate(-60,-518)' id='layer14'/>
|
27
|
+
<g transform='translate(-60,-518)' id='layer15'/>
|
28
|
+
</svg>
|
data/data/window-menu.ui
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<interface>
|
3
|
+
<!-- interface-requires gtk+ 3.0 -->
|
4
|
+
<menu id="winmenu">
|
5
|
+
<section>
|
6
|
+
<item >
|
7
|
+
<attribute name="label" translatable="yes" >_Css Configuration Editor</attribute>
|
8
|
+
</item>
|
9
|
+
<item>
|
10
|
+
<attribute name="label" translatable="yes">_Preferences</attribute>
|
11
|
+
<attribute name="action">app.preferences</attribute>
|
12
|
+
</item>
|
13
|
+
<item>
|
14
|
+
<attribute name="label" translatable="yes">_About</attribute>
|
15
|
+
<attribute name="action">app.about</attribute>
|
16
|
+
</item>
|
17
|
+
</section>
|
18
|
+
|
19
|
+
<section>
|
20
|
+
<item>
|
21
|
+
<attribute name="label" translatable="yes">_Quit</attribute>
|
22
|
+
<attribute name="action">app.quit</attribute>
|
23
|
+
</item>
|
24
|
+
</section>
|
25
|
+
</menu>
|
26
|
+
</interface>
|
data/data/window.ui
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!-- Generated with glade 3.18.3 -->
|
3
|
+
<interface>
|
4
|
+
<requires lib="gtk+" version="3.12"/>
|
5
|
+
<template class="window" parent="GtkWindow">
|
6
|
+
<property name="can_focus">False</property>
|
7
|
+
<child>
|
8
|
+
<object class="GtkNotebook" id="notebook">
|
9
|
+
<property name="visible">True</property>
|
10
|
+
<property name="can_focus">True</property>
|
11
|
+
<property name="show_border">False</property>
|
12
|
+
<property name="scrollable">True</property>
|
13
|
+
<property name="enable_popup">True</property>
|
14
|
+
<child>
|
15
|
+
<placeholder/>
|
16
|
+
</child>
|
17
|
+
<child type="tab">
|
18
|
+
<object class="GtkLabel" id="label1">
|
19
|
+
<property name="visible">True</property>
|
20
|
+
<property name="can_focus">False</property>
|
21
|
+
<property name="label" translatable="yes">page 1</property>
|
22
|
+
</object>
|
23
|
+
<packing>
|
24
|
+
<property name="tab_fill">False</property>
|
25
|
+
</packing>
|
26
|
+
</child>
|
27
|
+
<child>
|
28
|
+
<placeholder/>
|
29
|
+
</child>
|
30
|
+
<child type="tab">
|
31
|
+
<object class="GtkLabel" id="label2">
|
32
|
+
<property name="visible">True</property>
|
33
|
+
<property name="can_focus">False</property>
|
34
|
+
<property name="label" translatable="yes">page 2</property>
|
35
|
+
</object>
|
36
|
+
<packing>
|
37
|
+
<property name="position">1</property>
|
38
|
+
<property name="tab_fill">False</property>
|
39
|
+
</packing>
|
40
|
+
</child>
|
41
|
+
<child>
|
42
|
+
<placeholder/>
|
43
|
+
</child>
|
44
|
+
<child type="tab">
|
45
|
+
<object class="GtkLabel" id="label3">
|
46
|
+
<property name="visible">True</property>
|
47
|
+
<property name="can_focus">False</property>
|
48
|
+
<property name="label" translatable="yes">page 3</property>
|
49
|
+
</object>
|
50
|
+
<packing>
|
51
|
+
<property name="position">2</property>
|
52
|
+
<property name="tab_fill">False</property>
|
53
|
+
</packing>
|
54
|
+
</child>
|
55
|
+
</object>
|
56
|
+
</child>
|
57
|
+
</template>
|
58
|
+
</interface>
|
data/lib/actions.rb
ADDED
@@ -0,0 +1,73 @@
|
|
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 TopinambourActions
|
18
|
+
def self.generate_action(name)
|
19
|
+
action = Gio::SimpleAction.new(name)
|
20
|
+
action.signal_connect("activate") do |act, param|
|
21
|
+
yield(act, param) if block_given?
|
22
|
+
end
|
23
|
+
action
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.add_action_to(name, application)
|
27
|
+
method_name = "generate_#{name}_action".to_sym
|
28
|
+
return false unless methods.include?(method_name)
|
29
|
+
action = method(method_name).call(application)
|
30
|
+
application.add_action(action)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.generate_about_action(application)
|
34
|
+
action = generate_action("about") do |_act, _param|
|
35
|
+
application.windows[0].display_about
|
36
|
+
end
|
37
|
+
action
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.generate_preferences_action(application)
|
41
|
+
action = generate_action("preferences") do |_act, _param|
|
42
|
+
puts "TODO"
|
43
|
+
end
|
44
|
+
action
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.generate_quit_action(application)
|
48
|
+
action = generate_action("quit") do |_act, _param|
|
49
|
+
application.quit
|
50
|
+
end
|
51
|
+
action
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.generate_term_copy_action(application)
|
55
|
+
action = generate_action("term_copy") do |_act, _param|
|
56
|
+
application.windows[0].notebook.current.copy_clipboard
|
57
|
+
end
|
58
|
+
action
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.generate_term_paste_action(application)
|
62
|
+
action = generate_action("term_paste") do |_act, _param|
|
63
|
+
application.windows[0].notebook.current.paste_clipboard
|
64
|
+
end
|
65
|
+
action
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.add_actions_to(application)
|
69
|
+
%w(about preferences quit term_copy term_paste).each do |name|
|
70
|
+
add_action_to(name, application)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/application.rb
ADDED
@@ -0,0 +1,131 @@
|
|
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
|
+
class TopinambourApplication < Gtk::Application
|
18
|
+
attr_reader :provider
|
19
|
+
def initialize
|
20
|
+
super("com.github.cedlemo.germinal", :non_unique)
|
21
|
+
|
22
|
+
signal_connect "startup" do |application|
|
23
|
+
load_css_config
|
24
|
+
screen = Gdk::Display.default.default_screen
|
25
|
+
Gtk::StyleContext.add_provider_for_screen(screen, @provider, Gtk::StyleProvider::PRIORITY_USER)
|
26
|
+
TopinambourActions.add_actions_to(application)
|
27
|
+
load_menu_ui_in(application)
|
28
|
+
end
|
29
|
+
|
30
|
+
signal_connect "activate" do |application|
|
31
|
+
window = TopinambourWindow.new(application)
|
32
|
+
window.present
|
33
|
+
window.add_terminal
|
34
|
+
window.notebook.current.grab_focus
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_css(new_props = nil)
|
39
|
+
css_properties
|
40
|
+
@props.merge!(new_props) if new_props
|
41
|
+
css = update_css_properties
|
42
|
+
merged_css = Sass::Engine.new(css, :syntax => :scss).render
|
43
|
+
if File.exist?(USR_CSS)
|
44
|
+
FileUtils.mv(USR_CSS, "#{USR_CSS}_#{Time.new.strftime('%Y-%m-%d-%H-%M-%S')}.backup")
|
45
|
+
File.open(USR_CSS, "w") do |file|
|
46
|
+
file.puts merged_css
|
47
|
+
end
|
48
|
+
else
|
49
|
+
File.open(USR_CSS, "w") do |file|
|
50
|
+
file.puts merged_css
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def load_menu_ui_in(application)
|
58
|
+
builder = Gtk::Builder.new(:resource => "/com/github/cedlemo/germinal/app-menu.ui")
|
59
|
+
app_menu = builder["appmenu"]
|
60
|
+
application.app_menu = app_menu
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_css_config
|
64
|
+
@provider = Gtk::CssProvider.new
|
65
|
+
default_css = Gio::Resources.lookup_data("/com/github/cedlemo/germinal/germinal.css", 0)
|
66
|
+
if File.exist?(USR_CSS)
|
67
|
+
begin
|
68
|
+
@provider.load(:path => USR_CSS)
|
69
|
+
rescue
|
70
|
+
puts "Bad css file using default css"
|
71
|
+
@provider.load(:data => default_css)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
puts "No custom CSS, using default css"
|
75
|
+
@provider.load(:data => default_css)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def load_css_to_tree
|
80
|
+
engine = Sass::Engine.new(@provider.to_s, :syntax => :scss)
|
81
|
+
engine.to_tree
|
82
|
+
end
|
83
|
+
|
84
|
+
def update_css_properties
|
85
|
+
modified_sass = change_existing_properties
|
86
|
+
sass_to_add = @props.empty? ? "" : add_new_css_properties
|
87
|
+
Sass::Engine.new(sass_to_add + modified_sass, :syntax => :sass).render
|
88
|
+
end
|
89
|
+
|
90
|
+
def add_new_css_properties
|
91
|
+
new_sass = "*"
|
92
|
+
@props.each do |k, v|
|
93
|
+
new_sass += "\n #{k}: #{v}"
|
94
|
+
end
|
95
|
+
new_sass + "\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
def change_existing_properties
|
99
|
+
keys_found = []
|
100
|
+
tree = load_css_to_tree
|
101
|
+
# we search for properties that are already configured
|
102
|
+
tree.children.each do |node|
|
103
|
+
node.each do |prop|
|
104
|
+
next if prop.class != Sass::Tree::PropNode
|
105
|
+
name = prop.name[0]
|
106
|
+
next unless @props[name]
|
107
|
+
keys_found << name unless keys_found.include?(name)
|
108
|
+
if @props[name] != prop.value.value
|
109
|
+
value_object = prop.value.value.class.new(@props[name])
|
110
|
+
prop.value = Sass::Script::Tree::Literal.new(value_object)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
keys_found.each do |k|
|
115
|
+
@props.delete(k)
|
116
|
+
end
|
117
|
+
tree.to_sass
|
118
|
+
end
|
119
|
+
|
120
|
+
def css_properties
|
121
|
+
@props = {}
|
122
|
+
return @props if windows[0].notebook.current.class == TopinambourTerminal
|
123
|
+
|
124
|
+
terminal_colors = windows[0].notebook.current.colors
|
125
|
+
TERMINAL_COLOR_NAMES.each_with_index do |c, i|
|
126
|
+
@props["-TopinambourTerminal-#{c}"] = terminal_colors[i].to_s
|
127
|
+
end
|
128
|
+
@props["-TopinambourTerminal-font"] = DEFAULT_TERMINAL_FONT
|
129
|
+
@props["-TopinambourWindow-shell"] = "\'/usr/bin/fish\'"
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,94 @@
|
|
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 TopinambourColorSelector < Gtk::Box
|
17
|
+
attr_reader :colors
|
18
|
+
def initialize(window)
|
19
|
+
@window = window
|
20
|
+
super(:horizontal, 0)
|
21
|
+
|
22
|
+
reset_button = generate_reset_button
|
23
|
+
pack_start(reset_button, :expand => false, :fill => false, :padding => 0)
|
24
|
+
|
25
|
+
initialize_default_colors
|
26
|
+
add_color_selectors
|
27
|
+
|
28
|
+
save_button = generate_save_button
|
29
|
+
pack_start(save_button, :expand => false, :fill => false, :padding => 0)
|
30
|
+
|
31
|
+
show_all
|
32
|
+
set_halign(:center)
|
33
|
+
set_valign(:end)
|
34
|
+
set_name("color_selector")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def initialize_default_colors
|
40
|
+
@default_colors = @window.notebook.current.get_css_colors
|
41
|
+
@colors = @default_colors.dup
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_reset_button
|
45
|
+
button = Gtk::Button.new(:label => "Reset")
|
46
|
+
button.signal_connect "clicked" do
|
47
|
+
initialize_default_colors
|
48
|
+
children[1..-2].each_with_index do |child, i|
|
49
|
+
child.rgba = @default_colors[i]
|
50
|
+
end
|
51
|
+
apply_new_colors
|
52
|
+
end
|
53
|
+
button
|
54
|
+
end
|
55
|
+
|
56
|
+
def apply_new_css_properties(toplevel, props)
|
57
|
+
toplevel.application.update_css(props)
|
58
|
+
toplevel.notebook.each do |tab|
|
59
|
+
next unless tab.class == TopinambourTerminal
|
60
|
+
tab.colors = @colors
|
61
|
+
tab.apply_colors
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate_save_button
|
66
|
+
button = Gtk::Button.new(:label => "Save")
|
67
|
+
button.signal_connect "clicked" do |widget|
|
68
|
+
new_props = {}
|
69
|
+
TERMINAL_COLOR_NAMES.each_with_index do |c, i|
|
70
|
+
new_props["-TopinambourTerminal-#{c}"] = @colors[i].to_s
|
71
|
+
end
|
72
|
+
apply_new_css_properties(widget.toplevel, new_props)
|
73
|
+
button.toplevel.exit_overlay_mode
|
74
|
+
end
|
75
|
+
button
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_color_selectors
|
79
|
+
TERMINAL_COLOR_NAMES.each_with_index do |name, i|
|
80
|
+
color_sel = Gtk::ColorButton.new(@default_colors[i])
|
81
|
+
color_sel.set_title(name.to_s)
|
82
|
+
color_sel.signal_connect "color-set" do
|
83
|
+
@colors[i] = color_sel.rgba
|
84
|
+
apply_new_colors
|
85
|
+
end
|
86
|
+
pack_start(color_sel, :expand => false, :fill => false, :padding => 0)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def apply_new_colors
|
91
|
+
@window.notebook.current.colors = @colors
|
92
|
+
@window.notebook.current.apply_colors
|
93
|
+
end
|
94
|
+
end
|
data/lib/css_editor.rb
ADDED
@@ -0,0 +1,159 @@
|
|
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
|
+
require "gtksourceview3"
|
17
|
+
class TopinambourCssEditor < Gtk::Grid
|
18
|
+
attr_accessor :tab_label, :preview
|
19
|
+
def initialize(window)
|
20
|
+
super()
|
21
|
+
@window = window
|
22
|
+
@provider = window.application.provider
|
23
|
+
@default_css = @provider.to_s
|
24
|
+
@modified_css = @default_css
|
25
|
+
@tab_label = "Css Editor"
|
26
|
+
|
27
|
+
gen_source_view
|
28
|
+
|
29
|
+
sw = Gtk::ScrolledWindow.new(nil, nil)
|
30
|
+
sw.vexpand = true
|
31
|
+
sw.hexpand = true
|
32
|
+
sw.add(@view)
|
33
|
+
attach(sw, 0, 0, 3, 1)
|
34
|
+
|
35
|
+
button = gen_reset_button
|
36
|
+
attach(button, 0, 1, 1, 1)
|
37
|
+
|
38
|
+
@style_button = gen_style_chooser_button
|
39
|
+
attach(@style_button, 1, 1, 1, 1)
|
40
|
+
|
41
|
+
button = gen_save_button
|
42
|
+
attach(button, 2, 1, 1, 1)
|
43
|
+
manage_buffer_changes
|
44
|
+
manage_css_errors
|
45
|
+
show_all
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def gen_source_view
|
51
|
+
@view = GtkSource::View.new
|
52
|
+
@manager = GtkSource::LanguageManager.new
|
53
|
+
@language = @manager.get_language("css")
|
54
|
+
@sm = GtkSource::StyleSchemeManager.default
|
55
|
+
|
56
|
+
@view.show_line_numbers = true
|
57
|
+
@view.insert_spaces_instead_of_tabs = true
|
58
|
+
@view.buffer.language = @language
|
59
|
+
@view.buffer.highlight_syntax = true
|
60
|
+
@view.buffer.highlight_matching_brackets = true
|
61
|
+
@view.buffer.text = @default_css
|
62
|
+
@view.show_right_margin = true
|
63
|
+
@view.right_margin_position = 80
|
64
|
+
@view.smart_backspace = true
|
65
|
+
end
|
66
|
+
|
67
|
+
def gen_reset_button
|
68
|
+
button = Gtk::Button.new(:label => "Reset")
|
69
|
+
button.signal_connect "clicked" do
|
70
|
+
@view.buffer.text = @default_css
|
71
|
+
end
|
72
|
+
button.vexpand = false
|
73
|
+
button.hexpand = false
|
74
|
+
button
|
75
|
+
end
|
76
|
+
|
77
|
+
def gen_style_chooser_button
|
78
|
+
style_scheme = nil
|
79
|
+
if @sm.scheme_ids.include?(@window.css_editor_style)
|
80
|
+
style_scheme = @sm.get_scheme(@window.css_editor_style)
|
81
|
+
else
|
82
|
+
style_scheme = @sm.get_scheme("classic")
|
83
|
+
end
|
84
|
+
@view.buffer.style_scheme = style_scheme
|
85
|
+
button = GtkSource::StyleSchemeChooserButton.new
|
86
|
+
button.vexpand = false
|
87
|
+
button.hexpand = true
|
88
|
+
button.style_scheme = @view.buffer.style_scheme
|
89
|
+
button.signal_connect "style-updated" do |widget|
|
90
|
+
@view.buffer.style_scheme = widget.style_scheme
|
91
|
+
end
|
92
|
+
button
|
93
|
+
end
|
94
|
+
|
95
|
+
def gen_save_button
|
96
|
+
button = Gtk::Button.new(:label => "Save")
|
97
|
+
button.signal_connect "clicked" do
|
98
|
+
@window.application.update_css
|
99
|
+
reload_custom_css_properties
|
100
|
+
end
|
101
|
+
button.vexpand = false
|
102
|
+
button.hexpand = false
|
103
|
+
button
|
104
|
+
end
|
105
|
+
|
106
|
+
def manage_buffer_changes
|
107
|
+
@view.buffer.signal_connect "changed" do |buffer|
|
108
|
+
@modified_css = buffer.get_text(buffer.start_iter,
|
109
|
+
buffer.end_iter,
|
110
|
+
false)
|
111
|
+
begin
|
112
|
+
@provider.load_from_data(@modified_css)
|
113
|
+
rescue
|
114
|
+
@provider.load_from_data(@default_css)
|
115
|
+
end
|
116
|
+
|
117
|
+
reload_custom_css_properties
|
118
|
+
Gtk::StyleContext.reset_widgets
|
119
|
+
style_scheme = nil
|
120
|
+
if @sm.scheme_ids.include?(@window.css_editor_style)
|
121
|
+
style_scheme = @sm.get_scheme(@window.css_editor_style)
|
122
|
+
else
|
123
|
+
style_scheme = @sm.get_scheme("classic")
|
124
|
+
end
|
125
|
+
@view.buffer.style_scheme = style_scheme
|
126
|
+
@style_button.style_scheme = style_scheme
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def manage_css_errors
|
131
|
+
@provider.signal_connect "parsing-error" do |_css_provider, section, error|
|
132
|
+
# @start_i = @view.buffer.get_iter_at(:line => section.start_line,
|
133
|
+
# :index => section.start_position)
|
134
|
+
# @end_i = @view.buffer.get_iter_at(:line => section.end_line,
|
135
|
+
# :index => section.end_position)
|
136
|
+
# if error == Gtk::CssProviderError::DEPRECATED
|
137
|
+
# else
|
138
|
+
# end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def reload_custom_css_properties
|
143
|
+
reload_terminal_custom_css_properties
|
144
|
+
reload_window_custom_css_properties
|
145
|
+
end
|
146
|
+
|
147
|
+
def reload_terminal_custom_css_properties
|
148
|
+
@window.notebook.each do |tab|
|
149
|
+
next unless tab.class == TopinambourTerminal
|
150
|
+
colors = tab.get_css_colors unless colors
|
151
|
+
tab.colors = colors
|
152
|
+
tab.apply_colors
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def reload_window_custom_css_properties
|
157
|
+
@window.load_css_properties
|
158
|
+
end
|
159
|
+
end
|
data/lib/css_handler.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module CssHandler
|
2
|
+
def css_file?(filename)
|
3
|
+
filename =~ /^.*\.css$/ ? true : false
|
4
|
+
end
|
5
|
+
|
6
|
+
def scss_file?(filename)
|
7
|
+
filename =~ /^.*\.scss$/ ? true : false
|
8
|
+
end
|
9
|
+
|
10
|
+
def sass_file?(filename)
|
11
|
+
filename =~ /^.*\.sass$/ ? true : false
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_css(filename)
|
15
|
+
content = File.open(filename, "r").read
|
16
|
+
if css_file?(filename) || scss_file?(filename)
|
17
|
+
Sass::Engine.new(content, :syntax => :scss).render
|
18
|
+
else
|
19
|
+
Sass::Engine.new(content, :syntax => :sass).render
|
20
|
+
else
|
21
|
+
puts "Your theme file must be a css, scss or sass file"
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def color_property?(value)
|
27
|
+
begin
|
28
|
+
Gdk::RGBA.parse(value)
|
29
|
+
rescue
|
30
|
+
false
|
31
|
+
end
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def property_to_css_instructions(name, value)
|
36
|
+
if value.class == String && color_property?(value)
|
37
|
+
"#{name}: #{value};\n"
|
38
|
+
else value.class == String
|
39
|
+
"#{name}: \"#{value}\";\n"
|
40
|
+
else
|
41
|
+
"#{name}: #{value};\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_global
|
46
|
+
|
47
|
+
end
|