Skip to content

Commit ac2660d

Browse files
committed
Merge pull request #13 from dmacvicar/dmacvicar_selection_widgets
Implement selection widgets and items Thanks for patch
2 parents 0f50841 + 26ad4d3 commit ac2660d

36 files changed

+1867
-18
lines changed

README.rdoc

+6-3
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,16 @@ There is basically three ways how to handle events. It is possible to handle it
6363
define callbacks on widgets or combination of both approach. Events are documented in
6464
#UI::Event and its ancestor.
6565

66-
=== Events Examples
66+
=== Waiting for an event
6767

68-
simple example with event loop
68+
You can use Dialog#wait_for_event to wait and capture the next event.
6969

7070
{include:file:examples/basic_event.rb}
7171

72-
Example with event loop in block
72+
=== Ruby block as an event loop
73+
74+
You can also provide a block to Dialog#wait_for_event and a loop will be started, passing
75+
each event as a parameter to the block.
7376

7477
{include:file:examples/loop_event.rb}
7578

examples/selection_box.rb

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
$: << File.expand_path(File.join(File.dirname(__FILE__), '../lib'))
2+
require 'ui'
3+
require 'ui/builder/slim'
4+
require 'pp'
5+
#require 'debugger'
6+
7+
dialog = UI.main_dialog {
8+
vbox(:id => :vbox1) {
9+
selection_box "Elements", :id => :box
10+
right {
11+
push_button "Close", :id => :cancel
12+
}
13+
}
14+
}
15+
16+
class DumbClass
17+
def to_s
18+
"LOL!"
19+
end
20+
end
21+
22+
box = dialog.find(:box)
23+
24+
item = UI::Item.new("Hello")
25+
26+
box << "Bye"
27+
box << item
28+
box << DumbClass.new
29+
30+
box[:Notify] = true
31+
box.selection_changed do |ev|
32+
UI.debug "changed"
33+
UI::Dialog.show_text("Selected: #{box.selected_item}")
34+
end
35+
36+
count = 0
37+
dialog.wait_for_event do |ev|
38+
UI.debug ev.inspect
39+
#
40+
break if ev.widget.id == :cancel
41+
break if ev.cancel? || count > 10
42+
count += 1
43+
true
44+
end

examples/widget_gallery.rb

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
$: << File.expand_path(File.join(File.dirname(__FILE__), '../lib'))
2+
require 'ui'
3+
require 'ui/builder/slim'
4+
require 'pp'
5+
#require 'debugger'
6+
7+
dialog = UI.main_dialog {
8+
vbox {
9+
# row 1
10+
hbox(:id => :hbox1) {
11+
frame("PushButton", :Weight => 1) {
12+
hvcenter {
13+
vbox {
14+
push_button "Enabled"
15+
push_button "Disabled", :Enabled => false
16+
}
17+
}
18+
}
19+
frame("Label", :Weight => 1) {
20+
hvcenter {
21+
vbox {
22+
label "Headline"
23+
label "Label"
24+
}
25+
}
26+
}
27+
frame("CheckBox", :Weight => 1) {
28+
hvcenter {
29+
vbox {
30+
check_box "Check0"
31+
check_box "Check1"
32+
check_box "Disabled", :Enabled => false
33+
}
34+
}
35+
}
36+
frame("RadioButton", :Weight => 1) {
37+
hvcenter {
38+
radio_button_group {
39+
vbox {
40+
radio_button "Radio0"
41+
radio_button "Radio1"
42+
radio_button "Disabled", :Enabled => false
43+
}
44+
}
45+
}
46+
}
47+
}
48+
}
49+
}
50+
51+
count = 0
52+
dialog.wait_for_event do |ev|
53+
break if ev.cancel? || count > 10
54+
count += 1
55+
true
56+
end

ext/ui/alignment.cc

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "widget.h"
2+
#include "alignment.h"
3+
4+
static void
5+
dealloc(YAlignment *align)
6+
{
7+
widget_object_map_remove(align);
8+
}
9+
10+
VALUE
11+
ui_wrap_alignment(YAlignment*align)
12+
{
13+
return Data_Wrap_Struct(cUIAlignment, ui_widget_mark, dealloc, align);
14+
}
15+
16+
VALUE cUIAlignment;
17+
void init_ui_alignment()
18+
{
19+
VALUE ui = rb_define_module("UI");
20+
21+
VALUE klass = rb_define_class_under(ui, "Alignment", cUIWidget);
22+
cUIAlignment = klass;
23+
}
24+

