mittens_ui 0.0.7 → 0.0.11

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +3 -1
  5. data/Gemfile.lock +5 -2
  6. data/LICENSE +21 -0
  7. data/README.md +78 -21
  8. data/examples/app.rb +101 -8
  9. data/examples/assets/gnome_logo.png +0 -0
  10. data/examples/assets/mittens_ui_preview.gif +0 -0
  11. data/examples/contacts.rb +80 -0
  12. data/examples/file_menu_example.rb +52 -0
  13. data/examples/notify_example.rb +19 -0
  14. data/lib/mittens_ui.rb +40 -67
  15. data/lib/mittens_ui/alert.rb +32 -0
  16. data/lib/mittens_ui/assets/icon.png +0 -0
  17. data/lib/mittens_ui/assets/mittens_ui_preview.gif +0 -0
  18. data/lib/mittens_ui/button.rb +40 -0
  19. data/lib/mittens_ui/checkbox.rb +24 -0
  20. data/lib/mittens_ui/core.rb +34 -0
  21. data/lib/mittens_ui/file_menu.rb +83 -0
  22. data/lib/mittens_ui/file_picker.rb +29 -0
  23. data/lib/mittens_ui/grid.rb +29 -0
  24. data/lib/mittens_ui/hbox.rb +56 -0
  25. data/lib/mittens_ui/header_bar.rb +46 -0
  26. data/lib/mittens_ui/helpers.rb +41 -0
  27. data/lib/mittens_ui/image.rb +46 -0
  28. data/lib/mittens_ui/label.rb +19 -0
  29. data/lib/mittens_ui/listbox.rb +47 -0
  30. data/lib/mittens_ui/loader.rb +33 -0
  31. data/lib/mittens_ui/notify.rb +61 -0
  32. data/lib/mittens_ui/slider.rb +32 -0
  33. data/lib/mittens_ui/switch.rb +36 -0
  34. data/lib/mittens_ui/table_view.rb +179 -0
  35. data/lib/mittens_ui/textbox.rb +53 -0
  36. data/lib/mittens_ui/version.rb +1 -1
  37. data/lib/mittens_ui/web_link.rb +22 -0
  38. data/mittens_ui.gemspec +3 -3
  39. data/notes/dev_setup.txt +14 -0
  40. metadata +37 -16
  41. data/examples/brightness_controller.rb +0 -64
  42. data/lib/mittens_ui/layouts/box.rb +0 -38
  43. data/lib/mittens_ui/layouts/grid.rb +0 -31
  44. data/lib/mittens_ui/widgets/alert.rb +0 -33
  45. data/lib/mittens_ui/widgets/button.rb +0 -34
  46. data/lib/mittens_ui/widgets/label.rb +0 -41
  47. data/lib/mittens_ui/widgets/listbox.rb +0 -45
  48. data/lib/mittens_ui/widgets/slider.rb +0 -32
  49. data/lib/mittens_ui/widgets/switch.rb +0 -57
  50. data/lib/mittens_ui/widgets/textbox.rb +0 -25
@@ -0,0 +1,19 @@
1
+ require '../lib/mittens_ui'
2
+
3
+ app_options = {
4
+ name: "notify_example",
5
+ title: "Notify This",
6
+ height: 615,
7
+ width: 570,
8
+ can_resize: true
9
+ }.freeze
10
+
11
+
12
+ MittensUi::Application.Window(app_options) do
13
+ btn = MittensUi::Button.new(title: "Notify Me")
14
+ btn.render
15
+
16
+ btn.click do
17
+ MittensUi::Notify.new("Updated!").render
18
+ end
19
+ end
data/lib/mittens_ui.rb CHANGED
@@ -1,74 +1,65 @@
1
1
  require "mittens_ui/version"
2
- require "mittens_ui/widgets/alert"
3
- require "mittens_ui/widgets/label"
4
- require "mittens_ui/widgets/button"
5
- require "mittens_ui/widgets/textbox"
6
- require "mittens_ui/widgets/listbox"
7
- require "mittens_ui/widgets/slider"
8
- require "mittens_ui/widgets/switch"
2
+ require "mittens_ui/alert"
3
+ require "mittens_ui/label"
4
+ require "mittens_ui/button"
5
+ require "mittens_ui/textbox"
6
+ require "mittens_ui/listbox"
7
+ require "mittens_ui/slider"
8
+ require "mittens_ui/switch"
9
+ require "mittens_ui/image"
10
+ require "mittens_ui/checkbox"
11
+ require "mittens_ui/web_link"
12
+ require "mittens_ui/table_view"
13
+ require "mittens_ui/loader"
14
+ require "mittens_ui/header_bar"
15
+ require "mittens_ui/file_picker"
16
+ require "mittens_ui/file_menu"
17
+ require "mittens_ui/hbox"
18
+ require "mittens_ui/notify"
9
19
 
