1 /******************************************************************************
2 * Warmux is a convivial mass murder game.
3 * Copyright (C) 2001-2011 Warmux Team.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 *****************************************************************************/
19
20 #include <sstream>
21 #include "include/app.h"
22 #include "gui/spin_button_picture.h"
23 #include "gui/torus_cache.h"
24 #include "graphic/polygon_generator.h"
25 #include "graphic/text.h"
26 #include "graphic/sprite.h"
27 #include "graphic/video.h"
28 #include "tool/math_tools.h"
29 #include "tool/affine_transform.h"
30 #include "tool/resource_manager.h"
31
32 #define SMALL_R 25
33 #define BIG_R 35
34 #define OPEN_ANGLE 0.96f // 55
35
SpinButtonWithPicture(const std::string & label,const std::string & resource_id,const Point2i & _size,int value,int step,int min_value,int max_value)36 SpinButtonWithPicture::SpinButtonWithPicture(const std::string& label,
37 const std::string& resource_id,
38 const Point2i& _size,
39 int value, int step,
40 int min_value, int max_value)
41 : AbstractSpinButton(value, step, min_value, max_value)
42 {
43 position = Point2i(-1, -1);
44 size = _size;
45
46 Profile *res = GetResourceManager().LoadXMLProfile("graphism.xml", false);
47 torus = new TorusCache(res, resource_id, BIG_R, SMALL_R);
48
49 txt_label = new Text(label, dark_gray_color, Font::FONT_SMALL, Font::FONT_BOLD, false);
50 txt_label->SetMaxWidth(GetSizeX());
51
52 txt_value_black = new Text("", black_color, Font::FONT_MEDIUM, Font::FONT_BOLD, false);
53 txt_value_white = new Text("", white_color, Font::FONT_MEDIUM, Font::FONT_BOLD, false);
54
55 ValueHasChanged();
56 }
57
~SpinButtonWithPicture()58 SpinButtonWithPicture::~SpinButtonWithPicture ()
59 {
60 delete txt_label;
61 delete txt_value_black;
62 delete txt_value_white;
63 delete torus;
64 }
65
Pack()66 void SpinButtonWithPicture::Pack()
67 {
68 txt_label->SetMaxWidth(size.x);
69 }
70
Draw(const Point2i & mousePosition)71 void SpinButtonWithPicture::Draw(const Point2i &mousePosition)
72 {
73 Surface& surf = GetMainWindow();
74
75 // the computed positions are to center on the image part of the widget
76
77 // 1. draw torus
78 torus->Draw(*this);
79
80 // 2. then draw buttons
81 #define IMG_BUTTONS_W 5
82 #define IMG_BUTTONS_H 12
83
84 Point2i center = GetPosition() + torus->GetCenter();
85 if (GetValue() > GetMinValue()) {
86
87 if (Contains(mousePosition) && mousePosition.x < center.x)
88 torus->m_minus->SetCurrentFrame(1);
89 else
90 torus->m_minus->SetCurrentFrame(0);
91
92 torus->m_minus->Blit(surf, GetPosition().x + IMG_BUTTONS_W, GetPosition().y + IMG_BUTTONS_H);
93 }
94
95 if (GetValue() < GetMaxValue()) {
96 if (Contains(mousePosition) && mousePosition.x > center.x)
97 torus->m_plus->SetCurrentFrame(1);
98 else
99 torus->m_plus->SetCurrentFrame(0);
100
101 torus->m_plus->Blit(surf, GetPosition().x + GetSize().x - torus->m_plus->GetWidth() - IMG_BUTTONS_W,
102 GetPosition().y + IMG_BUTTONS_H);
103 }
104
105 // 6. add in the value image
106 int tmp_x = center.x;
107 int tmp_y = center.y + SMALL_R - 3;
108 uint value_h = Font::GetInstance(Font::FONT_MEDIUM)->GetHeight();
109
110 txt_value_black->DrawCenterTop(Point2i(tmp_x + 1, tmp_y + 1 - value_h/2));
111 txt_value_white->DrawCenterTop(Point2i(tmp_x, tmp_y - value_h/2));
112
113 // 7. and finally the label image
114 txt_label->DrawCenterTop(Point2i(GetPositionX() + GetSizeX()/2,
115 GetPositionY() + GetSizeY() - txt_label->GetHeight()));
116 }
117
RecreateTorus()118 void SpinButtonWithPicture::RecreateTorus()
119 {
120 float angle = (2.0f*M_PI - OPEN_ANGLE) * (GetValue() - GetMinValue())
121 / (GetMaxValue() - GetMinValue());
122 torus->Refresh(angle, OPEN_ANGLE);
123 }
124
ClickUp(const Point2i & mousePosition,uint button)125 Widget* SpinButtonWithPicture::ClickUp(const Point2i &mousePosition, uint button)
126 {
127 NeedRedrawing();
128
129 if (!Contains(mousePosition)) {
130 return NULL;
131 }
132
133 bool is_click = Mouse::IS_CLICK_BUTTON(button);
134 //if (button == Mouse::BUTTON_RIGHT() || button == SDL_BUTTON_WHEELDOWN) {
135 if ( (is_click && mousePosition.x <= (GetPositionX() + GetSizeX()/2))
136 || button == SDL_BUTTON_WHEELDOWN ) {
137 DecValue();
138 return this;
139 } else if ( (is_click && mousePosition.x > (GetPositionX() + GetSizeX()/2))
140 || button == SDL_BUTTON_WHEELUP ) {
141 //} else if (button == Mouse::BUTTON_LEFT() || button == SDL_BUTTON_WHEELUP) {
142 IncValue();
143 return this;
144 }
145
146 return NULL;
147 }
148
ValueHasChanged()149 void SpinButtonWithPicture::ValueHasChanged()
150 {
151 std::ostringstream value_s;
152 value_s << GetValue();
153
154 std::string s(value_s.str());
155 txt_value_black->SetText(s);
156 txt_value_white->SetText(s);
157 RecreateTorus();
158 }
159