|
| 1 | +#include <yui/YItem.h> |
| 2 | +#include "exception_guard.h" |
| 3 | +#include "widget.h" |
| 4 | +#include "item.h" |
| 5 | + |
| 6 | +typedef struct |
| 7 | +{ |
| 8 | + YItem *ptr; |
| 9 | + bool owned; |
| 10 | +} ItemWrapper; |
| 11 | + |
| 12 | +static void |
| 13 | +dealloc(ItemWrapper *wrapper) |
| 14 | +{ |
| 15 | + YEXCEPTION_TRY |
| 16 | + if (!wrapper->owned) { |
| 17 | + yuiDebug() << "unowned item, destroying..."; |
| 18 | + delete wrapper->ptr; |
| 19 | + } |
| 20 | + delete wrapper; |
| 21 | + YEXCEPTION_CATCH |
| 22 | +} |
| 23 | + |
| 24 | +static ItemWrapper * |
| 25 | + ui_item_wrapper(VALUE item) |
| 26 | +{ |
| 27 | + ItemWrapper *wrapper = 0L; |
| 28 | + |
| 29 | + Data_Get_Struct (item, ItemWrapper, wrapper); |
| 30 | + if (!wrapper) |
| 31 | + rb_raise(rb_eRuntimeError, "Item was already destroyed. Probably you destroyed its owning selection widget."); |
| 32 | + return wrapper; |
| 33 | +} |
| 34 | + |
| 35 | +VALUE |
| 36 | +ui_wrap_item(YItem *item) |
| 37 | +{ |
| 38 | + ItemWrapper *wrapper = new ItemWrapper; |
| 39 | + wrapper->ptr = item; |
| 40 | + wrapper->owned = false; |
| 41 | + return Data_Wrap_Struct(cUIItem, 0, dealloc, wrapper); |
| 42 | +} |
| 43 | + |
| 44 | +YItem * |
| 45 | +ui_unwrap_item(VALUE item) |
| 46 | +{ |
| 47 | + return ui_item_wrapper(item)->ptr; |
| 48 | +} |
| 49 | + |
| 50 | +// fwd decl |
| 51 | +static VALUE set_data(VALUE self, VALUE data); |
| 52 | + |
| 53 | +VALUE |
| 54 | +ui_object_to_item(VALUE object) { |
| 55 | + VALUE ui = rb_define_module("UI"); |
| 56 | + if (rb_class_of(object) == rb_const_get(ui, rb_intern("Item"))) |
| 57 | + return object; |
| 58 | + |
| 59 | + VALUE label = rb_funcall(object, rb_intern("to_s"), 0); |
| 60 | + VALUE item = rb_funcall(cUIItem, rb_intern("new"), 1, label); |
| 61 | + set_data(item, object); |
| 62 | + return item; |
| 63 | +} |
| 64 | + |
| 65 | +void |
| 66 | +ui_item_set_owned(VALUE object, bool owned) |
| 67 | +{ |
| 68 | + ui_item_wrapper(object)->owned = owned; |
| 69 | +} |
| 70 | + |
| 71 | +bool |
| 72 | +ui_item_is_owned(VALUE object) |
| 73 | +{ |
| 74 | + return ui_item_wrapper(object)->owned; |
| 75 | +} |
| 76 | + |
| 77 | +/* |
| 78 | + * @return [String] the item label |
| 79 | + */ |
| 80 | +static VALUE |
| 81 | +get_label(VALUE self) |
| 82 | +{ |
| 83 | + YEXCEPTION_TRY |
| 84 | + YItem *ptr = ui_unwrap_item(self); |
| 85 | + return rb_str_new2(ptr->label().c_str()); |
| 86 | + YEXCEPTION_CATCH |
| 87 | +} |
| 88 | + |
| 89 | +/* |
| 90 | + * Set the item label |
| 91 | + */ |
| 92 | +static VALUE |
| 93 | +set_label(VALUE self, VALUE label) |
| 94 | +{ |
| 95 | + YEXCEPTION_TRY |
| 96 | + YItem *ptr = ui_unwrap_item(self); |
| 97 | + ptr->setLabel(StringValueCStr(label)); |
| 98 | + return label; |
| 99 | + YEXCEPTION_CATCH |
| 100 | +} |
| 101 | + |
| 102 | +/* |
| 103 | + * @return [String] the item index |
| 104 | + */ |
| 105 | +static VALUE |
| 106 | +get_index(VALUE self) |
| 107 | +{ |
| 108 | + YEXCEPTION_TRY |
| 109 | + YItem *ptr = ui_unwrap_item(self); |
| 110 | + return INT2NUM(ptr->index()); |
| 111 | + YEXCEPTION_CATCH |
| 112 | +} |
| 113 | + |
| 114 | +/* |
| 115 | + * Set the item index |
| 116 | + */ |
| 117 | +static VALUE |
| 118 | +set_index(VALUE self, VALUE index) |
| 119 | +{ |
| 120 | + YEXCEPTION_TRY |
| 121 | + YItem *ptr = ui_unwrap_item(self); |
| 122 | + ptr->setIndex(NUM2INT(index)); |
| 123 | + return index; |
| 124 | + YEXCEPTION_CATCH |
| 125 | +} |
| 126 | + |
| 127 | +/* |
| 128 | + * @return [String] the 's' icon name |
| 129 | + */ |
| 130 | +static VALUE |
| 131 | +get_icon_name(VALUE self) |
| 132 | +{ |
| 133 | + YEXCEPTION_TRY |
| 134 | + YItem *ptr = ui_unwrap_item(self); |
| 135 | + return rb_str_new2(ptr->iconName().c_str()); |
| 136 | + YEXCEPTION_CATCH |
| 137 | +} |
| 138 | + |
| 139 | +/* |
| 140 | + * Set the item's icon name |
| 141 | + */ |
| 142 | +static VALUE |
| 143 | +set_icon_name(VALUE self, VALUE icon) |
| 144 | +{ |
| 145 | + YEXCEPTION_TRY |
| 146 | + YItem *ptr = ui_unwrap_item(self); |
| 147 | + ptr->setIconName(StringValueCStr(icon)); |
| 148 | + return icon; |
| 149 | + YEXCEPTION_CATCH |
| 150 | +} |
| 151 | + |
| 152 | +/* |
| 153 | + * @return [Object] the object associated with this item |
| 154 | + */ |
| 155 | +static VALUE |
| 156 | +get_data(VALUE self) |
| 157 | +{ |
| 158 | + YEXCEPTION_TRY |
| 159 | + YItem *ptr = ui_unwrap_item(self); |
| 160 | + return ptr->data() ? ((VALUE) ptr->data()) : Qnil; |
| 161 | + YEXCEPTION_CATCH |
| 162 | +} |
| 163 | + |
| 164 | +/* |
| 165 | + * Set the object associated with this item |
| 166 | + */ |
| 167 | +static VALUE |
| 168 | +set_data(VALUE self, VALUE data) |
| 169 | +{ |
| 170 | + YEXCEPTION_TRY |
| 171 | + YItem *ptr = ui_unwrap_item(self); |
| 172 | + ptr->setData((void *) data); |
| 173 | + return data; |
| 174 | + YEXCEPTION_CATCH |
| 175 | +} |
| 176 | + |
| 177 | +/* |
| 178 | + * @return [Boolean] True if the item is selected |
| 179 | + */ |
| 180 | +static VALUE |
| 181 | +get_selected(VALUE self) |
| 182 | +{ |
| 183 | + YEXCEPTION_TRY |
| 184 | + YItem *ptr = ui_unwrap_item(self); |
| 185 | + return ptr->selected() ? Qtrue : Qfalse; |
| 186 | + YEXCEPTION_CATCH |
| 187 | +} |
| 188 | + |
| 189 | +/* |
| 190 | + * Select or unselect this item. This does not have any effect on any other |
| 191 | + * item; if it is desired that only one item is selected at any time, the |
| 192 | + * caller has to take care of that. |
| 193 | + * |
| 194 | + * @param [Boolean] selected whether the item is selected or not |
| 195 | + */ |
| 196 | +static VALUE |
| 197 | +set_selected(VALUE self, VALUE selected) |
| 198 | +{ |
| 199 | + YEXCEPTION_TRY |
| 200 | + YItem *ptr = ui_unwrap_item(self); |
| 201 | + ptr->setSelected(RTEST(selected)); |
| 202 | + return selected; |
| 203 | + YEXCEPTION_CATCH |
| 204 | +} |
| 205 | + |
| 206 | +static VALUE |
| 207 | +each_child(VALUE self) |
| 208 | +{ |
| 209 | + YEXCEPTION_TRY |
| 210 | + YItem *ptr = ui_unwrap_item(self); |
| 211 | + |
| 212 | + for (YItemConstIterator it = ptr->childrenBegin(); |
| 213 | + it != ptr->childrenEnd(); |
| 214 | + ++it) { |
| 215 | + |
| 216 | + YItem *child = *it; |
| 217 | + if (!child) |
| 218 | + continue; |
| 219 | + |
| 220 | + VALUE rb_child = widget_object_map_for(child); |
| 221 | + if (!NIL_P(rb_child)) |
| 222 | + rb_yield(rb_child); |
| 223 | + } |
| 224 | + YEXCEPTION_CATCH |
| 225 | +} |
| 226 | + |
| 227 | +/* |
| 228 | + * @return [Item] the item's parent (or nil if the item has no parent) |
| 229 | + */ |
| 230 | +static VALUE |
| 231 | +get_parent(VALUE self) |
| 232 | +{ |
| 233 | + YEXCEPTION_TRY |
| 234 | + YItem *ptr = ui_unwrap_item(self); |
| 235 | + return widget_object_map_for(ptr->parent()); |
| 236 | + YEXCEPTION_CATCH |
| 237 | +} |
| 238 | + |
| 239 | +static VALUE |
| 240 | +_new(int argc, VALUE *argv, VALUE klass) |
| 241 | +{ |
| 242 | + YEXCEPTION_TRY |
| 243 | + |
| 244 | + VALUE label; |
| 245 | + rb_scan_args(argc, argv, "10", &label); |
| 246 | + |
| 247 | + YItem *item = new YItem(StringValueCStr(label)); |
| 248 | + VALUE object = ui_wrap_item(item); |
| 249 | + |
| 250 | + widget_object_map_add(item, object); |
| 251 | + rb_obj_call_init(object, argc, argv); |
| 252 | + return object; |
| 253 | + YEXCEPTION_CATCH |
| 254 | +} |
| 255 | + |
| 256 | +/* |
| 257 | + * Initializes an item with label +label+ |
| 258 | + * |
| 259 | + * @param [String] label initial label of the item |
| 260 | + * |
| 261 | + * @example |
| 262 | + * item = UI::Item.new("Orange") |
| 263 | + */ |
| 264 | +static VALUE |
| 265 | +initialize(int argc, VALUE *argv, VALUE self) |
| 266 | +{ |
| 267 | + ui_item_set_owned(self, false); |
| 268 | +} |
| 269 | + |
| 270 | +VALUE cUIItem; |
| 271 | +void init_ui_item() |
| 272 | +{ |
| 273 | + VALUE ui = rb_define_module("UI"); |
| 274 | + |
| 275 | + VALUE klass = rb_define_class_under(ui, "Item", rb_cObject); |
| 276 | + rb_define_singleton_method(klass, "new", RUBY_METHOD_FUNC(_new), -1); |
| 277 | + rb_define_method(klass, "initialize", RUBY_METHOD_FUNC(initialize), -1); |
| 278 | + rb_define_method(klass, "label", RUBY_METHOD_FUNC(get_label), 0); |
| 279 | + rb_define_method(klass, "label=", RUBY_METHOD_FUNC(set_label), 1); |
| 280 | + rb_define_method(klass, "data", RUBY_METHOD_FUNC(get_data), 0); |
| 281 | + rb_define_method(klass, "data=", RUBY_METHOD_FUNC(set_data), 1); |
| 282 | + rb_define_method(klass, "index", RUBY_METHOD_FUNC(get_index), 0); |
| 283 | + rb_define_method(klass, "index=", RUBY_METHOD_FUNC(set_index), 1); |
| 284 | + rb_define_method(klass, "icon_name", RUBY_METHOD_FUNC(get_icon_name), 0); |
| 285 | + rb_define_method(klass, "icon_name=", RUBY_METHOD_FUNC(set_icon_name), 1); |
| 286 | + rb_define_method(klass, "selected?", RUBY_METHOD_FUNC(get_selected), 0); |
| 287 | + rb_define_method(klass, "selected=", RUBY_METHOD_FUNC(set_selected), 1); |
| 288 | + rb_define_method(klass, "each_child", RUBY_METHOD_FUNC(each_child), 0); |
| 289 | + rb_define_method(klass, "parent", RUBY_METHOD_FUNC(get_parent), 0); |
| 290 | + cUIItem = klass; |
| 291 | +} |
| 292 | + |
0 commit comments