10
20
  require "gtk3"
11
21
 
12
22
  module MittensUi
13
-
14
23
  class Error < StandardError; end
15
24
 
16
- def self.Switch(options = {})
17
- MittensUi::Widgets::Switch.new(options)
18
- end
19
-
20
- def self.Slider(options = {})
21
- MittensUi::Widgets::Slider.new(options)
22
- end
23
-
24
- def self.ListBox(options = {})
25
- MittensUi::Widgets::ListBox.new(options)
26
- end
27
-
28
- def self.Alert(message, options = {})
29
- MittensUi::Widgets::Alert.new(message, options)
30
- end
31
-
32
- def self.Label(text, options = {})
33
- MittensUi::Widgets::Label.new(text, options)
34
- end
35
-
36
- def self.Textbox(options = {})
37
- MittensUi::Widgets::Textbox.new(options)
38
- end
39
-
40
- def self.Button(options = {})
41
- MittensUi::Widgets::Button.new(options)
42
- end
43
-
44
- def self.RemoveWidget(widget)
45
- widget.remove
46
- end
47
-
48
25
  class Application
49
26
  class << self
50
- def Window(options = {}, &block)
51
- init_gtk_application(options, block)
27
+ def Window(options = {}, &block)
28
+ init_gtk_application(options, &block)
29
+ end
30
+
31
+ def exit(&block)
32
+ begin
33
+ yield if block_given?
34
+ Kernel.exit(0)
35
+ rescue => _error
36
+ Kernel.exit(1)
37
+ end
52
38
  end
53
-
54
- private
39
+
40
+ private
55
41
 
56
42
  def set_process_name(name)
57
- # Doesn't work in MacOS Activity Monitor or Windows Task Manager. It shows up as "Ruby".
58
43
  Process.setproctitle(name)
59
44
  $PROGRAM_NAME = name
45
+ $0 = name
60
46
  end
61
47
 
62
- def init_gtk_application(options, block)
48
+ def init_gtk_application(options, &block)
63
49
  app_name = options[:name].nil? ? "mittens_ui_app" : options[:name]
64
50
  height = options[:height].nil? ? 600 : options[:height]
65
51
  width = options[:width].nil? ? 400 : options[:width]
66
52
  title = options[:title].nil? ? "Mittens App" : options[:title]
67
53
  can_resize = options[:can_resize].nil? ? true : options[:can_resize]
68
54
 
55
+ app_assets_path = File.join(File.expand_path(File.dirname(__FILE__)), "mittens_ui", "assets") + "/"
56
+ default_icon = app_assets_path + "icon.png"
57
+
58
+ app_icon = options[:icon].nil? ? default_icon : options[:icon]
59
+
69
60
  set_process_name(app_name)
70
61
 
71
- gtk_app_name = "org.gtk.mittens_ui.#{app_name}"
62
+ gtk_app_name = "org.mittens_ui.#{app_name}"
72
63
 
73
64
  app = Gtk::Application.new(gtk_app_name, :flags_none)
74
65
 
@@ -78,10 +69,11 @@ module MittensUi
78
69
  $vertical_box = Gtk::Box.new(:vertical, 10)
79
70
  scrolled_window.add($vertical_box)
80
71
  $app_window.add(scrolled_window)
81
- block.call($app_window, $vertical_box)
72
+ yield($app_window, $vertical_box)
82
73
  $app_window.set_size_request(width, height)
83
74
  $app_window.set_title(title)
84
75
  $app_window.set_resizable(can_resize)
76
+ $app_window.set_icon_from_file(app_icon)
85
77
  $app_window.show_all
86
78
  end
87
79
 
@@ -89,23 +81,4 @@ module MittensUi
89
81
  end
90
82
  end
91
83
  end
