fidgit 0.0.2alpha

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 (87) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/COPYING.txt +674 -0
  4. data/Gemfile +4 -0
  5. data/README.textile +138 -0
  6. data/Rakefile +38 -0
  7. data/config/default_schema.yml +180 -0
  8. data/examples/_all_examples.rb +9 -0
  9. data/examples/align_example.rb +56 -0
  10. data/examples/button_and_toggle_button_example.rb +27 -0
  11. data/examples/color_picker_example.rb +17 -0
  12. data/examples/color_well_example.rb +25 -0
  13. data/examples/combo_box_example.rb +24 -0
  14. data/examples/file_dialog_example.rb +42 -0
  15. data/examples/grid_packer_example.rb +29 -0
  16. data/examples/helpers/example_window.rb +17 -0
  17. data/examples/label_example.rb +17 -0
  18. data/examples/list_example.rb +23 -0
  19. data/examples/media/images/head_icon.png +0 -0
  20. data/examples/menu_pane_example.rb +27 -0
  21. data/examples/message_dialog_example.rb +65 -0
  22. data/examples/radio_button_example.rb +37 -0
  23. data/examples/readme_example.rb +32 -0
  24. data/examples/scroll_window_example.rb +49 -0
  25. data/examples/slider_example.rb +30 -0
  26. data/examples/splash_example.rb +42 -0
  27. data/examples/text_area_example.rb +28 -0
  28. data/fidgit.gemspec +28 -0
  29. data/lib/fidgit.rb +4 -0
  30. data/lib/fidgit/chingu_ext/window.rb +6 -0
  31. data/lib/fidgit/clipboard.rb +23 -0
  32. data/lib/fidgit/cursor.rb +38 -0
  33. data/lib/fidgit/elements/button.rb +68 -0
  34. data/lib/fidgit/elements/color_picker.rb +63 -0
  35. data/lib/fidgit/elements/color_well.rb +39 -0
  36. data/lib/fidgit/elements/combo_box.rb +85 -0
  37. data/lib/fidgit/elements/composite.rb +17 -0
  38. data/lib/fidgit/elements/container.rb +187 -0
  39. data/lib/fidgit/elements/element.rb +252 -0
  40. data/lib/fidgit/elements/file_browser.rb +152 -0
  41. data/lib/fidgit/elements/grid_packer.rb +219 -0
  42. data/lib/fidgit/elements/group.rb +66 -0
  43. data/lib/fidgit/elements/horizontal_packer.rb +12 -0
  44. data/lib/fidgit/elements/label.rb +77 -0
  45. data/lib/fidgit/elements/list.rb +47 -0
  46. data/lib/fidgit/elements/menu_pane.rb +149 -0
  47. data/lib/fidgit/elements/packer.rb +42 -0
  48. data/lib/fidgit/elements/radio_button.rb +86 -0
  49. data/lib/fidgit/elements/scroll_area.rb +75 -0
  50. data/lib/fidgit/elements/scroll_bar.rb +114 -0
  51. data/lib/fidgit/elements/scroll_window.rb +92 -0
  52. data/lib/fidgit/elements/slider.rb +119 -0
  53. data/lib/fidgit/elements/text_area.rb +351 -0
  54. data/lib/fidgit/elements/toggle_button.rb +67 -0
  55. data/lib/fidgit/elements/tool_tip.rb +35 -0
  56. data/lib/fidgit/elements/vertical_packer.rb +12 -0
  57. data/lib/fidgit/event.rb +99 -0
  58. data/lib/fidgit/gosu_ext/color.rb +123 -0
  59. data/lib/fidgit/history.rb +85 -0
  60. data/lib/fidgit/redirector.rb +83 -0
  61. data/lib/fidgit/schema.rb +123 -0
  62. data/lib/fidgit/selection.rb +106 -0
  63. data/lib/fidgit/standard_ext/hash.rb +21 -0
  64. data/lib/fidgit/states/dialog_state.rb +42 -0
  65. data/lib/fidgit/states/file_dialog.rb +24 -0
  66. data/lib/fidgit/states/gui_state.rb +301 -0
  67. data/lib/fidgit/states/message_dialog.rb +61 -0
  68. data/lib/fidgit/thumbnail.rb +29 -0
  69. data/lib/fidgit/version.rb +5 -0
  70. data/lib/fidgit/window.rb +19 -0
  71. data/media/images/arrow.png +0 -0
  72. data/media/images/file_directory.png +0 -0
  73. data/media/images/file_file.png +0 -0
  74. data/media/images/pixel.png +0 -0
  75. data/spec/fidgit/elements/helpers/helper.rb +3 -0
  76. data/spec/fidgit/elements/label_spec.rb +49 -0
  77. data/spec/fidgit/event_spec.rb +149 -0
  78. data/spec/fidgit/gosu_ext/color_spec.rb +130 -0
  79. data/spec/fidgit/gosu_ext/helpers/helper.rb +3 -0
  80. data/spec/fidgit/helpers/helper.rb +4 -0
  81. data/spec/fidgit/helpers/tex_play_helper.rb +9 -0
  82. data/spec/fidgit/history_spec.rb +144 -0
  83. data/spec/fidgit/redirector_spec.rb +78 -0
  84. data/spec/fidgit/schema_spec.rb +67 -0
  85. data/spec/fidgit/schema_test.yml +32 -0
  86. data/spec/fidgit/thumbnail_spec.rb +50 -0
  87. metadata +177 -0
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ # Container that auto-packs elements.
5
+ #
6
+ # @abstract
7
+ class Packer < Container
8
+ attr_reader :spacing_h, :spacing_v
9
+
10
+ # @param (see Container#initialize)
11
+ #
12
+ # @option (see Container#initialize)
13
+ def initialize(options = {})
14
+ options = {
15
+ }.merge! options
16
+
17
+ @spacing_h = options[:spacing_h] || options[:spacing] || default(:spacing_h)
18
+ @spacing_v = options[:spacing_v] || options[:spacing] || default(:spacing_v)
19
+
20
+ super(options)
21
+ end
22
+
23
+ protected
24
+ # Recalculate the size of the container.
25
+ # Should be overridden by any descendant that manages the positions of its children.
26
+ def layout
27
+ # This assumes that the container overlaps all the children.
28
+
29
+ # Move all children if we have moved.
30
+ @children.each.with_index do |child, index|
31
+ child.x = padding_left + x
32
+ child.y = padding_top + y
33
+ end
34
+
35
+ # Make us as wrap around the largest child.
36
+ rect.width = (@children.map {|c| c.width }.max || 0) + padding_left + padding_right
37
+ rect.height = (@children.map {|c| c.height }.max || 0) + padding_top + padding_bottom
38
+
39
+ super
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ class RadioButton < Button
5
+ attr_reader :group, :value
6
+
7
+ event :changed
8
+
9
+ def checked?; @checked; end
10
+
11
+ # @param (see Button#initialize)
12
+ # @param [Object] value
13
+ #
14
+ # @option (see Button#initialize)
15
+ # @option options [Boolean] :checked
16
+ def initialize(text, value, options = {}, &block)
17
+ options = {
18
+ checked: false,
19
+ checked_border_color: default(:checked, :border_color),
20
+ }.merge! options
21
+
22
+ @checked = options[:checked]
23
+ @value = value
24
+
25
+ super(text, options)
26
+
27
+ @checked_border_color = options[:checked_border_color].dup
28
+ @unchecked_border_color = border_color
29
+ add_to_group
30
+
31
+ @border_color = (checked? ? @checked_border_color : @unchecked_border_color).dup
32
+ end
33
+
34
+ def clicked_left_mouse_button(sender, x, y)
35
+ super
36
+ check
37
+ nil
38
+ end
39
+
40
+ # Check the button and update its group. This may uncheck another button in the group if one is selected.
41
+ def check
42
+ return if checked?
43
+
44
+ @checked = true
45
+ @group.value = value
46
+ @border_color = @checked_border_color.dup
47
+ publish :changed, @checked
48
+
49
+ nil
50
+ end
51
+
52
+ # Uncheck the button and update its group.
53
+ def uncheck
54
+ return unless checked?
55
+
56
+ @checked = false
57
+ @group.value = value
58
+ @border_color = @unchecked_border_color.dup
59
+ publish :changed, @checked
60
+
61
+ nil
62
+ end
63
+
64
+ protected
65
+ def parent=(parent)
66
+ @group.remove_button self if @parent
67
+ super(parent)
68
+ add_to_group if parent
69
+ parent
70
+ end
71
+
72
+ protected
73
+ def add_to_group
74
+ container = parent
75
+ while container and not container.is_a? Group
76
+ container = container.parent
77
+ end
78
+
79
+ raise "#{self.class.name} must be placed inside a group element" unless container
80
+
81
+ @group = container
82
+ @group.add_button self
83
+ nil
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ # A basic scrolling area. It is not managed in any way (use ScrollWindow for that).
5
+ class ScrollArea < Container
6
+ # @return [VerticalPacker] The content shown within this ScrollArea
7
+ attr_reader :content
8
+
9
+ def offset_x; x - @content.x; end
10
+ def offset_y; y - @content.y; end
11
+
12
+ def offset_x=(value)
13
+ @content.x = x - [[@content.width - width, value].min, 0].max
14
+ end
15
+
16
+ def offset_y=(value)
17
+ @content.y = y - [[@content.height - height, value].min, 0].max
18
+ end
19
+
20
+ # @option options [Number] :offset (0)
21
+ # @option options [Number] :offset_x (value of :offset option)
22
+ # @option options [Number] :offset_y (value of :offset option)
23
+ # @option options [Element] :owner The owner of the content, such as the scroll-window containing the content.
24
+ def initialize(options = {})
25
+ options = {
26
+ offset: 0,
27
+ owner: nil,
28
+ }.merge! options
29
+
30
+ @owner = options[:owner]
31
+
32
+ super(options)
33
+
34
+ @content = VerticalPacker.new(parent: self, padding: 0)
35
+
36
+ self.offset_x = options[:offset_x] || options[:offset]
37
+ self.offset_y = options[:offset_y] || options[:offset]
38
+ end
39
+
40
+ def hit_element(x, y)
41
+ # Only pass on mouse events if they are inside the window.
42
+ if hit?(x, y)
43
+ @content.hit_element(x, y) || self
44
+ else
45
+ nil
46
+ end
47
+ end
48
+
49
+ def recalc
50
+ super
51
+ # Always recalc our owner if our content resizes, even though our size can't change even if the content changes
52
+ # (may encourage ScrollWindow to show/hide scroll-bars, for example)
53
+ @owner.recalc if @owner
54
+ end
55
+
56
+ protected
57
+ def draw_foreground
58
+ $window.clip_to(*rect) do
59
+ @content.draw
60
+ end
61
+ end
62
+
63
+ protected
64
+ def post_init_block(&block)
65
+ case block.arity
66
+ when 1
67
+ yield @content
68
+ when 0
69
+ @content.instance_methods_eval &block
70
+ else
71
+ raise "block arity must be 0 or 1"
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,114 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ # @abstract
5
+ class ScrollBar < Composite
6
+ class Handle < Element
7
+ event :begin_drag
8
+ event :update_drag
9
+ event :end_drag
10
+
11
+ def drag?(button); button == :left; end
12
+
13
+ def initialize(options = {})
14
+ super options
15
+
16
+ subscribe :begin_drag do |sender, x, y|
17
+ # Store position of the handle when it starts to drag.
18
+ @drag_start_pos = [x - self.x, y - self.y]
19
+ end
20
+
21
+ subscribe :update_drag do |sender, x, y|
22
+ parent.parent.handle_dragged_to x - @drag_start_pos[0], y - @drag_start_pos[1]
23
+ end
24
+
25
+ subscribe :end_drag do
26
+ @drag_start_pos = nil
27
+ end
28
+ end
29
+ end
30
+
31
+ def initialize(options = {})
32
+ options = {
33
+ background_color: default(:background_color),
34
+ border_color: default(:border_color),
35
+ rail_width: default(:rail_width),
36
+ rail_color: default(:rail_color),
37
+ handle_color: default(:handle_color),
38
+ owner: nil,
39
+ }.merge! options
40
+
41
+ @owner = options[:owner]
42
+ @rail_thickness = options[:rail_width]
43
+ @rail_color = options[:rail_color]
44
+
45
+ super options
46
+
47
+ @handle_container = Container.new(parent: self, width: options[:width], height: options[:height]) do
48
+ @handle = Handle.new(parent: self, x: x, y: y, background_color: options[:handle_color])
49
+ end
50
+ end
51
+ end
52
+
53
+ class HorizontalScrollBar < ScrollBar
54
+ attr_reader :owner
55
+
56
+ def initialize(options = {})
57
+ super options
58
+
59
+ @handle.height = height
60
+
61
+ @handle_container.subscribe :left_mouse_button do |sender, x, y|
62
+ distance = @owner.view_width
63
+ @owner.offset_x += (x > @handle.x)? +distance : -distance
64
+ end
65
+ end
66
+
67
+ def update
68
+ window = parent.parent
69
+
70
+ # Resize and re-locate the handles based on changes to the scroll-window.
71
+ content_width = window.content_width.to_f
72
+ @handle.width = (window.view_width * width) / content_width
73
+ @handle.x = x + (window.offset_x * width) / content_width
74
+ end
75
+
76
+ def draw_foreground
77
+ draw_rect x + padding_left, y + (height - @rail_thickness) / 2, width, @rail_thickness, z, @rail_color
78
+ super
79
+ end
80
+
81
+ def handle_dragged_to(x, y)
82
+ @owner.offset_x = @owner.content_width * ((x - self.x) / width.to_f)
83
+ end
84
+ end
85
+
86
+ class VerticalScrollBar < ScrollBar
87
+ def initialize(options = {})
88
+ super options
89
+
90
+ @handle.width = width
91
+
92
+ @handle_container.subscribe :left_mouse_button do |sender, x, y|
93
+ distance = @owner.view_height
94
+ @owner.offset_y += (y > @handle.y)? +distance : -distance
95
+ end
96
+ end
97
+
98
+ def update
99
+ window = parent.parent
100
+ content_height = window.content_height.to_f
101
+ @handle.height = (window.view_height * height) / content_height
102
+ @handle.y = y + (window.offset_y * height) / content_height
103
+ end
104
+
105
+ def draw_foreground
106
+ draw_rect x + (width - @rail_thickness) / 2, y + padding_top, @rail_thickness, height, z, @rail_color
107
+ super
108
+ end
109
+
110
+ def handle_dragged_to(x, y)
111
+ @owner.offset_y = @owner.content_height * ((y - self.y) / height.to_f)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ class ScrollWindow < Composite
5
+ def content; @view.content; end
6
+
7
+ def offset_x; @view.offset_x; end
8
+ def offset_x=(value); @view.offset_x = value; end
9
+ def offset_y; @view.offset_y; end
10
+ def offset_y=(value); @view.offset_y = value; end
11
+
12
+ def view_width; @view.width; end
13
+ def view_height; @view.height; end
14
+ def content_width; @view.content.width; end
15
+ def content_height; @view.content.height; end
16
+
17
+ def width=(value); super(value); end
18
+ def height=(value); super(value); end
19
+
20
+ def initialize(options = {})
21
+ options = {
22
+ scroll_bar_thickness: default(:scroll_bar_thickness),
23
+ }.merge! options
24
+
25
+ super(options)
26
+
27
+ @grid = pack :grid, num_columns: 2, padding: 0, spacing: 0 do
28
+ @view = scroll_area(owner: self, width: options[:width], height: options[:height])
29
+ @spacer = label '', padding: 0, width: 0, height: 0
30
+ end
31
+
32
+ @scroll_bar_v = VerticalScrollBar.new(owner: self, width: options[:scroll_bar_thickness], align_v: :fill)
33
+ @scroll_bar_h = HorizontalScrollBar.new(owner: self, height: options[:scroll_bar_thickness], align_h: :fill)
34
+ end
35
+
36
+ protected
37
+ def layout
38
+ # Prevent recursive layouts.
39
+ return if @in_layout
40
+
41
+ @in_layout = true
42
+
43
+ if @view
44
+ # Constrain the values of the offsets.
45
+ @view.offset_x = @view.offset_x
46
+ @view.offset_y = @view.offset_y
47
+
48
+ if content_height > view_height
49
+ unless @scroll_bar_v.parent
50
+ @view.send(:rect).width -= @scroll_bar_v.width
51
+ @grid.remove @spacer
52
+ @grid.insert 1, @scroll_bar_v
53
+ end
54
+ else
55
+ if @scroll_bar_v.parent
56
+ @view.send(:rect).width += @scroll_bar_v.width
57
+ @grid.remove @scroll_bar_v
58
+ @grid.insert 1, @spacer
59
+ end
60
+ end
61
+
62
+ if content_width > view_width
63
+ unless @scroll_bar_h.parent
64
+ @view.send(:rect).height -= @scroll_bar_h.height
65
+ @grid.add @scroll_bar_h
66
+ end
67
+ else
68
+ if @scroll_bar_h.parent
69
+ @view.send(:rect).height += @scroll_bar_h.height
70
+ @grid.remove @scroll_bar_h
71
+ end
72
+ end
73
+ end
74
+
75
+ super
76
+
77
+ @in_layout = false
78
+ end
79
+
80
+ protected
81
+ def post_init_block(&block)
82
+ case block.arity
83
+ when 1
84
+ yield @view.content
85
+ when 0
86
+ @view.content.instance_methods_eval &block
87
+ else
88
+ raise "block arity must be 0 or 1"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,119 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ class Slider < Composite
5
+ # @private
6
+ class Handle < Element
7
+ event :begin_drag
8
+ event :end_drag
9
+ event :update_drag
10
+
11
+ def drag?(button); button == :left; end
12
+
13
+ # @param (see Element#initialize)
14
+ #
15
+ # @option (see Element#initialize)
16
+ def initialize(options = {}, &block)
17
+ options = {
18
+ background_color: default(:background_color),
19
+ border_color: default(:border_color),
20
+ }.merge! options
21
+
22
+ super options
23
+
24
+ subscribe :begin_drag do |sender, x, y|
25
+ # Store position of the handle when it starts to drag.
26
+ @drag_start_pos = [x - self.x, y - self.y]
27
+ end
28
+
29
+ subscribe :update_drag do |sender, x, y|
30
+ parent.handle_dragged_to x - @drag_start_pos[0], y - @drag_start_pos[1]
31
+ end
32
+
33
+ subscribe :end_drag do
34
+ @drag_start_pos = nil
35
+ end
36
+ end
37
+ end
38
+
39
+ event :changed
40
+
41
+ attr_reader :value, :range
42
+
43
+ # @param (see Composite#initialize)
44
+ #
45
+ # @option (see Composite#initialize)
46
+ # @option options [Range] :range (0.0..1.0)
47
+ # @option options [Range] :value (minimum of :range)
48
+ def initialize(options = {}, &block)
49
+ options = {
50
+ range: 0.0..1.0,
51
+ height: 25,
52
+ background_color: default(:background_color),
53
+ border_color: default(:border_color),
54
+ groove_color: default(:groove_color),
55
+ handle_color: default(:handle_color),
56
+ groove_thickness: 5,
57
+ }.merge! options
58
+
59
+ @range = options[:range].dup
60
+ @groove_color = options[:groove_color].dup
61
+ @groove_thickness = options[:groove_thickness]
62
+ @continuous = @range.min.is_a?(Float) or @range.max.is_a?(Float)
63
+
64
+ super(options)
65
+
66
+ @handle = Handle.new(parent: self, width: (height / 2 - padding_left), height: height - padding_top + padding_bottom,
67
+ background_color: options[:handle_color])
68
+
69
+ self.value = options.has_key?(:value) ? options[:value] : @range.min
70
+ end
71
+
72
+ def value=(value)
73
+ @value = @continuous ? value.to_f : value.round
74
+ @value = [[@value, @range.min].max, @range.max].min
75
+ @handle.x = x + padding_left + ((width - @handle.width) * (@value - @range.min) / (@range.max - @range.min).to_f)
76
+ publish :changed, @value
77
+
78
+ @value
79
+ end
80
+
81
+ def tip
82
+ tip = super
83
+ tip.empty? ? @value.to_s : "#{tip}: #{@value}"
84
+ end
85
+
86
+ def left_mouse_button(sender, x, y)
87
+ # In this case, x should be the centre of the handle after it has moved.
88
+ self.value = ((x - (@handle.width / 2) - self.x) / (width - @handle.width)) * (@range.max - @range.min) + @range.min
89
+ @mouse_down = true
90
+
91
+ nil
92
+ end
93
+
94
+ def handle_dragged_to(x, y)
95
+ # In this case, x is the left-hand side fo the handle.
96
+ self.value = ((x - self.x) / (width - @handle.width)) * (@range.max - @range.min) + @range.min
97
+ end
98
+
99
+ protected
100
+ # Prevent standard packing layout change.
101
+ def layout
102
+ nil
103
+ end
104
+
105
+ protected
106
+ def draw_background
107
+ super
108
+ # Draw a groove for the handle to move along.
109
+ draw_rect x + (@handle.width / 2), y + (height - @groove_thickness) / 2, width - @handle.width, @groove_thickness, z, @groove_color
110
+ nil
111
+ end
112
+
113
+ protected
114
+ # Use block as an event handler.
115
+ def post_init_block(&block)
116
+ subscribe :changed, &block
117
+ end
118
+ end
119
+ end