Files
OpenSceneGraph/src/osgWidget/Frame.cpp
2008-08-18 11:17:44 +00:00

252 lines
7.1 KiB
C++

// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Frame.cpp 59 2008-05-15 20:55:31Z cubicool $
#include <osgDB/ReadFile>
#include <osgWidget/WindowManager>
#include <osgWidget/Frame>
namespace osgWidget {
std::string Frame::cornerToString(CORNER c) {
if(c == CORNER_LOWER_LEFT) return "CornerLowerLeft";
else if(c == CORNER_LOWER_RIGHT) return "CornerLowerRight";
else if(c == CORNER_UPPER_RIGHT) return "CornerUpperRight";
else return "CornerUpperLeft";
}
std::string Frame::borderToString(BORDER b) {
if(b == BORDER_LEFT) return "BorderLeft";
else if(b == BORDER_RIGHT) return "BorderRight";
else if(b == BORDER_TOP) return "BorderTop";
else return "BorderBottom";
}
Frame::Corner::Corner(CORNER corner, point_type width, point_type height):
Widget (cornerToString(corner), width, height),
_corner (corner) {
setEventMask(EVENT_MASK_MOUSE_DRAG);
}
Frame::Corner::Corner(const Corner& corner, const osg::CopyOp& co):
Widget (corner, co),
_corner (corner._corner) {
}
bool Frame::Corner::mouseDrag(double x, double y, WindowManager* wm) {
Window* parent = getParent();
if(!parent) return false;
if(wm->isInvertedY()) {
if(_corner == CORNER_UPPER_LEFT) {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
else if(_corner == CORNER_UPPER_RIGHT) {
if(parent->resizeAdd(x, -y)) parent->addY(y);
}
else if(_corner == CORNER_LOWER_RIGHT) parent->resizeAdd(x, y);
else {
if(parent->resizeAdd(-x, y)) parent->addX(x);
}
}
// These are basically flipped-around versions of the above routines; we
// do it this way to avoid lots of uncessary if tests.
else {
if(_corner == CORNER_UPPER_LEFT) {
if(parent->resizeAdd(-x, y)) parent->addX(x);
}
else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y);
else if(_corner == CORNER_LOWER_RIGHT) {
if(parent->resizeAdd(x, -y)) parent->addY(y);
}
else {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
}
parent->update();
return true;
}
Frame::Border::Border(BORDER border, point_type width, point_type height):
Widget (borderToString(border), width, height),
_border (border) {
setCanFill(true);
setEventMask(EVENT_MASK_MOUSE_DRAG);
}
Frame::Border::Border(const Border& border, const osg::CopyOp& co):
Widget (border, co),
_border (border._border) {
}
bool Frame::Border::mouseDrag(double x, double y, WindowManager* wm) {
Window* parent = getParent();
if(!parent) return false;
if(_border == BORDER_LEFT) {
if(parent->resizeAdd(-x, 0.0f)) parent->addX(x);
}
else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f);
else if(_border == BORDER_TOP) parent->addOrigin(x, y);
else {
// The only BORDER that inverted-Y affects is this...
if(wm->isInvertedY()) parent->resizeAdd(0.0f, y);
else {
if(parent->resizeAdd(0.0f, -y)) parent->addY(y);
}
}
parent->update();
return true;
}
Frame::Frame(const std::string& name):
Table(name, 3, 3) {
}
Frame::Frame(const Frame& frame, const osg::CopyOp& co):
Table(frame, co) {
}
Widget* Frame::_getCorner(CORNER c) const {
return const_cast<Widget*>(getByName(cornerToString(c)));
}
Widget* Frame::_getBorder(BORDER b) const {
return const_cast<Widget*>(getByName(borderToString(b)));
}
void Frame::managed(WindowManager* wm) {
Window::managed(wm);
// Our Frame is created in an inverted-Y environment, so if this is the case
// just return here.
if(wm->isInvertedY()) return;
Corner* ll = getCorner(CORNER_LOWER_LEFT);
Corner* lr = getCorner(CORNER_LOWER_RIGHT);
Corner* ul = getCorner(CORNER_UPPER_LEFT);
Corner* ur = getCorner(CORNER_UPPER_RIGHT);
Border* t = getBorder(BORDER_TOP);
Border* b = getBorder(BORDER_BOTTOM);
if(!ll || !lr || !ul || !ur || !t || !b) {
warn()
<< "One or more of your Corner/Border objects in the Frame ["
<< _name << "] are invalid; cannot invert orientation." << std::endl
;
return;
}
ll->setCornerAndName(CORNER_UPPER_LEFT);
lr->setCornerAndName(CORNER_UPPER_RIGHT);
ul->setCornerAndName(CORNER_LOWER_LEFT);
ur->setCornerAndName(CORNER_LOWER_RIGHT);
t->setBorderAndName(BORDER_BOTTOM);
b->setBorderAndName(BORDER_TOP);
}
bool Frame::setWindow(Window* window) {
if(!window) return false;
EmbeddedWindow* ew = getEmbeddedWindow();
// If it's the first time setting the Window...
// if(!ew || !ew->getWindow()) return addWidget(window->embed(), 1, 1);
if(!ew) return addWidget(window->embed(), 1, 1);
else return ew->setWindow(window);
}
Frame* Frame::createSimpleFrame(
const std::string& name,
point_type cw,
point_type ch,
point_type w,
point_type h,
Frame* exFrame
) {
Frame* frame = 0;
// Use an "existing frame" if we have it (for example, if you've in inherited from
// Frame and want to use this stuff.
if(!exFrame) frame = new Frame(name);
else frame = exFrame;
frame->addWidget(new Corner(CORNER_UPPER_LEFT, cw, ch), 0, 0);
frame->addWidget(new Border(BORDER_TOP, w, ch), 0, 1);
frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 0, 2);
frame->addWidget(new Border(BORDER_LEFT, cw, h), 1, 0);
frame->addWidget(new Border(BORDER_RIGHT, cw, h), 1, 2);
frame->addWidget(new Corner(CORNER_LOWER_LEFT, cw, ch), 2, 0);
frame->addWidget(new Border(BORDER_BOTTOM, w, ch), 2, 1);
frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 2, 2);
EmbeddedWindow* ew = new EmbeddedWindow(name, w, h);
ew->setCanFill(true);
frame->addWidget(ew, 1, 1);
return frame;
}
Frame* Frame::createSimpleFrameWithSingleTexture(
const std::string& name,
const std::string& texture,
point_type tw,
point_type th,
point_type cw,
point_type ch,
point_type w,
point_type h,
Frame* exFrame
) {
Frame* frame = 0;
// The same as above...
if(!exFrame) frame = createSimpleFrame(name, cw, ch, w, h);
else frame = createSimpleFrame(name, cw, ch, w, h, exFrame);
for(unsigned int i = 0; i < 9; i++) frame->getObjects()[i]->setImage(texture);
frame->getByRowCol(0, 0)->setTexCoordRegion(0.0f, th - ch, cw, ch);
frame->getByRowCol(0, 1)->setTexCoordRegion(cw, th - ch, tw - (cw * 2.0f), ch);
frame->getByRowCol(0, 2)->setTexCoordRegion(tw - cw, th - ch, cw, ch);
frame->getByRowCol(1, 0)->setTexCoordRegion(0.0f, ch, cw, th - (ch * 2.0f));
frame->getByRowCol(1, 2)->setTexCoordRegion(tw - cw, ch, cw, th - (ch * 2.0f));
frame->getByRowCol(2, 0)->setTexCoordRegion(0.0f, 0.0f, cw, ch);
frame->getByRowCol(2, 1)->setTexCoordRegion(cw, 0.0f, tw - (cw * 2.0f), ch);
frame->getByRowCol(2, 2)->setTexCoordRegion(tw - cw, 0.0f, cw, ch);
frame->getEmbeddedWindow()->setTexCoordRegion(cw, ch, tw - (cw * 2.0f), th - (ch * 2.0f));
return frame;
}
}