92
-
93
- class Job
94
- attr_reader :name, :status
95
-
96
- def initialize(name)
97
- @name = name
98
- @status = nil
99
- end
100
-
101
- def run(&block)
102
- job_t = Thread.new { |_t| yield }
103
- set_status(job_t)
104
- end
105
-
106
- private
107
- def set_status(thread)
108
- @status = thread.status
109
- end
110
- end
111
84
  end
@@ -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
@@ -0,0 +1,40 @@
1
+ require_relative "./core"
2
+ require "mittens_ui/helpers"
3
+
4
+ module MittensUi
5
+ class Button < Core
6
+ include Helpers
7
+
8
+ def initialize(options={})
9
+ button_title = options[:title] || "Button"
10
+
11
+ icon_type = options[:icon] || nil
12
+
13
+ if icon_type
14
+ image = Gtk::Image.new(icon_name: icon_map[icon_type], size: @button)
15
+ @button = Gtk::Button.new
16
+ @button.add(image)
17
+ else
18
+ @button = Gtk::Button.new(label: button_title)
19
+ end
20
+
21
+ super(@button, options)
22
+ end
23
+
24
+ def enable(answer)
25
+ @button.set_sensitive(answer)
26
+ end
27
+
28
+ def click
29
+ @button.signal_connect("clicked") do |button_widget|
30
+ yield(button_widget)
31
+ end
32
+ end
33
+
34
+ def render
35
+ $vertical_box.pack_start(@button)
36
+ return self
37
+ end
38
+
39
+ end
40
+ 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,83 @@
1
+ require_relative "./core"
2
+
3
+ module MittensUi
4
+ class FileMenu < Core
5
+ def initialize(menu_items, options = {})
6
+ @menu_items = menu_items
7
+
8
+ @menu_bar = Gtk::MenuBar.new
9
+
10
+ # menu_name => menu_item(gtk)
11
+ @raw_menu_items = {}
12
+
13
+ associate_menu_items
14
+
15
+ create_menu_methods
16
+
17
+ super(@menu_bar, options)
18
+ end
19
+
20
+ def render
21
+ $vertical_box.pack_start(@menu_bar)
22
+ return self
23
+ end
24
+
25
+ private
26
+
27
+ def create_menu_methods
28
+ @raw_menu_items.each do |menu_label, menu_item|
29
+ menu_label = menu_label.downcase.gsub(/ /, "_").to_sym
30
+
31
+ define_singleton_method(menu_label) do |&blk|
32
+ menu_item.signal_connect("activate") do
33
+ blk.call(self)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def associate_menu_items
40
+ @menu_items.each do |root_menu_label, menu_item_data|
41
+ root_menu = Gtk::Menu.new
42
+
43
+ root_menu_item = Gtk::MenuItem.new(label: root_menu_label.to_s)
44
+ root_menu_item.set_submenu(root_menu)
45
+
46
+ next unless menu_item_data.is_a?(Hash)
47
+
48
+ menu_item_data.each do |sub_menus_key, sub_menus_item_data|
49
+ next unless sub_menus_key.to_sym == :sub_menus
50
+ sub_menus_item_data.each do |sub_menu_data|
51
+ sub_menu_data.is_a?(String) ? create_root_menu(sub_menu_data.to_s, root_menu) : nil
52
+ sub_menu_data.is_a?(Hash) ? create_sub_menu(sub_menu_data, root_menu) : nil
53
+ end
54
+ end
55
+
56
+ @menu_bar.append(root_menu_item)
57
+ end
58
+ end
59
+
60
+ def create_sub_menu(hsh, root_menu)
61
+ hsh.each do |sub_menu_label, sub_menu_data|
62
+ sub_menu = Gtk::Menu.new
63
+ sub_menu_item = Gtk::MenuItem.new(label: sub_menu_label.to_s)
64
+ sub_menu_item.set_submenu(sub_menu)
65
+ root_menu.append(sub_menu_item)
66
+
67
+ if sub_menu_data.is_a?(Array)
68
+ sub_menu_data.each do |label|
69
+ nested_sub_item = Gtk::MenuItem.new(label: label.to_s)
70
+ sub_menu.append(nested_sub_item)
71
+ @raw_menu_items[label.to_s] = nested_sub_item
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def create_root_menu(label, root_menu)
78
+ menu_item = Gtk::MenuItem.new(label: label)
79
+ root_menu.append(menu_item)
80
+ @raw_menu_items[label] = menu_item
81
+ end
82
+ end
83
+ 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