mittens_ui 0.0.6 → 0.0.10
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 +4 -4
- data/.ruby-version +1 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +5 -2
- data/LICENSE +21 -0
- data/README.md +82 -17
- data/examples/app.rb +102 -6
- data/examples/assets/gnome_logo.png +0 -0
- data/examples/assets/mittens_ui_preview.gif +0 -0
- data/examples/contacts.rb +75 -0
- data/lib/mittens_ui.rb +33 -60
- data/lib/mittens_ui/alert.rb +32 -0
- data/lib/mittens_ui/assets/icon.png +0 -0
- data/lib/mittens_ui/assets/mittens_ui_preview.gif +0 -0
- data/lib/mittens_ui/button.rb +29 -0
- data/lib/mittens_ui/checkbox.rb +24 -0
- data/lib/mittens_ui/core.rb +34 -0
- data/lib/mittens_ui/file_picker.rb +29 -0
- data/lib/mittens_ui/grid.rb +29 -0
- data/lib/mittens_ui/hbox.rb +56 -0
- data/lib/mittens_ui/header_bar.rb +48 -0
- data/lib/mittens_ui/helpers.rb +27 -0
- data/lib/mittens_ui/image.rb +46 -0
- data/lib/mittens_ui/label.rb +19 -0
- data/lib/mittens_ui/listbox.rb +47 -0
- data/lib/mittens_ui/loader.rb +35 -0
- data/lib/mittens_ui/slider.rb +32 -0
- data/lib/mittens_ui/switch.rb +36 -0
- data/lib/mittens_ui/table_view.rb +179 -0
- data/lib/mittens_ui/textbox.rb +31 -0
- data/lib/mittens_ui/version.rb +1 -1
- data/lib/mittens_ui/web_link.rb +22 -0
- data/mittens_ui.gemspec +3 -3
- data/notes/dev_setup.txt +14 -0
- metadata +33 -15
- data/examples/brightness_controller.rb +0 -64
- data/lib/mittens_ui/layouts/box.rb +0 -38
- data/lib/mittens_ui/layouts/grid.rb +0 -31
- data/lib/mittens_ui/widgets/alert.rb +0 -33
- data/lib/mittens_ui/widgets/button.rb +0 -34
- data/lib/mittens_ui/widgets/label.rb +0 -41
- data/lib/mittens_ui/widgets/listbox.rb +0 -45
- data/lib/mittens_ui/widgets/slider.rb +0 -32
- data/lib/mittens_ui/widgets/textbox.rb +0 -25
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module MittensUi
|
|
2
|
+
class Alert
|
|
3
|
+
def initialize(message, options={})
|
|
4
|
+
dialog_options = {
|
|
5
|
+
title: options[:title] || "Alert",
|
|
6
|
+
parent: $app_window,
|
|
7
|
+
flags: [:modal, :destroy_with_parent],
|
|
8
|
+
:buttons => [[Gtk::Stock::OK, :none]]
|
|
9
|
+
}.freeze
|
|
10
|
+
|
|
11
|
+
@alert_dialog = Gtk::Dialog.new(dialog_options)
|
|
12
|
+
@alert_dialog.set_transient_for($app_window)
|
|
13
|
+
@alert_dialog.set_default_width(420)
|
|
14
|
+
@alert_dialog.set_default_height(200)
|
|
15
|
+
@alert_dialog.set_modal(true)
|
|
16
|
+
@alert_dialog.set_resizable(false)
|
|
17
|
+
|
|
18
|
+
message_label = Gtk::Label.new(message)
|
|
19
|
+
message_label.set_margin_top(36)
|
|
20
|
+
|
|
21
|
+
dialog_box = @alert_dialog.content_area
|
|
22
|
+
dialog_box.add(message_label)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def render
|
|
26
|
+
@alert_dialog.show_all
|
|
27
|
+
response = @alert_dialog.run
|
|
28
|
+
response == :none ? @alert_dialog.destroy : @alert_dialog.destroy
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class Button < Core
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
button_title = options[:title] || "Button"
|
|
7
|
+
|
|
8
|
+
@button = Gtk::Button.new(label: button_title)
|
|
9
|
+
|
|
10
|
+
super(@button, options)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def enable(answer)
|
|
14
|
+
@button.set_sensitive(answer)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def click
|
|
18
|
+
@button.signal_connect("clicked") do |button_widget|
|
|
19
|
+
yield(button_widget)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def render
|
|
24
|
+
$vertical_box.pack_start(@button)
|
|
25
|
+
return self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class Checkbox < Core
|
|
5
|
+
attr_accessor :value
|
|
6
|
+
|
|
7
|
+
def initialize(options={})
|
|
8
|
+
label = options[:label] || "Checkbox"
|
|
9
|
+
|
|
10
|
+
@value = nil
|
|
11
|
+
@checkbox = Gtk::CheckButton.new(label)
|
|
12
|
+
|
|
13
|
+
$vertical_box.pack_start(@checkbox)
|
|
14
|
+
|
|
15
|
+
super(@checkbox, options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def toggle
|
|
19
|
+
@checkbox.signal_connect "toggled" do
|
|
20
|
+
yield
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require "mittens_ui/helpers"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class Core
|
|
5
|
+
include Helpers
|
|
6
|
+
|
|
7
|
+
attr_reader :core_widget
|
|
8
|
+
|
|
9
|
+
# All MittenUi::Widgets::* classes should inherit from this base class.
|
|
10
|
+
|
|
11
|
+
def initialize(widget, options={})
|
|
12
|
+
# core_widget is the Raw Gtk::Widget*
|
|
13
|
+
@core_widget = widget
|
|
14
|
+
set_margin_from_opts_for(@core_widget, options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def show
|
|
18
|
+
@core_widget.show_all
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def hidden?
|
|
22
|
+
@core_widget.visible?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def hide
|
|
26
|
+
return if @core_widget.nil?
|
|
27
|
+
@core_widget.hide
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def remove
|
|
31
|
+
$vertical_box.remove(@core_widget)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module MittensUi
|
|
2
|
+
class FilePicker
|
|
3
|
+
attr_reader :path
|
|
4
|
+
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
@path = ""
|
|
7
|
+
|
|
8
|
+
dialog_options = {
|
|
9
|
+
title: "Select File",
|
|
10
|
+
parent: $app_window,
|
|
11
|
+
action: options[:action] || :open,
|
|
12
|
+
buttons: [
|
|
13
|
+
[Gtk::Stock::OPEN, Gtk::ResponseType::ACCEPT],
|
|
14
|
+
[Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL]
|
|
15
|
+
]
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
@dialog = Gtk::FileChooserDialog.new(dialog_options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def render
|
|
22
|
+
if @dialog.run == :accept
|
|
23
|
+
@path = @dialog.filename
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@dialog.destroy
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module MittensUi
|
|
2
|
+
class Grid
|
|
3
|
+
def initialize(window, &block)
|
|
4
|
+
@grid = Gtk::Grid.new
|
|
5
|
+
yield(self)
|
|
6
|
+
window.add_child(@grid)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def attach(widget, options)
|
|
10
|
+
grid_height = options[:height]
|
|
11
|
+
grid_width = options[:width]
|
|
12
|
+
grid_top = options[:top]
|
|
13
|
+
grid_left = options[:left]
|
|
14
|
+
|
|
15
|
+
# Place widget next to each other in the direction determined by the “orientation” property
|
|
16
|
+
# defaults to :horizontal.
|
|
17
|
+
if options.size >= 1
|
|
18
|
+
@grid.add(widget)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
unless options[:attach_to].nil?
|
|
22
|
+
return
|
|
23
|
+
@grid.attach_next_to()
|
|
24
|
+
else
|
|
25
|
+
@grid.attach(widget, grid_left, grid_top, grid_width, grid_height)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require "mittens_ui/helpers"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class HBox
|
|
5
|
+
include Helpers
|
|
6
|
+
|
|
7
|
+
def initialize(widgets, options={})
|
|
8
|
+
box_spacing = options[:spacing].nil? ? 6 : options[:spacing]
|
|
9
|
+
|
|
10
|
+
@box = Gtk::Box.new(:horizontal, box_spacing)
|
|
11
|
+
|
|
12
|
+
set_margin_from_opts_for(@box, options)
|
|
13
|
+
|
|
14
|
+
widgets.each do |w|
|
|
15
|
+
# We need to remove the widget from the global $vertical_box before hand
|
|
16
|
+
# otherwise it won't render the widgets properly since they are already in another container.
|
|
17
|
+
w.remove
|
|
18
|
+
self.attach(w.core_widget, { position: :start })
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def remove
|
|
23
|
+
return if @box.nil?
|
|
24
|
+
@box.destroy
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def render
|
|
28
|
+
$vertical_box.pack_start(@box)
|
|
29
|
+
return self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def attach(widget, options={})
|
|
35
|
+
expand = options[:expand].nil? ? true : options[:expand]
|
|
36
|
+
fill = options[:fill].nil? ? true : options[:fill]
|
|
37
|
+
padding = options[:padding].nil? ? 0 : options[:padding]
|
|
38
|
+
|
|
39
|
+
filterd_options = {
|
|
40
|
+
expaned: expand,
|
|
41
|
+
fill: fill,
|
|
42
|
+
padding: padding
|
|
43
|
+
}.freeze
|
|
44
|
+
|
|
45
|
+
case options.dig(:position)
|
|
46
|
+
when :start
|
|
47
|
+
@box.pack_start(widget, filterd_options)
|
|
48
|
+
when :end
|
|
49
|
+
@box.pack_end(widget, filterd_options)
|
|
50
|
+
when nil
|
|
51
|
+
@box.pack_start(widget, filterd_options)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class HeaderBar < Core
|
|
5
|
+
def initialize(widgets, options = {})
|
|
6
|
+
title = options[:title].nil? ? "" : options[:title]
|
|
7
|
+
position = options[:position].nil? ? :left : options[:position]
|
|
8
|
+
|
|
9
|
+
box = Gtk::Box.new(:horizontal, 0)
|
|
10
|
+
box.style_context.add_class("linked")
|
|
11
|
+
|
|
12
|
+
@header = Gtk::HeaderBar.new
|
|
13
|
+
@header.show_close_button = true
|
|
14
|
+
@header.title = title
|
|
15
|
+
@header.has_subtitle = false
|
|
16
|
+
|
|
17
|
+
widgets.each do |w|
|
|
18
|
+
w.remove
|
|
19
|
+
case position
|
|
20
|
+
when :left
|
|
21
|
+
box.pack_start(w.core_widget)
|
|
22
|
+
when :right
|
|
23
|
+
box.pack_end(w.core_widget)
|
|
24
|
+
else
|
|
25
|
+
box.pack_start(w.core_widget)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if position == :left
|
|
30
|
+
@header.pack_start(box)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if position == :right
|
|
34
|
+
@header.pack_end(box)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
$app_window.titlebar = @header
|
|
38
|
+
|
|
39
|
+
super(@header, options)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def render
|
|
43
|
+
$vertical_box.pack_start(@header)
|
|
44
|
+
return self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module MittensUi
|
|
2
|
+
module Helpers
|
|
3
|
+
def set_margin_from_opts_for(widget, options={})
|
|
4
|
+
margin_top = options[:top].nil? ? nil : options[:top]
|
|
5
|
+
margin_bottom = options[:bottom].nil? ? nil : options[:bottom]
|
|
6
|
+
margin_right = options[:right].nil? ? nil : options[:right]
|
|
7
|
+
margin_left = options[:left].nil? ? nil : options[:left]
|
|
8
|
+
|
|
9
|
+
unless margin_top.nil?
|
|
10
|
+
widget.set_margin_top(margin_top)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
unless margin_bottom.nil?
|
|
14
|
+
widget.set_margin_bottom(margin_bottom)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
unless margin_left.nil?
|
|
18
|
+
widget.set_margin_left(margin_left)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
unless margin_right.nil?
|
|
22
|
+
widget.set_margin_right(margin_right)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class Image < Core
|
|
5
|
+
attr_reader :path
|
|
6
|
+
|
|
7
|
+
def initialize(path, options = {})
|
|
8
|
+
@path = File.join(path.strip)
|
|
9
|
+
|
|
10
|
+
tooltip_text = options[:tooltip_text].nil? ? "" : options[:tooltip_text]
|
|
11
|
+
width = options[:width].nil? ? 80 : options[:width]
|
|
12
|
+
height = options[:height].nil? ? 80 : options[:height]
|
|
13
|
+
|
|
14
|
+
pixbuf = nil
|
|
15
|
+
|
|
16
|
+
args_to_send = {}
|
|
17
|
+
|
|
18
|
+
if path.include?(".gif")
|
|
19
|
+
pixbuf = GdkPixbuf::PixbufAnimation.new(@path)
|
|
20
|
+
args_to_send[:animation] = pixbuf
|
|
21
|
+
else
|
|
22
|
+
pixbuf = GdkPixbuf::Pixbuf.new(file: @path, width: width, height: height)
|
|
23
|
+
args_to_send[:pixbuf] = pixbuf
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@image = Gtk::Image.new(args_to_send)
|
|
27
|
+
@image.tooltip_text = tooltip_text
|
|
28
|
+
|
|
29
|
+
@event_box = Gtk::EventBox.new.add_child(@image)
|
|
30
|
+
|
|
31
|
+
super(@image, options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def click
|
|
35
|
+
@event_box.signal_connect("button_press_event") do
|
|
36
|
+
yield
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def render
|
|
41
|
+
$vertical_box.pack_start(@event_box)
|
|
42
|
+
return self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class Label < Core
|
|
5
|
+
def initialize(text, options)
|
|
6
|
+
if text.nil? || text == "" || text == " "
|
|
7
|
+
text = "Label"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
@label = Gtk::Label.new(text)
|
|
11
|
+
super(@label, options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def render
|
|
15
|
+
$vertical_box.pack_start(@label)
|
|
16
|
+
return self
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class ListBox < Core
|
|
5
|
+
attr_reader :items
|
|
6
|
+
|
|
7
|
+
def initialize(options={})
|
|
8
|
+
@items = options[:items]
|
|
9
|
+
|
|
10
|
+
list_store = Gtk::ListStore.new(String)
|
|
11
|
+
|
|
12
|
+
@items.each do |i|
|
|
13
|
+
iter = list_store.append
|
|
14
|
+
iter[0] = i
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
renderer = Gtk::CellRendererText.new
|
|
18
|
+
|
|
19
|
+
@gtk_combobox = Gtk::ComboBox.new(model: list_store)
|
|
20
|
+
@gtk_combobox.pack_start(renderer, true)
|
|
21
|
+
@gtk_combobox.set_attributes(renderer, "text" => 0)
|
|
22
|
+
@gtk_combobox.set_cell_data_func(renderer) do |_layout, _cell_renderer, _model, iter|
|
|
23
|
+
set_selected_value(iter[0])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@gtk_combobox.set_active(0)
|
|
27
|
+
|
|
28
|
+
super(@gtk_combobox)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def set_selected_value(value)
|
|
32
|
+
@selected_value = value
|
|
33
|
+
end
|
|
34
|
+
alias :set_value :set_selected_value
|
|
35
|
+
|
|
36
|
+
def get_selected_value
|
|
37
|
+
@selected_value
|
|
38
|
+
end
|
|
39
|
+
alias :selected_value :get_selected_value
|
|
40
|
+
|
|
41
|
+
def render
|
|
42
|
+
$vertical_box.pack_start(@gtk_combobox)
|
|
43
|
+
return self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative "./core"
|
|
2
|
+
|
|
3
|
+
module MittensUi
|
|
4
|
+
class Loader < Core
|
|
5
|
+
def initialize(options={})
|
|
6
|
+
@spinner = Gtk::Spinner.new
|
|
7
|
+
|
|
8
|
+
@processing = false
|
|
9
|
+
|
|
10
|
+
$vertical_box.pack_end(@spinner)
|
|
11
|
+
|
|
12
|
+
super(@spinner, options)
|
|
13
|
+
|
|
14
|
+
self.hide
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def start(&block)
|
|
18
|
+
return if @processing
|
|
19
|
+
|
|
20
|
+
return if @worker_thread && @worker_thread.alive?
|
|
21
|
+
|
|
22
|
+
self.show
|
|
23
|
+
|
|
24
|
+
@spinner.start
|
|
25
|
+
|
|
26
|
+
@worker_thread = Thread.new { yield; self.remove; @processing = true }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def render
|
|
30
|
+
$vertical_box.pack_end(@spinner)
|
|
31
|
+
return self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|