openscenegraph
Frame
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14// Code by: Jeremy Moles (cubicool) 2007-2008
15
16#ifndef OSGWIDGET_FRAME
17#define OSGWIDGET_FRAME
18
19#include <osgWidget/Table>
20
21namespace osgWidget {
22
23/*
24Lets take a moment and explain how Frame texturing works. When you create a Frame, you use
25a specially designed texture that is "chopped" up horizontally by the Frame code into 8 equal
26regions. Each region is then textured to a corresponding portion of the Frame, in the
27following order:
28
29 +---+---+---+---+---+---+---+---+
30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
31 +---+---+---+---+---+---+---+---+
32
33 1. Upper-Left corner.
34 2. Top border (rotated 90 degrees CCW).
35 3. Upper-Right corner.
36 4. Left border.
37 5. Right border.
38 6. Bottom-Left corner.
39 7. Bottom border (rotated 90 degrees CCW).
40 8. Bottom-Right corner.
41
42Now, these should be pretty self-explanatory if you visualize a frame as a 3x3 "table"
43(which is exactly what it is), but note how regions 2 and 7 are rotated counter-clockwise.
44We do this for a VERY important reason: we want to enable texture repeat on the border
45regions, so that when the frame is resized the borders cleanly paint the texture over
46the entire are (and don't stretch it). However, it is impossible in OpenGL to repeat a
47sub-region of a texture without including either the vertical or horizontal bounds, so the
48artist is required to rotate the region during their rendering so that our code can properly
49rotate it back internally and have it repeat in the desired way.
50
51This method of texturing a Frame object is inspired by World of Warcraft "edge files", and it
52is both efficient and easy-to-use--once you understand the basics. If you're still confused,
53take a look at this URL, or any of the example themes:
54
55 http://www.wowwiki.com/EdgeFiles
56*/
57
58class OSGWIDGET_EXPORT Frame: public Table
59{
60 public:
61
62 enum CornerType
63 {
64 CORNER_LOWER_LEFT,
65 CORNER_LOWER_RIGHT,
66 CORNER_UPPER_LEFT,
67 CORNER_UPPER_RIGHT
68 };
69
70 enum BorderType
71 {
72 BORDER_LEFT,
73 BORDER_RIGHT,
74 BORDER_TOP,
75 BORDER_BOTTOM
76 };
77
78 enum FrameOptions
79 {
80 FRAME_RESIZE = 1,
81 FRAME_MOVE = 2,
82 FRAME_TEXTURE = 4,
83 FRAME_ALL = FRAME_RESIZE | FRAME_MOVE | FRAME_TEXTURE
84 };
85
86 static std::string cornerTypeToString (CornerType);
87 static std::string borderTypeToString (BorderType);
88
89 class OSGWIDGET_EXPORT Corner: public Widget
90 {
91 public:
92 META_Object(osgWidget, Corner);
93
94 Corner (CornerType = CORNER_LOWER_LEFT, point_type = 0.0f, point_type = 0.0f);
95 Corner (const Corner&, const osg::CopyOp&);
96
97 virtual void parented (Window*);
98 virtual bool mouseDrag (double, double, const WindowManager*);
99
100 CornerType getCornerType() const
101 {
102 return _corner;
103 }
104
105 void setCornerType(CornerType corner)
106 {
107 _corner = corner;
108 }
109
110 void setCornerTypeAndName(CornerType corner)
111 {
112 _corner = corner;
113 _name = cornerTypeToString(corner);
114 }
115
116 protected:
117
118 CornerType _corner;
119 };
120
121 class OSGWIDGET_EXPORT Border: public Widget
122 {
123 public:
124 META_Object(osgWidget, Border);
125
126 Border (BorderType = BORDER_LEFT, point_type = 0.0f, point_type = 0.0f);
127 Border (const Border&, const osg::CopyOp&);
128
129 virtual void parented (Window*);
130 virtual void positioned ();
131 virtual bool mouseDrag (double, double, const WindowManager*);
132
133 BorderType getBorderType() const
134 {
135 return _border;
136 }
137
138 void setBorderType(BorderType border)
139 {
140 _border = border;
141 }
142
143 void setBorderTypeAndName(BorderType border)
144 {
145 _border = border;
146 _name = borderTypeToString(border);
147 }
148
149 protected:
150
151 BorderType _border;
152 };
153
154 META_Object(osgWidget, Frame);
155
156 Frame (const std::string& = "", unsigned int = 0);
157 Frame (const Frame&, const osg::CopyOp&);
158
159 static Frame* createSimpleFrame(
160 const std::string&,
161 point_type,
162 point_type,
163 point_type,
164 point_type,
165 unsigned int = 0,
166 Frame* = 0
167 );
168
169 static Frame* createSimpleFrameWithSingleTexture(
170 const std::string&,
171 osg::ref_ptr<osg::Image>,
172 point_type,
173 point_type,
174 unsigned int = 0,
175 Frame* = 0
176 );
177
178 static Frame* createSimpleFrameFromTheme(
179 const std::string&,
180 osg::ref_ptr<osg::Image>,
181 point_type,
182 point_type,
183 unsigned int = 0,
184 Frame* = 0
185 );
186
187 void createSimpleFrame(point_type cw, point_type ch, point_type w, point_type h)
188 {
189 createSimpleFrame(_name, cw, ch, w, h, 0, this);
190 }
191
192 void createSimpleFrameWithSingleTexture(
193 osg::Image* image,
194 point_type w,
195 point_type h
196 )
197 {
198 createSimpleFrameWithSingleTexture(_name, image, w, h, 0, this);
199 }
200
201 bool setWindow(Window*);
202
203 EmbeddedWindow* getEmbeddedWindow() { return dynamic_cast<EmbeddedWindow*>(getByRowCol(1, 1)); }
204
205 const EmbeddedWindow* getEmbeddedWindow() const { return dynamic_cast<const EmbeddedWindow*>(getByRowCol(1, 1)); }
206
207 Corner* getCorner(CornerType c) { return dynamic_cast<Corner*>(_getCorner(c)); }
208
209 const Corner* getCorner(CornerType c) const { return dynamic_cast<const Corner*>(_getCorner(c)); }
210
211 Border* getBorder(BorderType b) { return dynamic_cast<Border*>(_getBorder(b)); }
212
213 const Border* getBorder(BorderType b) const { return dynamic_cast<const Border*>(_getBorder(b)); }
214
215 // This method resizes the internal EmbeddedWindow object and then properly resizes
216 // the reset of the Frame based on the sizes of the Corners, Borders, etc.
217 bool resizeFrame(point_type, point_type);
218
219 unsigned int getFlags() const
220 {
221 return _flags;
222 }
223
224 void setFlags(unsigned int flags)
225 {
226 _flags = flags;
227 }
228
229 bool canResize() const
230 {
231 return (_flags & FRAME_RESIZE) != 0;
232 }
233
234 bool canMove() const
235 {
236 return (_flags & FRAME_MOVE) != 0;
237 }
238
239 bool canTexture() const
240 {
241 return (_flags & FRAME_TEXTURE) != 0;
242 }
243
244 protected:
245
246 Widget* _getCorner (CornerType) const;
247 Widget* _getBorder (BorderType) const;
248
249 unsigned int _flags;
250};
251
252}
253
254#endif