0c05191246a7f3ce967bf6ed5aee4c8e1fae326c
[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 #ifndef NDEBUG
95       throw std::runtime_error("Invalid anchor point found");
96 #endif
97       log_warning << "Invalid anchor point found" << std::endl;
98       result.x = rect.get_left();
99       break;
100   }
101
102   switch(point & ANCHOR_H_MASK) {
103     case ANCHOR_TOP:
104       result.y = rect.get_top();
105       break;
106     case ANCHOR_MIDDLE:
107       result.y = rect.get_top() + (rect.get_bottom() - rect.get_top()) / 2.0;
108       break;
109     case ANCHOR_BOTTOM:
110       result.y = rect.get_bottom();
111       break;
112     default:
113 #ifndef NDEBUG
114       throw std::runtime_error("Invalid anchor point found");
115 #endif
116       log_warning << "Invalid anchor point found" << std::endl;
117       result.y = rect.get_top();
118       break;
119   }
120
121   return result;
122 }
123
124 Vector get_anchor_pos(const Rectf& destrect, float width, float height,
125                       AnchorPoint point)
126 {
127   Vector result;
128
129   switch(point & ANCHOR_V_MASK) {
130     case ANCHOR_LEFT:
131       result.x = destrect.get_left();
132       break;
133     case ANCHOR_MIDDLE:
134       result.x = destrect.get_middle().x - width/2.0;
135       break;
136     case ANCHOR_RIGHT:
137       result.x = destrect.get_right() - width;
138       break;
139     default:
140 #ifndef NDEBUG
141       throw std::runtime_error("Invalid anchor point found");
142 #endif
143       log_warning << "Invalid anchor point found" << std::endl;
144       result.x = destrect.get_left();
145       break;
146   }
147
148   switch(point & ANCHOR_H_MASK) {
149     case ANCHOR_TOP:
150       result.y = destrect.get_top();
151       break;
152     case ANCHOR_MIDDLE:
153       result.y = destrect.get_middle().y - height/2.0;
154       break;
155     case ANCHOR_BOTTOM:
156       result.y = destrect.get_bottom() - height;
157       break;
158     default:
159 #ifndef NDEBUG
160       throw std::runtime_error("Invalid anchor point found");
161 #endif
162       log_warning << "Invalid anchor point found" << std::endl;
163       result.y = destrect.get_top();
164       break;
165   }
166
167   return result;
168 }
169
170 /* EOF */