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