Merge lp:~rafalcieslak256/millenniumduel/containers into lp:millenniumduel

Proposed by Rafał Cieślak
Status: Merged
Merged at revision: 10
Proposed branch: lp:~rafalcieslak256/millenniumduel/containers
Merge into: lp:millenniumduel
Diff against target: 765 lines (+408/-108)
18 files modified
src/Box.cpp (+59/-0)
src/Box.hpp (+47/-0)
src/Fixed.cpp (+28/-30)
src/Fixed.hpp (+17/-16)
src/HBox.cpp (+61/-0)
src/HBox.hpp (+11/-0)
src/VBox.cpp (+60/-0)
src/VBox.hpp (+11/-0)
src/build (+1/-1)
src/button.cpp (+10/-4)
src/button.hpp (+5/-2)
src/display.cpp (+9/-10)
src/display.hpp (+6/-4)
src/drawable.cpp (+17/-7)
src/drawable.hpp (+33/-11)
src/label.cpp (+11/-4)
src/label.hpp (+4/-1)
src/main.cpp (+18/-18)
To merge this branch: bzr merge lp:~rafalcieslak256/millenniumduel/containers
Reviewer Review Type Date Requested Status
Adam Malinowski Approve
Jakub Sękowski Approve
Review via email: mp+176052@code.launchpad.net

Description of the change

