1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
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.
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.
14// Code by: Jeremy Moles (cubicool) 2007-2008
16#ifndef OSGWIDGET_FRAME
17#define OSGWIDGET_FRAME
19#include <osgWidget/Table>
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
29 +---+---+---+---+---+---+---+---+
30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
31 +---+---+---+---+---+---+---+---+
34 2. Top border (rotated 90 degrees CCW).
35 3. Upper-Right corner.
38 6. Bottom-Left corner.
39 7. Bottom border (rotated 90 degrees CCW).
40 8. Bottom-Right corner.
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.
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:
55 http://www.wowwiki.com/EdgeFiles
58class OSGWIDGET_EXPORT Frame: public Table
83 FRAME_ALL = FRAME_RESIZE | FRAME_MOVE | FRAME_TEXTURE
86 static std::string cornerTypeToString (CornerType);
87 static std::string borderTypeToString (BorderType);
89 class OSGWIDGET_EXPORT Corner: public Widget
92 META_Object(osgWidget, Corner);
94 Corner (CornerType = CORNER_LOWER_LEFT, point_type = 0.0f, point_type = 0.0f);
95 Corner (const Corner&, const osg::CopyOp&);
97 virtual void parented (Window*);
98 virtual bool mouseDrag (double, double, const WindowManager*);
100 CornerType getCornerType() const
105 void setCornerType(CornerType corner)
110 void setCornerTypeAndName(CornerType corner)
113 _name = cornerTypeToString(corner);
121 class OSGWIDGET_EXPORT Border: public Widget
124 META_Object(osgWidget, Border);
126 Border (BorderType = BORDER_LEFT, point_type = 0.0f, point_type = 0.0f);
127 Border (const Border&, const osg::CopyOp&);
129 virtual void parented (Window*);
130 virtual void positioned ();
131 virtual bool mouseDrag (double, double, const WindowManager*);
133 BorderType getBorderType() const
138 void setBorderType(BorderType border)
143 void setBorderTypeAndName(BorderType border)
146 _name = borderTypeToString(border);
154 META_Object(osgWidget, Frame);
156 Frame (const std::string& = "", unsigned int = 0);
157 Frame (const Frame&, const osg::CopyOp&);
159 static Frame* createSimpleFrame(
169 static Frame* createSimpleFrameWithSingleTexture(
171 osg::ref_ptr<osg::Image>,
178 static Frame* createSimpleFrameFromTheme(
180 osg::ref_ptr<osg::Image>,
187 void createSimpleFrame(point_type cw, point_type ch, point_type w, point_type h)
189 createSimpleFrame(_name, cw, ch, w, h, 0, this);
192 void createSimpleFrameWithSingleTexture(
198 createSimpleFrameWithSingleTexture(_name, image, w, h, 0, this);
201 bool setWindow(Window*);
203 EmbeddedWindow* getEmbeddedWindow() { return dynamic_cast<EmbeddedWindow*>(getByRowCol(1, 1)); }
205 const EmbeddedWindow* getEmbeddedWindow() const { return dynamic_cast<const EmbeddedWindow*>(getByRowCol(1, 1)); }
207 Corner* getCorner(CornerType c) { return dynamic_cast<Corner*>(_getCorner(c)); }
209 const Corner* getCorner(CornerType c) const { return dynamic_cast<const Corner*>(_getCorner(c)); }
211 Border* getBorder(BorderType b) { return dynamic_cast<Border*>(_getBorder(b)); }
213 const Border* getBorder(BorderType b) const { return dynamic_cast<const Border*>(_getBorder(b)); }
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);
219 unsigned int getFlags() const
224 void setFlags(unsigned int flags)
229 bool canResize() const
231 return (_flags & FRAME_RESIZE) != 0;
236 return (_flags & FRAME_MOVE) != 0;
239 bool canTexture() const
241 return (_flags & FRAME_TEXTURE) != 0;
246 Widget* _getCorner (CornerType) const;
247 Widget* _getBorder (BorderType) const;