rubygoo 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,10 @@
1
+ === 0.0.3 / 2008-09-16
2
+
3
+ * Rubygoo hits useable state
4
+ * added modal dialogs
5
+ * added named css colors
6
+ * changed default colorscheme
7
+ * refactored rubygame input/rendering into adapters
8
+ * started adding support for gosu applications
9
+
10
+
data/Manifest.txt ADDED
@@ -0,0 +1,37 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ TODO
6
+ docs/.DS_Store
7
+ docs/Picture 1.png
8
+ docs/ui/.DS_Store
9
+ docs/ui/UI.hpp
10
+ docs/ui/abutton.png
11
+ docs/ui/background.png
12
+ docs/ui/button.png
13
+ docs/ui/moveable.png
14
+ docs/ui/textbutton.png
15
+ lib/code_statistics.rb
16
+ lib/platform.rb
17
+ lib/rubygoo.rb
18
+ lib/rubygoo/adapters/adapter_factory.rb
19
+ lib/rubygoo/adapters/gosu_app_adapter.rb
20
+ lib/rubygoo/adapters/gosu_render_adapter.rb
21
+ lib/rubygoo/adapters/rubygame_app_adapter.rb
22
+ lib/rubygoo/adapters/rubygame_render_adapter.rb
23
+ lib/rubygoo/app.rb
24
+ lib/rubygoo/button.rb
25
+ lib/rubygoo/check_box.rb
26
+ lib/rubygoo/container.rb
27
+ lib/rubygoo/css_colors.rb
28
+ lib/rubygoo/dialog.rb
29
+ lib/rubygoo/goo_color.rb
30
+ lib/rubygoo/goo_event.rb
31
+ lib/rubygoo/label.rb
32
+ lib/rubygoo/text_field.rb
33
+ lib/rubygoo/widget.rb
34
+ samples/gosu_app.rb
35
+ samples/rubygame_app.rb
36
+ themes/default/Vera.ttf
37
+ themes/default/config.yml
data/README.txt ADDED
@@ -0,0 +1,81 @@
1
+ = rubygoo
2
+
3
+ http://rubygoo.googlecode.com
4
+
5
+ == DESCRIPTION:
6
+
7
+ Rubygoo is a theme-able gui framework for use with rubygame and soon gosu. It has a strong focus on nice syntax and ease of use.
8
+
9
+ == FEATURES:
10
+
11
+ * theme-able gui widgets
12
+ * named css colors
13
+ * works with rubygame, gosu support on its way
14
+ * containers, labels, buttons, checkboxes
15
+ * tabbing focus of widgets
16
+ * modal dialogs
17
+
18
+ == SYNOPSIS:
19
+
20
+ def build_gui(renderer)
21
+ app = App.new :renderer => renderer
22
+
23
+ label = Label.new "click the button to set the time", :x=>20, :y=>30
24
+
25
+ button = Button.new "Click Me!", :x=>70, :y=>80, :x_pad=>20, :y_pad=>20
26
+ button.on :pressed do |*opts|
27
+ label.set_text(Time.now.to_s)
28
+ end
29
+
30
+ check = CheckBox.new :x=>370, :y=>70, :w=>20, :h=>20
31
+ check.on :checked do
32
+ label.set_text("CHECKED [#{check.checked?}]")
33
+ end
34
+
35
+ text_field = TextField.new "initial text", :x => 70, :y => 170
36
+
37
+ text_field.on_key K_RETURN, K_KP_ENTER do |evt|
38
+ puts "BOO-YAH"
39
+ end
40
+
41
+ # implicit tab ordering based on order of addition, can
42
+ # specify if you want on widget creation
43
+
44
+ # can add many or one at a time
45
+ app.add text_field, label, button
46
+ app.add check
47
+ end
48
+
49
+ screen = Screen.new [600,480]
50
+
51
+ factory = AdapterFactory.new
52
+ render_adapter = factory.renderer_for :rubygame, screen
53
+ app = create_gui(render_adapter)
54
+ app_adapter = factory.app_for :rubygame, app
55
+
56
+ # <standard rubygame setup stuff here>
57
+
58
+ # rubygame loop do ..
59
+
60
+ # each event in our queue do ..
61
+ # pass on our events to the GUI
62
+ app_adapter.on_event event
63
+ end
64
+
65
+ app_adapter.update clock.tick
66
+ app_adapter.draw render_adapter
67
+ end
68
+
69
+ == REQUIREMENTS:
70
+
71
+ * publisher gem
72
+ * constructor gem
73
+ * rubygame gem (for now)
74
+
75
+ == INSTALL:
76
+
77
+ * sudo gem install rubygoo
78
+
79
+ == LICENSE:
80
+
81
+ GPLv2
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/rubygoo.rb'
6
+
7
+ Hoe.new('rubygoo', Rubygoo::VERSION) do |p|
8
+ p.developer('Shawn Anderson', 'shawn42@gmail.com')
9
+ p.author = "Shawn Anderson"
10
+ p.description = "GUI library for use with Gosu or Rubygame"
11
+ p.email = 'boss@topfunky.com'
12
+ p.summary = "Beautiful graphs for one or multiple datasets."
13
+ p.url = "http://rubygoo.googlecode.com"
14
+ p.changes = p.paragraphs_of('History.txt', 0..2).join("\n\n")
15
+ p.remote_rdoc_dir = '' # Release to root
16
+ p.extra_deps = ['constructor','publisher']
17
+ end
18
+
19
+ # run rubygame_app
20
+ task :run do
21
+ # this is for convenience on os x
22
+ sh "rsdl samples/rubygame_app.rb"
23
+ end
24
+
25
+ STATS_DIRECTORIES = [
26
+ %w(Source lib/)
27
+ ].collect { |name, dir| [ name, "#{dir}" ] }.select { |name, dir| File.directory?(dir) }
28
+
29
+ desc "Report code statistics (KLOCs, etc) from the application"
30
+ task :stats do
31
+ require 'code_statistics'
32
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
33
+ end
34
+
35
+ # vim: syntax=Ruby
data/TODO ADDED
@@ -0,0 +1,10 @@
1
+ TODO
2
+ - should rubygoo take control of the screen & events?
3
+ - just provide callbacks?
4
+ - make clicking on a component focus it
5
+ - add more listener types (when mouse_enter, mouse_leave, mouse_click, focus, key_pressed...)
6
+ - image icons for buttons
7
+
8
+ - abstract the events that rubygoo takes and the renderer to allow for gosu-ness
9
+ - rework color scheme to not suck
10
+ - double-check the tab focus stuff on modal dialogs
data/docs/.DS_Store ADDED
Binary file
Binary file
data/docs/ui/.DS_Store ADDED
Binary file
data/docs/ui/UI.hpp ADDED
@@ -0,0 +1,425 @@
1
+ #ifndef UI_HPP
2
+ #define UI_HPP
3
+
4
+ #include <boost/function.hpp>
5
+ #include <Gosu/Input.hpp>
6
+ #include <Gosu/Font.hpp>
7
+ #include <Gosu/TextInput.hpp>
8
+ #include <boost/bind.hpp>
9
+ #include <Gosu/Utility.hpp>
10
+ #include <Gosu/Graphics.hpp>
11
+ #include <Gosu/Directories.hpp>
12
+
13
+ // Comment out these lines if you're using the same thing anyway.
14
+ typedef boost::shared_ptr<Gosu::Image> Image; // Ich brauch einen tollen Namen D:
15
+ typedef std::vector<Image> Animation;
16
+ enum ZOrder {
17
+ zBackground,
18
+ zSomething,
19
+ zOMG, // sorry about this.
20
+ zUI,
21
+ zUIButton,
22
+ zCursor;
23
+ };
24
+ // if you don't, you may want to uncomment these.
25
+ /*
26
+ void loadImage(std::wstring filename, Image &loadTo, Gosu::Graphics& graphics, bool hardBorder) {
27
+ loadTo.reset(new Gosu::Image(graphics, Gosu::sharedResourcePrefix() + L"media/" + filename, hardBorder));
28
+ }
29
+
30
+ void loadAnimation(std::wstring filename, Animation &loadTo, Gosu::Graphics& graphics, int width, int height, bool hardBorder) {
31
+ Gosu::imagesFromTiledBitmap(graphics, Gosu::sharedResourcePrefix() + L"media/" + filename, width, height, hardBorder, loadTo);
32
+ }
33
+ */
34
+
35
+ // Change this.
36
+ #define WINDOW_WIDTH 800
37
+ #define WINDOW_HEIGHT 600
38
+
39
+ /*
40
+ For the best usage you define a "Mother-Widget". Example code:
41
+
42
+ class GameWindow : public Gosu::Window {
43
+ protected:
44
+ Widget widgets, *background, *acontainer, *txtbtn;
45
+ public:
46
+ GameWindow()
47
+ : Gosu::Window(WINDOW_WIDTH, WINDOW_HEIGHT, false, 20) {
48
+ background = new Widget(L"background.png", graphics(), 0, 0, zBackground);
49
+ widgets->add(background);
50
+ Button* btn1 = new Button(L"button.png", graphics(), 20, 20, zUIButton);
51
+ background->add(btn1);
52
+ btn1->onLeftClick = boost::bind(&GameWindow::explode, this);
53
+ AdvButton* btn2 = new AdvButton(L"abutton.png", graphics(), 50, 50, 40, 40, zUIButton);
54
+ widgets->add(btn2);
55
+ acontainer = new Moveable(L"moveable.png", graphics(), 200, 200, zUI, 120, 40);
56
+ txtbtn = new AdvTextButton(L"textbutton.png", graphics(), 205, 250, 132, 22, Gosu::defaultFontName(), L"Hello World", true);
57
+ txtbtn->onLeftClick = boost::bind(&GameWindow::noWorld, this);
58
+ acontainer->addWidget(txtbtn);
59
+ }
60
+
61
+ void buttonDown(Gosu::Button btn) {
62
+ if (btn == Gosu::kbF7) {
63
+ if (background->isVisible()) background->hide(),
64
+ else background->show();
65
+ } else if (btn == Gosu::kbF8) {
66
+ if (acointainer->isVisible()) acontainer->hide();
67
+ else acointainer->show();
68
+ } else if (btn == Gosu::kbF9) {
69
+ // force txtbtn to show >:[
70
+ txtbtn->show(true);
71
+ }
72
+ widgets.buttonDown(btn, input());
73
+ }
74
+
75
+ void buttonUp(Gosu::Button btn) {
76
+ widgets.buttonUp(btn, input());
77
+ }
78
+
79
+ void update() {
80
+ widgets.update(input());
81
+ }
82
+
83
+ void draw() {
84
+ widgets.draw(input());
85
+ }
86
+
87
+ void explode() {
88
+ exit(-42);
89
+ }
90
+
91
+ void noWorld() {
92
+ txtbtn->setText(L":((");
93
+ background->deactivate();
94
+ }
95
+ };
96
+
97
+ int main(int argc, char* argv[]) {
98
+ GameWindow window;
99
+ window.show();
100
+ }
101
+ */
102
+ class Widget;
103
+ typedef std::vector<Widget*> Widgets;
104
+
105
+ enum AdvTxtBtnKeep {
106
+ tbkNone = -1,
107
+ tbkNormal = 0,
108
+ tbkHover = 1,
109
+ tbkPressed = 2,
110
+ tbkDisabled = 3
111
+ };
112
+ /**
113
+ * Mutter aller Grafikelemente! Kann abgeleitet werden und funktioniert rekursiv bis ~ewig!
114
+ * X/Y/Z: Selbsterkl�rend
115
+ * Widgets sind eigentlich nicht zum bewegen geeignet.
116
+ * Sie k�nnen zwar verschoben werden (setX, setY: nur dieses; move(ox,oy): rekursiv).
117
+ * widgets k�nnen sich X und Y wiederholen (festlegbar).
118
+ * Sie sind deaktivierbar und versteckbar. Ersters hat keine Funktion in Widget.
119
+ */
120
+
121
+ class Widget {
122
+ protected:
123
+ Widgets widgets, addQueue;
124
+ Image image;
125
+ int x, y;
126
+ ZOrder z;
127
+ bool active, visible, noAutoShow, locked;
128
+ WidgetType type;
129
+ public:
130
+ Widget(int x = 0, int y = 0, ZOrder z = zBackground, bool noAutoShow = false) {
131
+ this->x = x;
132
+ this->y = y;
133
+ this->z = z;
134
+ active = visible = true;
135
+ locked = false;
136
+ this->noAutoShow = noAutoShow;
137
+ type = wtWidget;
138
+ }
139
+
140
+ Widget(Image& image, int x, int y, ZOrder z, bool noAutoShow = false) {
141
+ this->image = image;
142
+ this->x = x;
143
+ this->y = y;
144
+ this->z = z;
145
+ active = visible = true;
146
+ type = wtWidget;
147
+ this->noAutoShow = noAutoShow;
148
+ }
149
+
150
+ Widget(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, bool noAutoShow = false) {
151
+ loadImage(name, image, graphics);
152
+ this->x = x;
153
+ this->y = y;
154
+ this->z = z;
155
+ active = visible = true;
156
+ type = wtWidget;
157
+ this->noAutoShow = noAutoShow;
158
+ }
159
+ // Gosu related
160
+ virtual void draw(Gosu::Input& input);
161
+ virtual void update(Gosu::Input& input);
162
+ virtual void buttonUp(Gosu::Button& btn, Gosu::Input& input); // Redirect call
163
+ virtual void buttonDown(Gosu::Button& btn, Gosu::Input& input); // Redirect call
164
+ virtual void move(int vx, int vy); // bewegt um vx/vy; alle untergeordneten auch.
165
+ int getX() { return x; }
166
+ int getY() { return y; }
167
+ ZOrder getZ() { return z; }
168
+ virtual Image getImage() { return image; }
169
+ void setX(int x) { this->x = x; }
170
+ void setY(int y) { this->y = y; }
171
+ void setZ(ZOrder z) { this->z = z; }
172
+ WidgetType getType() { return type; }
173
+ void addWidget(Widget* widget); // unterwidget hinzuf�gen
174
+ void remWidget(Widget* widget); // unterwidget l�schen
175
+ // (De-)aktivieren
176
+ void activate();
177
+ void deactivate();
178
+ bool isActive() { return active; }
179
+ // verstecken/anzeigen
180
+ void hide();
181
+ void show(bool force = false); // force: erzwinge anzeigen. hat nur mit noAutoShow effekt.
182
+ bool isVisible() { return visible; }
183
+ virtual ~Widget();
184
+ };
185
+
186
+ /**
187
+ * Movable. Sie (und alles untergeordnete) verschiebt sich. Lustige Sache.
188
+ *
189
+ */
190
+ class Moveable : public Widget {
191
+ int omx, omy, wdt, hgt, twdt, thgt;
192
+ bool moving;
193
+ public:
194
+ static std::vector<Moveable*> moveables;
195
+ boost::function<void(Moveable*)> onTitleLeftClick, onTitleRightClick;
196
+ Moveable(Image& image, int x, int y, ZOrder z, int titleWidth, int titleHeight)
197
+ : Widget(image, x, y, z) {
198
+ moving = false;
199
+ omx = omy = 0;
200
+ wdt = image->width();
201
+ hgt = image->height();
202
+ twdt = titleWidth;
203
+ thgt = titleHeight;
204
+ type = wtMoveable;
205
+ Moveable::moveables.push_back(this);
206
+ }
207
+
208
+ Moveable(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, int titleWidth, int titleHeight)
209
+ :Widget(name, graphics, x, y, z) {
210
+ moving = false;
211
+ omx = omy = 0;
212
+ wdt = image->width();
213
+ hgt = image->height();
214
+ twdt = titleWidth;
215
+ thgt = titleHeight;
216
+ type = wtMoveable;
217
+ Moveable::moveables.push_back(this);
218
+ }
219
+
220
+ void update(Gosu::Input& input);
221
+ void buttonDown(Gosu::Button& btn, Gosu::Input& input);
222
+ void buttonUp(Gosu::Button& btn, Gosu::Input& input);
223
+ void move(int vx, int vy);
224
+ };
225
+
226
+ /**
227
+ * Primitiver Button der nur f�r Mausklicks zust�ndig ist.
228
+ * 2 calls: onLeftClick, onRightClick. Param jeweils Button* btn
229
+ */
230
+ class Button : public Widget {
231
+ protected:
232
+ int width, height;
233
+ bool focus;
234
+ Button* next;
235
+ public:
236
+ static Button* btnFocus;
237
+ boost::function<void (Button*)> onRightClick, onLeftClick;
238
+
239
+ Button(int x = 0, int y = 0, ZOrder z = zBackground, bool noAutoShow = false)
240
+ : Widget(x, y, z, noAutoShow) {
241
+ width = height = 0;
242
+ focus = false;
243
+ next = NULL;
244
+ type = wtButton;
245
+ }
246
+
247
+ Button(Image& image, int x, int y, ZOrder z, bool noAutoShow = false)
248
+ : Widget(image, x, y, z, noAutoShow) {
249
+ width = image->width();
250
+ height = image->height();
251
+ focus = false;
252
+ next = NULL;
253
+ type = wtButton;
254
+ }
255
+
256
+ Button(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, bool noAutoShow = false)
257
+ : Widget(name, graphics, x, y, z, noAutoShow) {
258
+ loadImage(name, image, graphics);
259
+ width = image->width();
260
+ height = image->height();
261
+ focus = false;
262
+ next = NULL;
263
+ type = wtButton;
264
+ }
265
+
266
+ virtual void update(Gosu::Input& input);
267
+ virtual void buttonUp(Gosu::Button& btn, Gosu::Input& input);
268
+ static void buttonUpAll(Gosu::Button& btn, Gosu::Input& input);
269
+ virtual void setFocus(bool woot) { focus = woot; }
270
+ virtual void setNextFocus(Button* toFocus) { next = toFocus; }
271
+ virtual void onFocus(Button* from, Gosu::Input& input);
272
+ virtual void onDefocus(Button* from, Gosu::Input& input);
273
+ };
274
+
275
+ /**
276
+ * Textbutton: Dynamischer erzeugte Buttons
277
+ */
278
+
279
+ class TextButton : public Button {
280
+ protected:
281
+ Gosu::Font* font;
282
+ std::wstring text;
283
+ public:
284
+ TextButton(Image& image, int x, int y, ZOrder z, Gosu::Graphics& graphics, std::wstring fontName, std::wstring text, bool noAutoShow = false)
285
+ : Button(image, x, y, z, noAutoShow) {
286
+ font = new Gosu::Font(graphics, fontName, image->height()-5);
287
+ this->text = text;
288
+ }
289
+
290
+ TextButton(Image& image, int x, int y, ZOrder z, Gosu::Font* font, std::wstring text, bool noAutoShow = false)
291
+ : Button(image, x, y, z, noAutoShow) {
292
+ this->font = font;
293
+ this->text = text;
294
+ }
295
+
296
+ TextButton(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, std::wstring fontName, std::wstring text, bool noAutoShow = false)
297
+ : Button(name, graphics, x, y, z, noAutoShow) {
298
+ font = new Gosu::Font(graphics, fontName, image->height()-5);
299
+ this->text = text;
300
+ }
301
+
302
+ TextButton(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, Gosu::Font* font, std::wstring text, bool noAutoShow = false)
303
+ : Button(name, graphics, x, y, z, noAutoShow) {
304
+ this->font = font;
305
+ this->text = text;
306
+ }
307
+
308
+ TextButton(int x, int y, ZOrder z, Gosu::Graphics& graphics, std::wstring fontname, std::wstring text, int height, bool noAutoShow = false)
309
+ : Button(x, y, z, noAutoShow) {
310
+ font = new Gosu::Font(graphics, fontname, height-5);
311
+ this->text = text;
312
+ }
313
+
314
+ TextButton(int x, int y, ZOrder z, Gosu::Font* font, std::wstring text, bool noAutoShow = false)
315
+ : Button(x, y, z, noAutoShow) {
316
+ this->font = font;
317
+ this->text = text;
318
+ }
319
+
320
+ std::wstring getText() { return text; }
321
+ Gosu::Font* getFont() { return font; }
322
+ void setText(std::wstring newText) { text = newText; }
323
+
324
+ void draw(Gosu::Input& input);
325
+ };
326
+
327
+ /**
328
+ * Input Klasse. Abgeleitet von Button f�r width/height Zeug + FOKUS!
329
+ */
330
+
331
+ class Input : public Button {
332
+ protected:
333
+ Gosu::TextInput textInput;
334
+ Gosu::Font font;
335
+ public:
336
+ Input(Image& image, int x, int y, ZOrder z, Gosu::Graphics& graphics, std::wstring fontName)
337
+ : Button(image, x, y, z), font(graphics, fontName, image->height()-5) {
338
+ type = wtInput;
339
+ }
340
+
341
+ Input(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, std::wstring fontName)
342
+ : Button(name, graphics, x, y, z), font(graphics, fontName, image->height()-5) {
343
+ type = wtInput;
344
+ }
345
+ void buttonUp(Gosu::Button& btn, Gosu::Input& input);
346
+ virtual void draw(Gosu::Input& input);
347
+ std::string text() { return Gosu::narrow(textInput.text()); }
348
+ void reset() { textInput.setText(L""); }
349
+ void onFocus(Button* from, Gosu::Input& input);
350
+ void onDefocus(Button* from, Gosu::Input& input);
351
+ protected:
352
+ void ThereCanBeOnlyOne(Gosu::Input& input);
353
+ };
354
+ /**
355
+ * AdvButtons sind 4-tile-ige Buttons.
356
+ * die Reihenfolge dabei ist:
357
+ * - Normal
358
+ * - onHover
359
+ * - onClick
360
+ * - disabled
361
+ * Sie sind/sollten nicht weiter vererbt werden weil draw() das nicht weitergibt.
362
+ * wozu auch. mit 2 advbuttons arbeiten ist h�sslich.
363
+ */
364
+ class AdvButton : public Button {
365
+ Animation* animation;
366
+ public:
367
+ AdvButton(Animation* animation, int x, int y, ZOrder z, bool noAutoShow = false)
368
+ : Button(x, y, z, noAutoShow) {
369
+ this->animation = animation;
370
+ width = animation->at(0)->width();
371
+ height = animation->at(0)->height();
372
+ assert(animation->size() == 4);
373
+ type = wtAdvButton;
374
+ }
375
+
376
+ AdvButton(std::wstring name, Gosu::Graphics& graphics, int x, int y, int width, int height, ZOrder z, bool noAutoShow = false)
377
+ : Button(x, y, z, noAutoShow) {
378
+ animation = new Animation();
379
+ loadAnimation(name, *animation, graphics, width, height);
380
+ assert(animation->size() == 4);
381
+ this->width = width;
382
+ this->height = height;
383
+ type = wtAdvButton;
384
+ }
385
+ virtual void draw(Gosu::Input& input);
386
+ Image getImage() { return animation->at(0); }
387
+ Animation* getAnimation() { return animation; }
388
+ };
389
+
390
+ /**
391
+ * AdvButton + TextButton
392
+ *
393
+ */
394
+
395
+ class AdvTextButton : public TextButton {
396
+ protected:
397
+ Animation* animation;
398
+ AdvTxtBtnKeep keepState;
399
+ public:
400
+ AdvTextButton(std::wstring name, Gosu::Graphics& graphics, int x, int y, ZOrder z, int width, int height, std::wstring fontname, std::wstring text, bool noAutoShow = false)
401
+ :TextButton(x, y, z, graphics, fontname, text, height, noAutoShow)
402
+ {
403
+ animation = new Animation();
404
+ loadAnimation(name, *animation, graphics, width, height);
405
+ keepState = tbkNone;
406
+ this->width = width;
407
+ this->height = height;
408
+ }
409
+
410
+ AdvTextButton(Animation* animation, int x, int y, ZOrder z, Gosu::Font* font, std::wstring text, bool noAutoShow = false)
411
+ :TextButton(x, y, z, font, text, noAutoShow) {
412
+ this->animation = animation;
413
+ keepState = tbkNone;
414
+ this->width = animation->at(0)->width();
415
+ this->height = animation->at(0)->height();
416
+ }
417
+
418
+ Image getImage() { return animation->at(0); }
419
+ void draw(Gosu::Input& input);
420
+ Animation* getAnimation() { return animation; }
421
+ AdvTxtBtnKeep getKeepState() { return keepState; }
422
+ void setKeepState(AdvTxtBtnKeep keep) { keepState = keep; }
423
+ };
424
+ #endif
425
+