This branch implements Container widgets (namely a custom VBox and a HBox).
[https://blueprints.launchpad.net/millenniumduel/+spec/millenniumduel-containers]

These widgets are meant to spread evenly widgets aligned horizontally or vertically.

They are kind of similar to GTK's boxes, but one should not assume any similarities.

This branch also significantly changes the way draw() is used. It is now called with a set of 4 values, representing coordinates of a rectangular area where the widget should draw itself.
This way all widgets can be drawn in variety of sizes.

All Drawables can also provide the minimal size they need for drawing (for example, a button cannot be too thin or its text will not fit). These can be learned by calling GetMinimalHeight and GetMinimalWidth.

Both boxes are used by appending widgets with Add(drawable). By default all items are shrinked to minimum, except for those that are added with BOX_EXPAND as a second argument to Add, these will be spread evenly.
One can set the space between boxes with SetSpacing, as well as the margin around the Box with SetMargin (both default to 0).

Of course, Boxes are also a Drawable, and therefore can be nested freely.

Another change introduced by this branch is that a View widget (renamed to Fixed) is now a Drawable.
The Display class requires now a Drawable to be the topmost widget, it does not have to be a Fixed (View).

The example in main() sets a VBox as the main menu, shrinking and expanding some of the buttons. The additional menu is left as it was, as a Fixed.

NOTE: This code does not fix bug #1198640.

To post a comment you must log in.
Revision history for this message
Jakub Sękowski (sequba) wrote :

Why items in Box are stored in a set? I would use list or vector instead. Ordering of items would be clear and member order (of struct BoxEntry) wouldn't be needed.

Revision history for this message
Rafał Cieślak (rafalcieslak256) wrote :

My idea is that one may wish to insert a widget *between* some that already exist. This might be done using a vector too, but inserting items there may look more tricky, as the indexes might change in the meantime. The solution I implemented binds a (potentially) number to each item, so that one can freely insert the items wherever wanted.

Also please note that the struct BoxEntry would still be needed, as it also keeps info about the current size of the widget, the Drawables themselves do not store it, and it has to be recalculated from time to time to ensure proper widget resizing.

Revision history for this message
Jakub Sękowski (sequba) wrote :

In my opinion, that's exactly what we need.

I'm still not fully convinced of set and that weird attribute "order", but it may indeed be more convenient to use it this way.

Approve.

review: Approve
Revision history for this message
Adam Malinowski (adayah) wrote :

I love the code you wrote. It's elegant and very powerful, and is going to save us a lot of effort.

However, I discovered a minor bug. When examined carefully, it turns out, that buttons' click sensivity areas are a bit offset upwards with respect to their drawings.
I think I can tell which part of code needs a correction. In functions HBox::on_clicked and VBox::on_clicked, the 'sum' variable should be initialized with:

int sum = margin;

instead of actual:

int sum = 0;

Very nice job!

review: Needs Fixing
22. By Rafał Cieślak

Fixed click detection allignment

Revision history for this message
Adam Malinowski (adayah) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'src/Box.cpp'
--- src/Box.cpp 1970-01-01 00:00:00 +0000
+++ src/Box.cpp 2013-07-23 20:39:00 +0000
@@ -0,0 +1,59 @@
1#include "Box.hpp"
2
3Box::Box(){
4 spacing = 0;
5 margin = 0;
6}
7
8void Box::_RecalculateSizes(int total, int (Drawable::*size_func)()){
9 if(children.size() == 0) return;
10
11 int shrinked_sum = 0;
12 int expand_count = 0;
13
14 for(auto &i : children){
15 if(i.mode == BOX_SHRINK){
16 int h = ((i.item).*size_func)(); //use the size_func to get minimal width/height
17 i.size = h;
18 shrinked_sum += h;
19 }else if(i.mode == BOX_EXPAND){
20 expand_count++;
21 }
22 shrinked_sum += spacing;
23 }
24 if (shrinked_sum > 0) shrinked_sum -= spacing;
25
26 if(expand_count > 0){
27 int rest = total - 2*margin - shrinked_sum;
28 int expand_size = rest / expand_count;
29 int last_expand_size = rest - (expand_size * expand_count) + expand_size;
30
31 if(expand_size < 0) expand_size = 0;
32 if(last_expand_size < 0) last_expand_size = 0;
33
34 for(auto &i : children){
35 if(i.mode == BOX_EXPAND){
36 if(expand_count != 1){ //this is not the last expanding item
37 i.size = expand_size;
38 }else{
39 i.size = last_expand_size;
40 }
41 expand_count--;
42 }
43 }
44 }
45}
46
47void Box::Add(Drawable& item, int position, BoxPackingMode mode){
48 BoxEntry be(item);
49 be.order = position;
50 be.mode = mode;
51 children.insert(be);
52}
53
54void Box::SetSpacing(int s){
55 spacing = s;
56}
57void Box::SetMargin(int m){
58 margin = m;
59}
060
=== added file 'src/Box.hpp'
--- src/Box.hpp 1970-01-01 00:00:00 +0000
+++ src/Box.hpp 2013-07-23 20:39:00 +0000
@@ -0,0 +1,47 @@
1#include "drawable.hpp"
2#include <string>
3#include <set>
4
5enum BoxPackingMode{
6 BOX_SHRINK = 0,
7 BOX_EXPAND = 1
8};
9
10class Box : public Drawable{
11protected:
12 Box();
13
14public:
15 void Add(Drawable& item, int position, BoxPackingMode mode = BOX_SHRINK);
16
17 void SetSpacing(int spacing);
18 void SetMargin(int margin);
19
20 virtual void draw(SDrawArea a) = 0;
21
22 virtual int GetMinimalHeight() = 0;
23 virtual int GetMinimalWidth () = 0;
24
25 virtual void on_clicked(SCoordinates p) = 0;
26protected:
27
28 struct BoxEntry{
29 BoxEntry(Drawable& i) : item(i) {};
30 int order; // Used to determine item's position within the container
31 BoxPackingMode mode;
32 mutable int size; // size in px for this item, used temporarily for calculations
33 Drawable& item;
34 };
35 struct BoxEntryComparator{
36 bool operator()(const BoxEntry& x,const BoxEntry& y) const {return x.order < y.order;}
37 };
38
39 /* This set contains all widgets contained within this container. */
40 std::set< BoxEntry, BoxEntryComparator> children;
41
42 int spacing;
43 int margin;
44 int current_width, current_height;
45
46 void _RecalculateSizes(int total, int (Drawable::*size_func)());
47};
048
=== renamed file 'src/view.cpp' => 'src/Fixed.cpp'
--- src/view.cpp 2013-07-07 08:48:44 +0000
+++ src/Fixed.cpp 2013-07-23 20:39:00 +0000
@@ -1,39 +1,37 @@
1#include "view.hpp"1#include "Fixed.hpp"
2#include <allegro5/allegro.h>2
33Fixed::Fixed(int w, int h) : width(w), height(h){
4void View::draw(){4}
5 al_clear_to_color(al_map_rgb(0,0,0));5
66void Fixed::draw(SDrawArea a){
7 ALLEGRO_TRANSFORM transform;
8 for(auto q : items){7 for(auto q : items){
9 Drawable* x = q.first;8 Drawable* x = q.first;
10 Coordinates c = q.second;9 SCoordinates c = q.second;
11 al_identity_transform(&transform);
12 al_translate_transform(&transform, c.x, c.y);
13 al_use_transform(&transform);
1410
15 x->draw();11 int width = x->GetMinimalWidth ();
12 int height = x->GetMinimalHeight();
13
14 x->draw(SDrawArea(a.x + c.x, a.y + c.y, width, height));
16 }15 }
17 16}
18 al_identity_transform(&transform);17
19 al_use_transform(&transform);18void Fixed::add_item(Drawable& d, SCoordinates c){
2019 items[&d] = c;
21}20}
2221
23void View::add_item(Drawable* d, Coordinates c){22void Fixed::remove_item(Drawable& d){
24 items[d] = c;23 items.erase(&d);
25}24}
2625
27void View::remove_item(Drawable *d){26void Fixed::on_clicked(SCoordinates p){
28 items.erase(d);
29}
30
31void View::on_clicked(int x, int y){
32 for(auto q : items){27 for(auto q : items){
33 Drawable* d = q.first;28 Drawable* d = q.first;
34 Coordinates c = q.second;29 SCoordinates c = q.second;
35 if(c.x <= x && c.y <= y && c.x+d->width >= x && c.y+d->height >= y){30 if(c.x <= p.x && c.y <= p.y && c.x+d->GetMinimalWidth() >= p.x && c.y+d->GetMinimalHeight() >= p.y){
36 d->on_clicked();31 d->on_clicked(SCoordinates(p.x - c.x, p.y - c.y));
37 }32 }
38 }33 }
39}34}
35
36int Fixed::GetMinimalHeight(){ return height; }
37int Fixed::GetMinimalWidth() { return width; }
4038
=== renamed file 'src/view.hpp' => 'src/Fixed.hpp'
--- src/view.hpp 2013-07-07 08:48:44 +0000
+++ src/Fixed.hpp 2013-07-23 20:39:00 +0000
@@ -1,23 +1,24 @@
1#ifndef __VIEW_HPP__1#ifndef __FIXED_HPP__
2#define __VIEW_HPP__2#define __FIXED_HPP__
33
4#include "drawable.hpp"4#include "drawable.hpp"
5#include <map>5#include <map>
66
7struct Coordinates{7class Fixed : public Drawable{
8 int x;
9 int y;
10 Coordinates(int _x, int _y) : x(_x), y(_y) {}
11 Coordinates() : x(0), y(0) {}
12};
13
14class View{
15public:8public:
16 std::map<Drawable*,Coordinates> items;9 Fixed(int w = 0, int h = 0);
17 void draw();10 void draw(SDrawArea a);
18 void add_item(Drawable* d, Coordinates c);11 void add_item(Drawable& d, SCoordinates c);
19 void remove_item(Drawable * d);12 void remove_item(Drawable& d);
20 void on_clicked(int x, int y);13 void on_clicked(SCoordinates y);
14
15 virtual int GetMinimalWidth () override;
16 virtual int GetMinimalHeight() override;
17private:
18 std::map<Drawable*,SCoordinates> items;
19
20 int width;
21 int height;
21};22};
2223
23#endif //__VIEW_HPP__24#endif //__FIXED_HPP__
2425
=== added file 'src/HBox.cpp'
--- src/HBox.cpp 1970-01-01 00:00:00 +0000
+++ src/HBox.cpp 2013-07-23 20:39:00 +0000
@@ -0,0 +1,61 @@
1#include "HBox.hpp"
2
3void HBox::draw(SDrawArea a){
4
5 _RecalculateSizes(a.h, &Drawable::GetMinimalWidth);
6
7 int x = a.x + margin, y = a.y + margin;
8
9 for(auto i : children){
10 int width = i.size;
11 int height = a.h - 2*margin;
12
13
14 i.item.draw(SDrawArea(x,y,width,height));
15
16 x += i.size;
17 x += spacing;
18 }
19
20 // Remember my size (for click recognition)
21 current_height = a.h;
22 current_width = a.w;
23
24}
25
26int HBox::GetMinimalHeight() {
27 // Maximum of all items' heights
28 int max = 0;
29 for(auto i : children){
30 int w = i.item.GetMinimalHeight();
31 if (w > max) max = w;
32 }
33 return max + 2*margin;
34
35}
36int HBox::GetMinimalWidth () {
37 // Sum of all items' widths and gaps
38 int sum = 0;
39 for(auto i : children){
40 sum += i.item.GetMinimalWidth();
41 sum += spacing;
42 }
43 if(sum >= 0) sum -= spacing;
44 return sum + 2*margin;
45}
46
47void HBox::on_clicked(SCoordinates p){
48 if (p.x < margin || p.y < margin || p.y > current_height - margin) return;
49 int sum = margin;
50 for(auto i : children){
51 sum += i.size;
52 if(p.x <= sum) { // This item was clicked!
53 i.item.on_clicked(SCoordinates(p.x - sum, p.y));
54 return;
55 }
56 sum += spacing;
57 if(p.x <= sum){ // Empty space between items was clicked
58 return;
59 }
60 }
61}
062
=== added file 'src/HBox.hpp'
--- src/HBox.hpp 1970-01-01 00:00:00 +0000
+++ src/HBox.hpp 2013-07-23 20:39:00 +0000
@@ -0,0 +1,11 @@
1#include "Box.hpp"
2
3class HBox : public Box{
4public:
5 virtual void draw(SDrawArea a) override;
6
7 virtual int GetMinimalHeight() override;
8 virtual int GetMinimalWidth () override;
9
10 virtual void on_clicked(SCoordinates p) override;
11};
012
=== added file 'src/VBox.cpp'
--- src/VBox.cpp 1970-01-01 00:00:00 +0000
+++ src/VBox.cpp 2013-07-23 20:39:00 +0000
@@ -0,0 +1,60 @@
1#include "VBox.hpp"
2
3void VBox::draw(SDrawArea a){
4
5 _RecalculateSizes(a.h, &Drawable::GetMinimalHeight);
6
7 int x = a.x + margin, y = a.y + margin;
8
9 for(auto i : children){
10 int width = a.w - 2*margin;
11 int height = i.size;
12
13
14 i.item.draw(SDrawArea(x,y,width,height));
15
16 y += i.size;
17 y += spacing;
18 }
19
20 // Remember my size (for click recognition)
21 current_height = a.h;
22 current_width = a.w;
23
24}
25
26int VBox::GetMinimalHeight() {
27 // Sum of all items' heights and gaps
28 int sum = 0;
29 for(auto i : children){
30 sum += i.item.GetMinimalHeight();
31 sum += spacing;
32 }
33 if(sum >= 0) sum -= spacing;
34 return sum + 2*margin;
35}
36int VBox::GetMinimalWidth () {
37 // Maximum of all items' widths
38 int max = 0;
39 for(auto i : children){
40 int w = i.item.GetMinimalWidth();
41 if (w > max) max = w;
42 }
43 return max + 2*margin;
44}
45
46void VBox::on_clicked(SCoordinates p){
47 if (p.y < margin || p.x < margin || p.x > current_width - margin) return;
48 int sum = margin;
49 for(auto i : children){
50 sum += i.size;
51 if(p.y <= sum) { // This item was clicked!
52 i.item.on_clicked(SCoordinates(p.x, p.y - sum));
53 return;
54 }
55 sum += spacing;
56 if(p.y <= sum){ // Empty space between items was clicked
57 return;
58 }
59 }
60}
061
=== added file 'src/VBox.hpp'
--- src/VBox.hpp 1970-01-01 00:00:00 +0000
+++ src/VBox.hpp 2013-07-23 20:39:00 +0000
@@ -0,0 +1,11 @@
1#include "Box.hpp"
2
3class VBox : public Box{
4public:
5 virtual void draw(SDrawArea a) override;
6
7 virtual int GetMinimalHeight() override;
8 virtual int GetMinimalWidth () override;
9
10 virtual void on_clicked(SCoordinates p) override;
11};
012
=== modified file 'src/build'
--- src/build 2013-07-14 19:38:45 +0000
+++ src/build 2013-07-23 20:39:00 +0000
@@ -1,2 +1,2 @@
1#!/bin/sh1#!/bin/sh
2g++-4.8 -o main *.cpp `pkg-config --cflags --libs allegro-5.0 allegro_image-5.0 allegro_primitives-5.0 allegro_font-5.0 allegro_ttf-5.0` --std=c++112g++-4.8 -o main *.cpp `pkg-config --cflags --libs allegro-5.0 allegro_image-5.0 allegro_primitives-5.0 allegro_font-5.0 allegro_ttf-5.0` --std=c++11 -Wall -g
33
=== modified file 'src/button.cpp'
--- src/button.cpp 2013-07-07 08:48:44 +0000
+++ src/button.cpp 2013-07-23 20:39:00 +0000
@@ -5,7 +5,7 @@
5#include <allegro5/allegro_font.h>5#include <allegro5/allegro_font.h>
6#include <allegro5/allegro_ttf.h>6#include <allegro5/allegro_ttf.h>
77
8Button::Button(std::string _text) : Drawable(60,20), text(_text){8Button::Button(std::string _text) : text(_text){
99
10}10}
1111
@@ -13,13 +13,19 @@
13 click_reaction = f;13 click_reaction = f;
14}14}
1515
16void Button::draw(){16void Button::draw(SDrawArea a){
17 use_new_transform_to(a.x,a.y);
17 ALLEGRO_COLOR color = al_map_rgb(120, 140, 200);18 ALLEGRO_COLOR color = al_map_rgb(120, 140, 200);
18 al_draw_filled_rectangle(0,0,width,height, color);19 al_draw_filled_rectangle(0,0, a.w, a.h, color);
19 al_draw_text(Display::main_font, al_map_rgb(255,255,255), 30, 0 ,ALLEGRO_ALIGN_CENTRE, text.c_str());20 al_draw_text(Display::main_font, al_map_rgb(255,255,255), a.w/2, a.h/2 - 8, ALLEGRO_ALIGN_CENTRE, text.c_str());
20}21}
2122
22void Button::on_clicked(){23void Button::on_clicked(){
23 if(click_reaction == nullptr) return;24 if(click_reaction == nullptr) return;
24 click_reaction();25 click_reaction();
25}26}
27
28int Button::GetMinimalHeight() {return 20;}
29int Button::GetMinimalWidth () {
30 return al_get_text_width(Display::main_font, text.c_str()) + 6; // 3px margin from both sides
31}
2632
=== modified file 'src/button.hpp'
--- src/button.hpp 2013-07-07 08:48:44 +0000
+++ src/button.hpp 2013-07-23 20:39:00 +0000
@@ -9,6 +9,9 @@
9 void (*click_reaction)() = nullptr;9 void (*click_reaction)() = nullptr;
10 std::string text;10 std::string text;
11 11
12 virtual void draw();12 virtual void draw(SDrawArea a) override;
13 virtual void on_clicked();13 virtual void on_clicked() override;
14
15 virtual int GetMinimalHeight() override;
16 virtual int GetMinimalWidth () override;
14};17};
1518
=== modified file 'src/display.cpp'
--- src/display.cpp 2013-07-07 08:48:44 +0000
+++ src/display.cpp 2013-07-23 20:39:00 +0000
@@ -9,7 +9,7 @@
99
10ALLEGRO_DISPLAY* Display::display = nullptr; 10ALLEGRO_DISPLAY* Display::display = nullptr;
11ALLEGRO_FONT* Display::main_font = nullptr;11ALLEGRO_FONT* Display::main_font = nullptr;
12View* Display::current_view = nullptr;12Drawable* Display::main_widget = nullptr;
1313
14void Display::init(){14void Display::init(){
15 al_init();15 al_init();
@@ -18,7 +18,7 @@
18 al_init_font_addon();18 al_init_font_addon();
19 al_init_ttf_addon();19 al_init_ttf_addon();
20 20
21 display = al_create_display(200,150);21 display = al_create_display(170,200);
2222
23 main_font = al_load_ttf_font("Ubuntu-R.ttf",12,0);23 main_font = al_load_ttf_font("Ubuntu-R.ttf",12,0);
24 24
@@ -27,10 +27,9 @@
27}27}
2828
29void Display::redraw(){29void Display::redraw(){
30 if(current_view != nullptr){30 al_clear_to_color(al_map_rgb(0,0,0));
31 current_view->draw();31 if(main_widget != nullptr){
32 }else{32 main_widget->draw( SDrawArea(0,0,al_get_display_width(display),al_get_display_height(display)) );
33 al_clear_to_color(al_map_rgb(0,0,0));
34 }33 }
35 al_flip_display();34 al_flip_display();
36}35}
@@ -56,8 +55,8 @@
56 }else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN){55 }else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN){
57 int x = ev.mouse.x;56 int x = ev.mouse.x;
58 int y = ev.mouse.y;57 int y = ev.mouse.y;
59 if(current_view != nullptr){58 if(main_widget != nullptr){
60 current_view->on_clicked(x,y);59 main_widget->on_clicked(SCoordinates(x,y));
61 }60 }
62 }61 }
63 }62 }
@@ -73,6 +72,6 @@
73 al_destroy_display(display);72 al_destroy_display(display);
74}73}
7574
76void Display::set_view(View* v){75void Display::SetMainWidget(Drawable& v){
77 current_view = v;76 main_widget = &v;
78}77}
7978
=== modified file 'src/display.hpp'
--- src/display.hpp 2013-07-07 08:48:44 +0000
+++ src/display.hpp 2013-07-23 20:39:00 +0000
@@ -1,7 +1,7 @@
1#ifndef __DISPLAY_HPP__1#ifndef __DISPLAY_HPP__
2#define __DISPLAY_HPP__2#define __DISPLAY_HPP__
33
4#include "view.hpp"4#include "drawable.hpp"
5#include <allegro5/allegro.h>5#include <allegro5/allegro.h>
6#include <allegro5/allegro_font.h>6#include <allegro5/allegro_font.h>
77
@@ -11,16 +11,18 @@
11 static void main_loop();11 static void main_loop();
12 static void cleanup();12 static void cleanup();
1313
14 static void set_view(View* v);14 static void SetMainWidget(Drawable& v);
15 15
16 static ALLEGRO_DISPLAY* display;
17 static ALLEGRO_FONT* main_font;16 static ALLEGRO_FONT* main_font;
1817
19 static View* current_view;
20 18
21private:19private:
22 Display() = delete;20 Display() = delete;
21
23 static void redraw();22 static void redraw();
23
24 static Drawable* main_widget;
25 static ALLEGRO_DISPLAY* display;
24};26};
2527
26#endif //__DISPLAY_HPP__28#endif //__DISPLAY_HPP__
2729
=== modified file 'src/drawable.cpp'
--- src/drawable.cpp 2013-07-07 08:48:44 +0000
+++ src/drawable.cpp 2013-07-23 20:39:00 +0000
@@ -2,20 +2,30 @@
2#include "allegro5/allegro.h"2#include "allegro5/allegro.h"
3#include "allegro5/allegro_primitives.h"3#include "allegro5/allegro_primitives.h"
4#include <iostream>4#include <iostream>
5 5
6Drawable::Drawable(int _w, int _h){6void Drawable::use_new_transform_to(int x,int y){
7 width = _w;7 ALLEGRO_TRANSFORM temp_transform;
8 height = _h;8 al_identity_transform(&temp_transform);
9 al_translate_transform(&temp_transform, x, y);
10 al_use_transform(&temp_transform);
11}
12
13Drawable::Drawable(){
9}14}
1015
11Drawable::~Drawable(){16Drawable::~Drawable(){
12}17}
1318
1419
15void Drawable::draw(){20void Drawable::draw(SDrawArea a){
21 use_new_transform_to(a.x,a.y);
16 ALLEGRO_COLOR red = al_map_rgb(255, 0, 0);22 ALLEGRO_COLOR red = al_map_rgb(255, 0, 0);
17 al_draw_filled_rectangle(0,0,width,height, red);23 al_draw_filled_rectangle(0,0, a.w, a.h, red);
1824
25}
26
27void Drawable::on_clicked(SCoordinates p){
28 on_clicked(); //by default, use the ignoring position version
19}29}
2030
21void Drawable::on_clicked(){31void Drawable::on_clicked(){
2232
=== modified file 'src/drawable.hpp'
--- src/drawable.hpp 2013-07-07 08:48:44 +0000
+++ src/drawable.hpp 2013-07-23 20:39:00 +0000
@@ -1,16 +1,38 @@
1 #ifndef __DRAWABLE_HPP__1#ifndef __DRAWABLE_HPP__
2 #define __DRAWABLE_HPP__2#define __DRAWABLE_HPP__
3 3
4 class Drawable{4struct SDrawArea{
5 public:5 SDrawArea(int _x, int _y, int _w, int _h) : x(_x), y(_y), w(_w), h(_h) {};
6 Drawable(int w, int h);6 int x;
7 int y;
8 int w;
9 int h;
10};
11
12struct SCoordinates{
13 int x;
14 int y;
15 SCoordinates(int _x, int _y) : x(_x), y(_y) {}
16 SCoordinates() : x(0), y(0) {}
17};
18
19
20class Drawable{
21public:
22 Drawable();
7 virtual ~Drawable();23 virtual ~Drawable();
824
9 int width;25 virtual void draw(SDrawArea area);
10 int height;26 /* Click coordinates are relative to widget position */
27 virtual void on_clicked(SCoordinates p);
28 /* This version ignores position */
29 virtual void on_clicked();
30
31 virtual int GetMinimalWidth () = 0;
32 virtual int GetMinimalHeight() = 0;
11 33
12 virtual void draw();34 /* A helpful macro, used by probably every drawable in its draw() func */
13 virtual void on_clicked();35 static void use_new_transform_to(int x, int y);
14 };36};
1537
16#endif //__DRAWABLE_HPP__38#endif //__DRAWABLE_HPP__
1739
=== modified file 'src/label.cpp'
--- src/label.cpp 2013-07-07 08:48:44 +0000
+++ src/label.cpp 2013-07-23 20:39:00 +0000
@@ -8,11 +8,18 @@
8extern ALLEGRO_FONT* main_font;8extern ALLEGRO_FONT* main_font;
99
1010
11Label::Label(std::string _text) : Drawable(60,20), text(_text){11Label::Label(std::string _text) : text(_text){
1212
13}13}
1414
15void Label::draw(){15void Label::draw(SDrawArea a){
16 use_new_transform_to(a.x,a.y);
16 ALLEGRO_COLOR white = al_map_rgb(255, 255, 255);17 ALLEGRO_COLOR white = al_map_rgb(255, 255, 255);
17 al_draw_text(Display::main_font, white, 30, 0 ,ALLEGRO_ALIGN_CENTRE, text.c_str());18 al_draw_text(Display::main_font, white, a.w/2, a.h/2 - 8 ,ALLEGRO_ALIGN_CENTRE, text.c_str());
18}19}
20
21int Label::GetMinimalHeight() {return 20;}
22int Label::GetMinimalWidth () {
23 return al_get_text_width(Display::main_font, text.c_str()) + 6; // 3px margin from both sides
24}
25
1926
=== modified file 'src/label.hpp'
--- src/label.hpp 2013-07-07 08:48:44 +0000
+++ src/label.hpp 2013-07-23 20:39:00 +0000
@@ -6,5 +6,8 @@
6 Label(std::string);6 Label(std::string);
7 std::string text;7 std::string text;
8 8
9 virtual void draw();9 virtual void draw(SDrawArea a) override;
10
11 virtual int GetMinimalHeight() override;
12 virtual int GetMinimalWidth () override;
10};13};
1114
=== modified file 'src/main.cpp'
--- src/main.cpp 2013-07-07 08:48:44 +0000
+++ src/main.cpp 2013-07-23 20:39:00 +0000
@@ -1,13 +1,14 @@
1#include "display.hpp"1#include "display.hpp"
2#include "button.hpp"2#include "button.hpp"
3#include "label.hpp"3#include "label.hpp"
4#include "view.hpp"4#include "Fixed.hpp"
5#include "VBox.hpp"
5#include <iostream>6#include <iostream>
6#include <cstdlib>7#include <cstdlib>
78
8View* main_menu;9Fixed additional_menu;
9View* additional_menu;
1010
11VBox main_menu_vbox;
1112
1213
13void click_reaction1(){14void click_reaction1(){
@@ -27,10 +28,10 @@
27}28}
2829
29void switch_to_main_menu(){30void switch_to_main_menu(){
30 Display::set_view(main_menu);31 Display::SetMainWidget(main_menu_vbox);
31}32}
32void switch_to_additional_menu(){33void switch_to_additional_menu(){
33 Display::set_view(additional_menu);34 Display::SetMainWidget(additional_menu);
34}35}
3536
3637
@@ -38,11 +39,9 @@
38int main(){39int main(){
39 Display::init();40 Display::init();
40 41
41 main_menu = new View();
42 additional_menu = new View();
43
44 Label label_main_menu("Main menu");42 Label label_main_menu("Main menu");
45 43
44
46 Button button1("Button1");45 Button button1("Button1");
47 button1.set_click_reaction(click_reaction1);46 button1.set_click_reaction(click_reaction1);
48 Button button2("Button2");47 Button button2("Button2");
@@ -61,22 +60,23 @@
61 button_to_main.set_click_reaction(switch_to_main_menu);60 button_to_main.set_click_reaction(switch_to_main_menu);
62 61
63 62
64 main_menu->add_item(&label_main_menu,Coordinates(40,25));63 main_menu_vbox.SetSpacing(3); // gaps between buttons
65 main_menu->add_item(&button1,Coordinates(40,50));64 main_menu_vbox.SetMargin(5); // empty frame around the box
66 main_menu->add_item(&button2,Coordinates(40,75));65 main_menu_vbox.Add(label_main_menu, 0);
67 main_menu->add_item(&button_to_2,Coordinates(40,100));66 main_menu_vbox.Add(button1, 1);
68 main_menu->add_item(&button_quit,Coordinates(40,125));67 main_menu_vbox.Add(button2, 2);
69 additional_menu->add_item(&label_additional_menu,Coordinates(42,27));68 main_menu_vbox.Add(button_to_2, 3, BOX_EXPAND);
70 additional_menu->add_item(&button3,Coordinates(42,52));69 main_menu_vbox.Add(button_quit, 4);
71 additional_menu->add_item(&button_to_main,Coordinates(42,77));70 additional_menu.add_item(label_additional_menu,SCoordinates(42,27));
71 additional_menu.add_item(button3, SCoordinates(42,52));
72 additional_menu.add_item(button_to_main, SCoordinates(42,77));
72 73
73 Display::set_view(main_menu);74 Display::SetMainWidget(main_menu_vbox);
74 75
75 Display::main_loop();76 Display::main_loop();
76 77
77 Display::cleanup();78 Display::cleanup();
78 79
79 delete main_menu, additional_menu;
80 80
81 return 0;81 return 0;
82}82}

Subscribers

People subscribed via source and target branches