Minimal code for earthflower active ability.
[supertux.git] / src / object / anchor_point.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "object/anchor_point.hpp"
18
19 #include <config.h>
20
21 #include <stdexcept>
22 #include <sstream>
23
24 #include "math/rectf.hpp"
25 #include "util/log.hpp"
26
27 std::string anchor_point_to_string(AnchorPoint point)
28 {
29   switch(point) {
30     case ANCHOR_TOP_LEFT:
31       return "topleft";
32     case ANCHOR_TOP:
33       return "top";
34     case ANCHOR_TOP_RIGHT:
35       return "topright";
36     case ANCHOR_LEFT:
37       return "left";
38     case ANCHOR_MIDDLE:
39       return "middle";
40     case ANCHOR_RIGHT:
41       return "right";
42     case ANCHOR_BOTTOM_LEFT:
43       return "bottomleft";
44     case ANCHOR_BOTTOM:
45       return "bottom";
46     case ANCHOR_BOTTOM_RIGHT:
47       return "bottomright";
48     default:
49       throw std::runtime_error("Invalid anchor point");
50   }
51 }
52
53 AnchorPoint string_to_anchor_point(const std::string& str)
54 {
55   if(str == "topleft")
56     return ANCHOR_TOP_LEFT;
57   else if(str == "top")
58     return ANCHOR_TOP;
59   else if(str == "topright")
60     return ANCHOR_TOP_RIGHT;
61   else if(str == "left")
62     return ANCHOR_LEFT;
63   else if(str == "middle")
64     return ANCHOR_MIDDLE;
65   else if(str == "right")
66     return ANCHOR_RIGHT;
67   else if(str == "bottomleft")
68     return ANCHOR_BOTTOM_LEFT;
69   else if(str == "bottom")
70     return ANCHOR_BOTTOM;
71   else if(str == "bottomright")
72     return ANCHOR_BOTTOM_RIGHT;
73
74   std::ostringstream msg;
75   msg << "Unknown anchor '" << str << "'";
76   throw std::runtime_error(msg.str());
77 }
78
79 Vector get_anchor_pos(const Rectf& rect, AnchorPoint point)
80 {
81   Vector result;
82
83   switch(point & ANCHOR_V_MASK) {
84     case ANCHOR_LEFT:
85       result.x = rect.get_left();
86       break;
87     case ANCHOR_MIDDLE:
88       result.x = rect.get_left() + (rect.get_right() - rect.get_left()) / 2.0;
89       break;
90     case ANCHOR_RIGHT:
91       result.x = rect.get_right();
92       break;
93     default:
94       log_warning << "Invalid anchor point found" << std::endl;
95       result.x = rect.get_left();
96       break;
97   }
98
99   switch(point & ANCHOR_H_MASK) {
100     case ANCHOR_TOP:
101       result.y = rect.get_top();
102       break;
103     case ANCHOR_MIDDLE:
104       result.y = rect.get_top() + (rect.get_bottom() - rect.get_top()) / 2.0;
105       break;
106     case ANCHOR_BOTTOM:
107       result.y = rect.get_bottom();
108       break;
109     default:
110       log_warning << "Invalid anchor point found" << std::endl;
111       result.y = rect.get_top();
112       break;
113   }
114
115   return result;
116 }
117
118 Vector get_anchor_pos(const Rectf& destrect, float width, float height,
119                       AnchorPoint point)
120 {
121   Vector result;
122
123   switch(point & ANCHOR_V_MASK) {
124     case ANCHOR_LEFT:
125       result.x = destrect.get_left();
126       break;
127     case ANCHOR_MIDDLE:
128       result.x = destrect.get_middle().x - width/2.0;
129       break;
130     case ANCHOR_RIGHT:
131       result.x = destrect.get_right() - width;
132       break;
133     default:
134       log_warning << "Invalid anchor point found" << std::endl;
135       result.x = destrect.get_left();
136       break;
137   }
138
139   switch(point & ANCHOR_H_MASK) {
140     case ANCHOR_TOP:
141       result.y = destrect.get_top();
142       break;
143     case ANCHOR_MIDDLE:
144       result.y = destrect.get_middle().y - height/2.0;
145       break;
146     case ANCHOR_BOTTOM:
147       result.y = destrect.get_bottom() - height;
148       break;
149     default:
150       log_warning << "Invalid anchor point found" << std::endl;
151       result.y = destrect.get_top();
152       break;
153   }
154
155   return result;
156 }
157
158 /* EOF */