本示例演示osgearth_controls示例,包括各种控件的添加以及简单的事件相应。
像小房子一样的图片,是替换了源码中个gif图。不知为何gif图总是加载不上。
执行程序
// 依然沿用之前的earth文件
osgearth_controlsd.exe earth_image\china-simple.earth
滑动红色进度条,对应的会显示百分比。
选中checkbox 1,会打印输入选中情况。
滑动蓝色进度条,粉色房子会旋转。
点击4个标签,会打印输出点击标签上位置xy信息。
对代码checkbox部分进行了增加,增加选中复选框时,打印输出选中状态。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace osgEarth::Symbology;
using namespace osgEarth::Util::Controls;
void createControls( ControlCanvas* );
ImageControl* s_imageControl = 0L;// 包含光栅图像的控件。全局变量
int main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc,argv);
osgViewer::Viewer viewer(arguments);
osg::Node* node = osgEarth::Util::MapNodeHelper().load(arguments, &viewer);
if (!node)
{
OE_WARN << "No earth file on the command line." << std::endl;
return -1;
}
osg::Group* root = new osg::Group();
root->addChild( node );
// create a surface to house the controls 创建曲面以放置控件,父类为osg::Camera
ControlCanvas* cs = ControlCanvas::getOrCreate( &viewer );
viewer.setSceneData( root );
viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator );
// create some controls.
createControls( cs );
return viewer.run();
}
// 点击事件
struct MyClickHandler : public ControlEventHandler
{
// 在什么控件上点击,并输出鼠标在控件中点击的位置
void onClick( Control* control, const osg::Vec2f& pos, int mouseButtonMask )
{
OE_NOTICE << "You clicked at (" << pos.x() << ", " << pos.y() << ") within the control."
<< std::endl;
}
};
// 仿照 MyClickHandler点击事件,写checkbox勾选事件
struct MyCheckBoxHandler : public ControlEventHandler
{
// 在什么控件上点击,并输出鼠标在控件中点击的位置
void onValueChanged(Control* control, bool value)
{
OE_NOTICE << "You checked at " << value << std::endl;
}
};
// 标签控件
static LabelControl* s_sliderLabel;// 全局变量
// 滑块控件
struct MySliderHandler : public ControlEventHandler
{
void onValueChanged( Control* control, float value )
{
std::stringstream buf;
buf << (int)value;
std::string str;
str = buf.str();
s_sliderLabel->setText( str );// 将变化的值显示在标签上
}
};
// 旋转图
struct RotateImage : public ControlEventHandler
{
void onValueChanged( Control* control, float value )
{
if (s_imageControl)
s_imageControl->setRotation( Angular(value) );
}
};
void
createControls( ControlCanvas* cs )
{
// a container centered on the screen, containing an image and a text label.
{
VBox* center = new VBox();
center->setBorderColor( 1, 1, 1, 1 );// 边框白色
center->setBackColor( .6,.5,.4,0.5 );// 填充色
center->setPadding( 10 ); // 内边距属性
center->setHorizAlign( Control::ALIGN_CENTER );// 水平居中
center->setVertAlign( Control::ALIGN_CENTER ); // 垂直居中
// Add an image:
// gif的图加载不上
// osg::ref_ptr image = osgDB::readRefImageFile("D:/FreeXGIS/osgearth_gch/data/osgearth.gif");
osg::ref_ptr image = osgDB::readRefImageFile("D:/FreeXGIS/osgearth_gch/data/m2525_air.png");
if ( image.valid() )
{
// s_imageControl 全局变量,可以接收到滑块的值
s_imageControl = new ImageControl( image.get() );
s_imageControl->setHorizAlign( Control::ALIGN_CENTER );// 图片居中
s_imageControl->setFixSizeForRotation( true );// 支持旋转
center->addControl( s_imageControl );
center->setHorizAlign( Control::ALIGN_CENTER );// 水平居中(上面不是设置过了吗???)
}
// Add a text label:
LabelControl* label = new LabelControl( "osgEarth Controls Toolkit" );
label->setFont( osgEarth::Registry::instance()->getDefaultFont() );
label->setFontSize( 24.0f );// 字号
label->setHorizAlign( Control::ALIGN_CENTER );// 字体居中
label->setMargin( 5 );// 边距5像素
center->addControl( label );
// Rotation slider
HBox* rotateBox = new HBox();// 水平
rotateBox->setChildVertAlign( Control::ALIGN_CENTER );// 插入HBox的控件垂直居中
rotateBox->setHorizFill( true );// 控件水平填充
rotateBox->setBackColor( Color::Blue );// 背景蓝色
{
rotateBox->addControl( new LabelControl("Rotate: ") );// 添加label控件
HSliderControl* rotateSlider = new HSliderControl( -180.0, 180.0, 0.0 );// 滑块控件,范围[-180,180]
rotateSlider->addEventHandler( new RotateImage() );// s_imageControl 可以接收到值
rotateSlider->setHeight( 8.0f );// 高度
rotateSlider->setHorizFill( true );// 控件水平填充
rotateBox->addControl( rotateSlider );// 滑块放入旋转box中
}
center->addControl( rotateBox );
cs->addControl( center );
}
// a simple vbox with absolute positioning in the upper left with two text labels.
{
VBox* ul = new VBox();// 垂直box
ul->setPosition( 20, 20 );
ul->setPadding( 10 );// 内边距
{
// 不同于上面的label控件的构造方式
LabelControl* title = new LabelControl( "Upper left control", 22, osg::Vec4f(1,1,0,1) );
ul->addControl( title );
LabelControl* content = new LabelControl( "Here is some text in the upper left control" );
ul->addControl( content );
HBox* c2 = new HBox();// 水平box
c2->setChildSpacing( 10 );// 子控件的间距
{
HSliderControl* slider = new HSliderControl( 0, 100 );
slider->setBackColor( .6,0,0,1 );
slider->setHeight( 25 );
slider->setWidth( 300 );
slider->addEventHandler( new MySliderHandler() );
c2->addControl( slider );
s_sliderLabel = new LabelControl();// 按理说,应该先new s_sliderLabel,再new slider.
s_sliderLabel->setVertAlign( Control::ALIGN_CENTER );
c2->addControl( s_sliderLabel );
}
ul->addControl( c2 );
HBox* c3 = new HBox(); // 处理两个复选框
c3->setHorizAlign( Control::ALIGN_CENTER );
c3->setChildSpacing( 10 );
{
HBox* c4 = new HBox(); // 每一个复选框,都是由一个框和一个文字组成
c4->setChildSpacing( 5 );
{
// 原版并没有添加事件
//c4->addControl( new CheckBoxControl( true ) );
//c4->addControl( new LabelControl( "Checkbox 1" ) );
// 修改获取选中状态并打印输出
CheckBoxControl *ckbx = new CheckBoxControl(true);
ckbx->addEventHandler(new MyCheckBoxHandler());
c4->addControl(ckbx);
c4->addControl(new LabelControl("Checkbox 1"));
}
c3->addControl( c4 );
HBox* c5 = new HBox();
c5->setChildSpacing( 5 );
{
c5->addControl( new CheckBoxControl( false ) );
c5->addControl( new LabelControl( "Checkbox 2" ) );
}
c3->addControl( c5 );
}
ul->addControl( c3 );
}
cs->addControl( ul );
ul->addEventHandler( new MyClickHandler );
}
// a centered hbox container along the bottom on the screen.
{
HBox* bottom = new HBox();// 底部的水平box,放了4个label
bottom->setBackColor(0,0,0,0.5);
bottom->setMargin( 10 );
bottom->setChildSpacing( 145 );
bottom->setVertAlign( Control::ALIGN_BOTTOM );// 垂直方向,靠底部
bottom->setHorizAlign( Control::ALIGN_CENTER );
for( int i=0; i<4; ++i )
{
LabelControl* label = new LabelControl();
std::stringstream buf;
buf << "Label_" << i;
std::string str;
str = buf.str();
label->setText( str );
label->setMargin( 10 );
label->setBackColor( 1,1,1,0.4 );// 背景色
bottom->addControl( label );
label->setActiveColor(1,.3,.3,1);
label->addEventHandler( new MyClickHandler );
}
cs->addControl( bottom );
}
}