mittens_ui 0.0.9 → 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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +2 -2
  4. data/README.md +65 -61
  5. data/examples/app.rb +9 -1
  6. data/examples/assets/mittens_ui_preview.gif +0 -0
  7. data/examples/contacts.rb +75 -0
  8. data/lib/mittens_ui.rb +21 -67
  9. data/lib/mittens_ui/alert.rb +32 -0
  10. data/lib/mittens_ui/assets/icon.png +0 -0
  11. data/lib/mittens_ui/assets/mittens_ui_preview.gif +0 -0
  12. data/lib/mittens_ui/button.rb +29 -0
  13. data/lib/mittens_ui/checkbox.rb +24 -0
  14. data/lib/mittens_ui/core.rb +34 -0
  15. data/lib/mittens_ui/file_picker.rb +29 -0
  16. data/lib/mittens_ui/grid.rb +29 -0
  17. data/lib/mittens_ui/hbox.rb +56 -0
  18. data/lib/mittens_ui/header_bar.rb +48 -0
  19. data/lib/mittens_ui/image.rb +46 -0
  20. data/lib/mittens_ui/label.rb +19 -0
  21. data/lib/mittens_ui/listbox.rb +47 -0
  22. data/lib/mittens_ui/loader.rb +35 -0
  23. data/lib/mittens_ui/slider.rb +32 -0
  24. data/lib/mittens_ui/switch.rb +36 -0
  25. data/lib/mittens_ui/table_view.rb +179 -0
  26. data/lib/mittens_ui/textbox.rb +31 -0
  27. data/lib/mittens_ui/version.rb +1 -1
  28. data/lib/mittens_ui/web_link.rb +22 -0
  29. data/notes/dev_setup.txt +14 -0
  30. metadata +28 -23
  31. data/examples/brightness_controller.rb +0 -64
  32. data/lib/mittens_ui/dialogs/file_dialog.rb +0 -29
  33. data/lib/mittens_ui/layouts/box.rb +0 -38
  34. data/lib/mittens_ui/layouts/grid.rb +0 -31
  35. data/lib/mittens_ui/widgets/alert.rb +0 -33
  36. data/lib/mittens_ui/widgets/button.rb +0 -25
  37. data/lib/mittens_ui/widgets/checkbox.rb +0 -28
  38. data/lib/mittens_ui/widgets/core.rb +0 -32
  39. data/lib/mittens_ui/widgets/image.rb +0 -36
  40. data/lib/mittens_ui/widgets/label.rb +0 -21
  41. data/lib/mittens_ui/widgets/listbox.rb +0 -45
  42. data/lib/mittens_ui/widgets/loader.rb +0 -34
  43. data/lib/mittens_ui/widgets/slider.rb +0 -31
  44. data/lib/mittens_ui/widgets/switch.rb +0 -37
  45. data/lib/mittens_ui/widgets/table_view.rb +0 -159
  46. data/lib/mittens_ui/widgets/textbox.rb +0 -28
  47. data/lib/mittens_ui/widgets/web_link.rb +0 -23