ext/ui/alignment.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef RUBY_NATIVE_UI_ALIGNMENT_H
2+
#define RUBY_NATIVE_UI_ALIGNMENT_H
3+
4+
#include <yui/YAlignment.h>
5+
#include "ui.h"
6+
7+
void init_ui_alignment();
8+
9+
extern VALUE cUIAlignment;
10+
VALUE ui_wrap_alignment(YAlignment *align);
11+
12+
#endif

ext/ui/callback_filter.cc

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ YEvent * CallbackFilter::filter (YEvent * event)
2727
method = rb_intern("value_changed_fire");
2828
break;
2929
}
30+
case YEvent::SelectionChanged:
31+
{
32+
method = rb_intern("selection_changed_fire");
33+
break;
34+
}
3035
}
3136
if (NIL_P(method))
3237
return event;

ext/ui/check_box.cc

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#include "widget.h"
2+
#include "check_box.h"
3+
#include "exception_guard.h"
4+
5+
static void
6+
dealloc(YCheckBox *box)
7+
{
8+
widget_object_map_remove(box);
9+
}
10+
11+
VALUE
12+
ui_wrap_check_box(YCheckBox *box)
13+
{
14+
return Data_Wrap_Struct(cUICheckBox, ui_widget_mark, dealloc, box);
15+
}
16+
17+
static YCheckBox *
18+
ui_unwrap_check_box(VALUE box)
19+
{
20+
YCheckBox *ptr = 0L;
21+
Data_Get_Struct(box, YCheckBox, ptr);
22+
return ptr;
23+
}
24+
25+
/**
26+
* @return [Boolean] Current on/off value:
27+
* +true+ if checked, +false+ if unchecked.
28+
* +nil+ if don't care (tri-state)
29+
*/
30+
static VALUE
31+
get_value(VALUE self)
32+
{
33+
YEXCEPTION_TRY
34+
YCheckBox *ptr = ui_unwrap_check_box(self);
35+
switch(ptr->value())
36+
{
37+
case YCheckBox_on:
38+
return Qtrue;
39+
case YCheckBox_off:
40+
return Qfalse;
41+
default:
42+
return Qnil;
43+
}
44+
YEXCEPTION_CATCH
45+
}
46+
47+
/**
48+
* Get the current value:
49+
* @return [Boolean] true if CheckBox is checked
50+
* @return [Boolean] false if CheckBox is unchecked
51+
* @return [nil] tri-state: CheckBox is greyed out,
52+
* neither checked nor unchecked
53+
*
54+
* The user cannot set the 3rd state directly. This status is always
55+
* only set from the outside, usually because a setting cannot be clearly
56+
* determined. For example, a checkbox
57+
*
58+
* [ ] Read only
59+
*
60+
* would be set to "don't care" (by the application, not directly by the
61+
* user) when it is to display the read-only state of a group of files
62+
* where some are read-only and some are writeable.
63+
*
64+
*/
65+
static VALUE
66+
set_value(VALUE self, VALUE val)
67+
{
68+
YEXCEPTION_TRY
69+
YCheckBox *ptr = ui_unwrap_check_box(self);
70+
if (NIL_P(val)) {
71+
ptr->setValue(YCheckBox_dont_care);
72+
}
73+
else {
74+
ptr->setValue(RTEST(val) ? YCheckBox_on : YCheckBox_off);
75+
}
76+
YEXCEPTION_CATCH
77+
}
78+
79+
/**
80+
* @return [String] the label (the text on the CheckBox)
81+
*/
82+
static VALUE
83+
get_label(VALUE self)
84+
{
85+
YEXCEPTION_TRY
86+
YCheckBox *ptr = ui_unwrap_check_box(self);
87+
return rb_str_new2(ptr->label().c_str());
88+
YEXCEPTION_CATCH
89+
}
90+
91+
/**
92+
* Set the label (the text on the CheckBox).
93+
*/
94+
static VALUE
95+
set_label(VALUE self, VALUE label)
96+
{
97+
YEXCEPTION_TRY
98+
YCheckBox *ptr = ui_unwrap_check_box(self);
99+
ptr->setLabel(StringValueCStr(label));
100+
YEXCEPTION_CATCH
101+
}
102+
103+
/**
104+
* @return [Boolean] true if a bold font should be used.
105+
*/
106+
static VALUE
107+
get_use_bold_font(VALUE self)
108+
{
109+
YEXCEPTION_TRY
110+
YCheckBox *ptr = ui_unwrap_check_box(self);
111+
return ptr->useBoldFont() ? Qtrue : Qfalse;
112+
YEXCEPTION_CATCH
113+
}
114+
115+
/**
116+
* Indicate whether or not a bold font should be used.
117+
*/
118+
static VALUE
119+
set_use_bold_font(VALUE self, VALUE use)
120+
{
121+
YEXCEPTION_TRY
122+
YCheckBox *ptr = ui_unwrap_check_box(self);
123+
ptr->setUseBoldFont(RTEST(use));
124+
YEXCEPTION_CATCH
125+
}
126+
127+
/**
128+
* Simplified access to value()
129+
* @return [Boolean] true if the CheckBox is checked.
130+
*/
131+
static VALUE
132+
get_checked(VALUE self)
133+
{
134+
YEXCEPTION_TRY
135+
YCheckBox *ptr = ui_unwrap_check_box(self);
136+
return ptr->isChecked() ? Qtrue : Qfalse;
137+
YEXCEPTION_CATCH
138+
}
139+
140+
/**
141+
* Simplified access to setValue(): Check of uncheck the CheckBox.
142+
*/
143+
static VALUE
144+
set_checked(VALUE self, VALUE checked)
145+
{
146+
YEXCEPTION_TRY
147+
YCheckBox *ptr = ui_unwrap_check_box(self);
148+
ptr->setChecked(RTEST(checked));
149+
YEXCEPTION_CATCH
150+
}
151+
152+
153+
/**
154+
* Simplified access to tri-state ("don't care").
155+
* @return [Boolean] true if the CheckBox is "don't care".
156+
*/
157+
static VALUE
158+
get_dont_care(VALUE self)
159+
{
160+
YEXCEPTION_TRY
161+
YCheckBox *ptr = ui_unwrap_check_box(self);
162+
return ptr->dontCare() ? Qtrue : Qfalse;
163+
YEXCEPTION_CATCH
164+
}
165+
166+
/**
167+
* Simplified access to setting tri-state ("don't care").
168+
*/
169+
static VALUE
170+
set_dont_care(VALUE self)
171+
{
172+
YEXCEPTION_TRY
173+
YCheckBox *ptr = ui_unwrap_check_box(self);
174+
ptr->setDontCare();
175+
YEXCEPTION_CATCH
176+
}
177+
178+
VALUE cUICheckBox;
179+
void init_ui_check_box()
180+
{
181+
VALUE ui = rb_define_module("UI");
182+
183+
VALUE klass = rb_define_class_under(ui, "CheckBox", cUIWidget);
184+
rb_define_method(klass, "value", RUBY_METHOD_FUNC(get_value), 0);
185+
rb_define_method(klass, "value=", RUBY_METHOD_FUNC(set_value), 1);
186+
rb_define_method(klass, "label", RUBY_METHOD_FUNC(get_label), 0);
187+
rb_define_method(klass, "label=", RUBY_METHOD_FUNC(set_label), 1);
188+
rb_define_method(klass, "use_bold_font?", RUBY_METHOD_FUNC(get_use_bold_font), 0);
189+
rb_define_method(klass, "use_bold_font=", RUBY_METHOD_FUNC(set_use_bold_font), 1);
190+
rb_define_method(klass, "checked?", RUBY_METHOD_FUNC(get_checked), 0);
191+
rb_define_method(klass, "checked=", RUBY_METHOD_FUNC(set_checked), 1);
192+
rb_define_method(klass, "dont_care?", RUBY_METHOD_FUNC(get_dont_care), 0);
193+
rb_define_method(klass, "dont_care!", RUBY_METHOD_FUNC(set_dont_care), 0);
194+
cUICheckBox = klass;
195+
196+
}
197+

ext/ui/check_box.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef RUBY_NATIVE_UI_CHECK_BOX_H
2+
#define RUBY_NATIVE_UI_CHECK_BOX_H
3+
4+
#include <yui/YCheckBox.h>
5+
#include "ui.h"
6+
7+
void init_ui_check_box();
8+
9+
extern VALUE cUICheckBox;
10+
VALUE ui_wrap_check_box(YCheckBox *box);
11+
12+
#endif

0 commit comments

Comments
 (0)