00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef GFX_SUBWINDOW_HPP
00026 #define GFX_SUBWINDOW_HPP
00027
00028
00029 #include <string>
00030 #include <set>
00031 #include <iostream>
00032 #include <cmath>
00033
00034
00035 namespace gfx {
00036
00037
00049 class Subwindow
00050 {
00051 public:
00053 template<typename T>
00054 class bbox {
00055 public:
00056 bbox(T _x0, T _y0, T _x1, T _y1):
00057 x0(_x0), y0(_y0), x1(_x1), y1(_y1) { }
00058
00059 friend std::ostream & operator << (std::ostream & os, const bbox & b) {
00060 return os << "(" << b.x0 << ", " << b.y0
00061 << ", " << b.x1 << ", " << b.y1 << ")";
00062 }
00063
00064 T x0, y0, x1, y1;
00065 };
00066
00068 template<typename T>
00069 class point {
00070 public:
00071 point(T _x, T _y):
00072 x(_x), y(_y) { }
00073
00074 T x, y;
00075 };
00076
00077 typedef bbox<double> logical_bbox_t;
00078 typedef bbox<int> screen_bbox_t;
00079 typedef point<double> logical_point_t;
00080 typedef point<int> screen_point_t;
00081
00082
00083 Subwindow(const std::string & name,
00084 logical_bbox_t lbbox,
00085 bool enable = true,
00086 bool clickable = true);
00087 virtual ~Subwindow();
00088
00089 static Subwindow * GetSubwindow(logical_point_t lpoint);
00090 static Subwindow * GetSubwindow(screen_point_t spoint);
00091 static void DispatchUpdate();
00092 static void DispatchResize(screen_point_t winsize);
00093 static void DispatchDrag(screen_point_t mouse);
00094 static void DispatchClick(int button, int state, screen_point_t mouse);
00095
00096 virtual void PushProjection() const = 0;
00097 virtual void PopProjection() const = 0;
00098
00100 virtual void Update();
00101
00102 void Resize(screen_point_t winsize);
00103 void Reposition(logical_bbox_t lbbox);
00104 void Enable();
00105 void Disable();
00106 inline bool ContainsLogicalPoint(logical_point_t lpoint) const;
00107 inline bool ContainsScreenPoint(screen_point_t spoint) const;
00108 inline const std::string & Name() const;
00109 inline bool Enabled() const;
00110
00111 inline logical_point_t Screen2Logical(screen_point_t pixel) const;
00112 inline logical_bbox_t Screen2Logical(screen_bbox_t sbbox) const;
00113 inline screen_point_t Logical2Screen(logical_point_t lpoint) const;
00114 inline screen_bbox_t Logical2Screen(logical_bbox_t lbbox) const;
00115
00116 inline void InvertYaxis(screen_point_t & spoint) const;
00117 inline void InvertYaxis(screen_bbox_t & sbbox) const;
00118 inline void InvertYaxis(logical_point_t & lpoint) const;
00119 inline void InvertYaxis(logical_bbox_t & lbbox) const;
00120
00121 protected:
00122 virtual void PostResize() = 0;
00123 virtual void Click(int button, int state, screen_point_t mouse) = 0;
00124 virtual void Drag(screen_point_t mouse) = 0;
00125
00126 inline const logical_bbox_t & Lbbox() const { return m_lbbox; }
00127 inline const logical_point_t & Lsize() const { return m_lsize; }
00128 inline const screen_bbox_t & Sbbox() const { return m_sbbox; }
00129 inline const screen_point_t & Ssize() const { return m_ssize; }
00130 inline const screen_point_t & Winsize() const { return m_winsize; }
00131
00132
00133 private:
00134 typedef std::set<Subwindow *> registry_t;
00135
00136
00137 static Subwindow * Root();
00138
00139
00140 static registry_t m_registry;
00141 static Subwindow * m_lastclicked;
00142
00143 logical_bbox_t m_lbbox;
00144 logical_point_t m_lsize;
00145 screen_bbox_t m_sbbox;
00146 screen_point_t m_ssize;
00147 screen_point_t m_winsize;
00148 bool m_enabled;
00149 bool m_clickable;
00150 std::string m_name;
00151 };
00152
00153
00154 const std::string & Subwindow::
00155 Name()
00156 const
00157 {
00158 return m_name;
00159 }
00160
00161
00162 bool Subwindow::
00163 ContainsLogicalPoint(logical_point_t lpoint)
00164 const
00165 {
00166 return
00167 (lpoint.x >= m_lbbox.x0) &&
00168 (lpoint.y >= m_lbbox.y0) &&
00169 (lpoint.x <= m_lbbox.x1) &&
00170 (lpoint.y <= m_lbbox.y1);
00171 }
00172
00173
00174 bool Subwindow::
00175 ContainsScreenPoint(screen_point_t spoint)
00176 const
00177 {
00178 return
00179 (spoint.x >= m_sbbox.x0) &&
00180 (spoint.y >= m_sbbox.y0) &&
00181 (spoint.x <= m_sbbox.x1) &&
00182 (spoint.y <= m_sbbox.y1);
00183 }
00184
00185
00186 bool Subwindow::
00187 Enabled()
00188 const
00189 {
00190 return m_enabled;
00191 }
00192
00193
00194 Subwindow::logical_point_t Subwindow::
00195 Screen2Logical(screen_point_t pixel)
00196 const
00197 {
00198 return logical_point_t(static_cast<double>(pixel.x) / m_winsize.x,
00199 static_cast<double>(pixel.y) / m_winsize.y);
00200 }
00201
00202
00203 Subwindow::logical_bbox_t Subwindow::
00204 Screen2Logical(screen_bbox_t sbbox)
00205 const
00206 {
00207 return logical_bbox_t(static_cast<double>(sbbox.x0) / m_winsize.x,
00208 static_cast<double>(sbbox.y0) / m_winsize.y,
00209 static_cast<double>(sbbox.x1) / m_winsize.x,
00210 static_cast<double>(sbbox.y1) / m_winsize.y);
00211 }
00212
00213
00214 Subwindow::screen_point_t Subwindow::
00215 Logical2Screen(logical_point_t lpoint)
00216 const
00217 {
00218 return screen_point_t(static_cast<int>(rint(lpoint.x * m_winsize.x)),
00219 static_cast<int>(rint(lpoint.y * m_winsize.y)));
00220 }
00221
00222
00223 Subwindow::screen_bbox_t Subwindow::
00224 Logical2Screen(logical_bbox_t lbbox)
00225 const
00226 {
00227 return screen_bbox_t(static_cast<int>(floor(lbbox.x0 * m_winsize.x)),
00228 static_cast<int>(floor(lbbox.y0 * m_winsize.y)),
00229 static_cast<int>(ceil( lbbox.x1 * m_winsize.x)),
00230 static_cast<int>(ceil( lbbox.y1 * m_winsize.y)));
00231 }
00232
00233
00234 void Subwindow::
00235 InvertYaxis(screen_point_t & spoint)
00236 const
00237 {
00238 spoint.y = m_winsize.y - spoint.y;
00239 }
00240
00241
00242 void Subwindow::
00243 InvertYaxis(screen_bbox_t & sbbox)
00244 const
00245 {
00246 int y0bak(sbbox.y0);
00247 sbbox.y0 = m_winsize.y - sbbox.y1;
00248 sbbox.y1 = m_winsize.y - y0bak;
00249 }
00250
00251
00252 void Subwindow::
00253 InvertYaxis(logical_point_t & lpoint)
00254 const
00255 {
00256 lpoint.y = 1 - lpoint.y;
00257 }
00258
00259
00260 void Subwindow::
00261 InvertYaxis(logical_bbox_t & lbbox)
00262 const
00263 {
00264 double y0bak(lbbox.y0);
00265 lbbox.y0 = 1 - lbbox.y1;
00266 lbbox.y1 = 1 - y0bak;
00267 }
00268
00269 }
00270
00271 #endif // GFX_SUBWINDOW_HPP