@@ -1,29 +0,0 @@
1
- module MittensUi
2
- module Dialogs
3
- class File
4
- attr_reader :path
5
-
6
- def initialize(options={})
7
- @path = ""
8
-
9
- dialog_options = {
10
- title: "Select File",
11
- parent: $app_window,
12
- action: options[:action] || :open,
13
- buttons: [
14
- [Gtk::Stock::OPEN, Gtk::ResponseType::ACCEPT],
15
- [Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL]
16
- ]
17
- }.freeze
18
-
19
- dialog = Gtk::FileChooserDialog.new(dialog_options)
20
-
21
- if dialog.run == :accept
22
- @path = dialog.filename
23
- end
24
-
25
- dialog.destroy
26
- end
27
- end
28
- end
29
- end
@@ -1,38 +0,0 @@
1
- module MittensUi
2
- module Layouts
3
- class Box
4
- def initialize(window, options={}, &block)
5
- box_spacing = options[:spacing].nil? ? 6 : options[:spacing]
6
- @box = Gtk::Box.new(:vertical, box_spacing)
7
- yield(self)
8
- window.add(@box)
9
- end
10
-
11
- def attach(widget, options)
12
- expand = options[:expand].nil? ? true : options[:expand]
13
- fill = options[:fill].nil? ? true : options[:fill]
14
- padding = options[:padding].nil? ? 0 : options[:padding]
15
-
16
- filterd_options = {
17
- expaned: expand,
18
- fill: fill,
19
- padding: padding
20
- }.freeze
21
-
22
- case options.dig(:position)
23
- when :start
24
- @box.pack_start(widget, filterd_options)
25
- when :end
26
- @box.pack_end(widget, filterd_options)
27
- when nil
28
- @box.pack_start(widget, filterd_options)
29
- end
30
- end
31
-
32
- def remove
33
- return if @box.nil?
34
- @box.destroy
35
- end
36
- end
37
- end
38
- end
@@ -1,31 +0,0 @@
1
- module MittensUi
2
- module Layouts
3
- class Grid
4
- def initialize(window, &block)
5
- @grid = Gtk::Grid.new
6
- yield(self)
7
- window.add_child(@grid)
8
- end
9
-
10
- def attach(widget, options)
11
- grid_height = options[:height]
12
- grid_width = options[:width]
13
- grid_top = options[:top]
14
- grid_left = options[:left]
15
-
16
- # Place widget next to each other in the direction determined by the “orientation” property
17
- # defaults to :horizontal.
18
- if options.size >= 1
19
- @grid.add(widget)
20
- end
21
-
22
- unless options[:attach_to].nil?
23
- return
24
- @grid.attach_next_to()
25
- else
26
- @grid.attach(widget, grid_left, grid_top, grid_width, grid_height)
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,33 +0,0 @@
1
- module MittensUi
2
- module Widgets
3
- class Alert
4
- def initialize(message, options)
5
- dialog_options = {
6
- title: options[:title] || "Alert",
7
- parent: $app_window,
8
- flags: [:modal, :destroy_with_parent],
9
- :buttons => [[Gtk::Stock::OK, :none]]
10
- }.freeze
11
-
12
- alert_dialog = Gtk::Dialog.new(dialog_options)
13
- alert_dialog.set_transient_for($app_window)
14
- alert_dialog.set_default_width(420)
15
- alert_dialog.set_default_height(200)
16
- alert_dialog.set_modal(true)
17
- alert_dialog.set_resizable(false)
18
-
19
- message_label = Gtk::Label.new(message)
20
- message_label.set_margin_top(65)
21
-
22
- dialog_box = alert_dialog.content_area
23
- dialog_box.add(message_label)
24
-
25
- alert_dialog.show_all
26
-
27
- response = alert_dialog.run
28
-
29
- response == :none ? alert_dialog.destroy : alert_dialog.destroy
30
- end
31
- end
32
- end
33
- end
@@ -1,25 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Button < Core
6
- def initialize(options={})
7
- button_title = options[:title] || "Button"
8
-
9
- @button = Gtk::Button.new(label: button_title)
10
-
11
- set_margin_from_opts_for(@button, options)
12
-
13
- $vertical_box.pack_start(@button)
14
-
15
- super(@button)
16
- end
17
-
18
- def click
19
- @button.signal_connect("clicked") do |button_widget|
20
- yield(button_widget)
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,28 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Checkbox < Core
6
- attr_accessor :value
7
-
8
- def initialize(options={})
9
- label = options[:label] || "Checkbox"
10
-
11
- @value = nil
12
- @checkbox = Gtk::CheckButton.new(label)
13
-
14
- set_margin_from_opts_for(@checkbox, options)
15
-
16
- $vertical_box.pack_start(@checkbox)
17
-
18
- super(@checkbox)
19
- end
20
-
21
- def toggle
22
- @checkbox.signal_connect "toggled" do
23
- yield
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,32 +0,0 @@
1
- require "mittens_ui/helpers"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Core
6
- include Helpers
7
-
8
- # All MittenUi::Widgets::* classes should inherit from this base class.
9
-
10
- def initialize(widget)
11
- @core_widget = widget
12
- end
13
-
14
- def show
15
- @core_widget.show_all
16
- end
17
-
18
- def hidden?
19
- @core_widget.visible?
20
- end
21
-
22
- def hide
23
- return if @core_widget.nil?
24
- @core_widget.hide
25
- end
26
-
27
- def remove
28
- $vertical_box.remove(@core_widget)
29
- end
30
- end
31
- end
32
- end
@@ -1,36 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Image < Core
6
- attr_reader :path
7
-
8
- def initialize(path, options = {})
9
- @path = File.join(path.strip)
10
-
11
- tooltip_text = options[:tooltip_text].nil? ? "" : options[:tooltip_text]
12
- width = options[:width].nil? ? 80 : options[:width]
13
- height = options[:height].nil? ? 80 : options[:height]
14
-
15
- pixbuf = GdkPixbuf::Pixbuf.new(file: @path, width: width, height: height)
16
-
17
- @image = Gtk::Image.new(pixbuf: pixbuf)
18
- @image.tooltip_text = tooltip_text
19
-
20
- set_margin_from_opts_for(@image, options)
21
-
22
- @event_box = Gtk::EventBox.new.add_child(@image)
23
-
24
- $vertical_box.pack_start(@event_box)
25
-
26
- super(@image)
27
- end
28
-
29
- def click
30
- @event_box.signal_connect("button_press_event") do
31
- yield
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,21 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Label < Core
6
- def initialize(text, options)
7
- if text.nil? || text == "" || text == " "
8
- text = "Label"
9
- end
10
-
11
- @label = Gtk::Label.new(text)
12
-
13
- set_margin_from_opts_for(@label, options)
14
-
15
- $vertical_box.pack_start(@label)
16
-
17
- super(@label)
18
- end
19
- end
20
- end
21
- end
@@ -1,45 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class ListBox < Core
6
- attr_reader :items
7
-
8
- def initialize(options={})
9
- @items = options[:items]
10
-
11
- list_store = Gtk::ListStore.new(String)
12
-
13
- @items.each do |i|
14
- iter = list_store.append
15
- iter[0] = i
16
- end
17
-
18
- renderer = Gtk::CellRendererText.new
19
-
20
- @gtk_combobox = Gtk::ComboBox.new(model: list_store)
21
- @gtk_combobox.pack_start(renderer, true)
22
- @gtk_combobox.set_attributes(renderer, "text" => 0)
23
- @gtk_combobox.set_cell_data_func(renderer) do |_layout, _cell_renderer, _model, iter|
24
- set_selected_value(iter[0])
25
- end
26
-
27
- @gtk_combobox.set_active(0)
28
-
29
- $vertical_box.pack_start(@gtk_combobox)
30
-
31
- super(@gtk_combobox)
32
- end
33
-
34
- def set_selected_value(value)
35
- @selected_value = value
36
- end
37
- alias :set_value :set_selected_value
38
-
39
- def get_selected_value
40
- @selected_value
41
- end
42
- alias :selected_value :get_selected_value
43
- end
44
- end
45
- end
@@ -1,34 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Loader < Core
6
- def initialize(options={})
7
- @spinner = Gtk::Spinner.new
8
-
9
- @processing = false
10
-
11
- set_margin_from_opts_for(@spinner, options)
12
-
13
- $vertical_box.pack_end(@spinner)
14
-
15
- super(@spinner)
16
-
17
- self.hide
18
- end
19
-
20
- def start(&block)
21
- return if @processing
22
-
23
- return if @worker_thread && @worker_thread.alive?
24
-
25
- self.show
26
-
27
- @spinner.start
28
-
29
- @worker_thread = Thread.new { yield; self.remove; @processing = true }
30
- end
31
-
32
- end
33
- end
34
- end
@@ -1,31 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Slider < Core
6
- def initialize(options={})
7
- start_value = options[:start_value].nil? ? 1.0 : options[:start_value]
8
- stop_value = options[:stop_value].nil? ? 10.0 : options[:stop_value]
9
- step_value = options[:step_value].nil? ? 1.0 : options[:step_value]
10
- init_value = options[:initial_value].nil? ? 1.0 : options[:initial_value]
11
-
12
- @scale = Gtk::Scale.new(:horizontal, start_value, stop_value, step_value)
13
- @scale.digits = 0
14
- @scale.draw_value = true
15
- @scale.value = init_value
16
-
17
- $vertical_box.pack_start(@scale)
18
-
19
- super(@scale)
20
- end
21
-
22
- def move
23
- @scale.signal_connect "value_changed" do |scale_widget|
24
- yield(scale_widget)
25
- end
26
- end
27
-
28
- alias :slide :move
29
- end
30
- end
31
- end
@@ -1,37 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class Switch < Core
6
- def initialize(options = {})
7
- @switch = Gtk::Switch.new
8
- @switch.set_active(false)
9
-
10
- set_margin_from_opts_for(@switch, options)
11
-
12
- # We need a Grid within our global $vertical_box layout
13
- # in order to make the Widget look good (meaning not overly streched).
14
- grid = Gtk::Grid.new
15
- grid.set_column_spacing(1)
16
- grid.set_row_spacing(1)
17
- grid.attach(@switch, 0, 0, 1, 1)
18
-
19
- $vertical_box.pack_start(grid)
20
-
21
- super(@switch)
22
- end
23
-
24
- def activate
25
- @switch.signal_connect('notify::active') do |switch_widget|
26
- switch_widget.active? ? switch_widget.set_active(true) : switch_widget.set_active(false)
27
- yield
28
- end
29
- end
30
- alias :on :activate
31
-
32
- def status
33
- @switch.active? ? 'on' : 'off'
34
- end
35
- end
36
- end
37
- end
@@ -1,159 +0,0 @@
1
- require_relative "./core"
2
-
3
- module MittensUi
4
- module Widgets
5
- class TableView < Core
6
- def initialize(options={})
7
- headers = options[:headers] || []
8
- data = options[:data] || []
9
-
10
- unless is_data_valid?(headers, data)
11
- exit 1
12
- end
13
-
14
- init_column_headers(headers)
15
-
16
- init_list_store
17
-
18
- @tree_view = Gtk::TreeView.new(@list_store)
19
- @tree_view.selection.set_mode(:single)
20
-
21
- @columns.each { |col| @tree_view.append_column(col) }
22
-
23
- init_sortable_columns
24
-
25
- init_data_rows(data)
26
-
27
- $vertical_box.pack_start(@tree_view)
28
-
29
- super(@tree_view)
30
- end
31
-
32
- def add(data, direction=:append)
33
- return if data.size.zero?
34
-
35
- case direction
36
- when :append
37
- iter = @list_store.append
38
- when :prepend
39
- iter = @list_store.prepend
40
- else
41
- iter = @list_store.append
42
- end
43
-
44
- data.each_with_index do |item, idx|
45
- iter[idx] = item
46
- end
47
- end
48
-
49
- def clear
50
- @list_store.clear
51
- end
52
-
53
-
54
- def row_count
55
- count = 0
56
- @list_store.each { |item| count += 1 }
57
-
58
- return count
59
- end
60
-
61
- def remove_selected
62
- iter = @tree_view.selection.selected
63
- iter ? @list_store.remove(iter) : nil
64
- end
65
-
66
- def row_clicked
67
- @tree_view.signal_connect("row-activated") do |tv, path, column|
68
- row = tv.selection.selected
69
-
70
- values = []
71
-
72
- @list_store.n_columns.times { |x| values << row.get_value(x) if row }
73
-
74
- yield(values)
75
- end
76
- end
77
-
78
- private
79
-
80
- def is_data_valid?(headers, data)
81
- column_size = headers.size
82
-
83
- data_is_array = data.class == Array
84
- headers_is_array = headers.class == Array
85
-
86
- valid = true
87
-
88
- unless data_is_array
89
- puts "=====[MittensUi: Critical Error]====="
90
- puts "Incoming data must be an Array of Arrays: data = [ [el..], [el...] ]"
91
- valid = false
92
- return valid
93
- end
94
-
95
- unless headers_is_array
96
- puts "=====[MittensUi: Critical Error]====="
97
- puts "Incoming data must be an Array of Arrays: data = [ [el..], [el...] ]"
98
- valid = false
99
- return valid
100
- end
101
-
102
- data.each_with_index do |row, idx|
103
- # Row data must be an Array.
104
- # The size of the Row Array must match the size of the Header columns.
105
- valid = row.class == Array && column_size == row.size ? true : false
106
-
107
- unless valid
108
- puts
109
- puts "=====[MittensUi: Critical Error]====="
110
- puts "The length of your data(Row) must match the length of the headers."
111
- puts "Failed at Row: #{idx}"
112
- puts "Row Length: #{row.size} elements"
113
- puts "Header Length #{column_size} elements"
114
- puts
115
- return valid
116
- end
117
- end
118
- end
119
-
120
- def init_sortable_columns
121
- @columns.each_with_index do |col, idx|
122
- col.sort_indicator = true
123
- col.sort_column_id = idx
124
-
125
- col.signal_connect('clicked') do |w|
126
- w.sort_order = w.sort_order == :ascending ? :descending : :ascending
127
- end
128
- end
129
- end
130
-
131
- def init_list_store
132
- types = []
133
- @columns.size.times { types << String }
134
- @list_store = Gtk::ListStore.new(*types)
135
- end
136
-
137
- def init_data_rows(data)
138
- data.each_with_index do |items_arr|
139
- iter = @list_store.append
140
- items_arr.each_with_index do |item, idx|
141
- iter[idx] = item
142
- end
143
- end
144
- end
145
-
146
- def init_column_headers(headers_list)
147
- renderer = Gtk::CellRendererText.new
148
-
149
- @columns = []
150
-
151
- headers_list.each_with_index do |h, i|
152
- next unless h.class == String
153
- @columns << Gtk::TreeViewColumn.new(h, renderer, text: i)
154
- end
155
- end
156
-
157
- end
158
- end
159
- end