00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # ifdef FC_OS_WIN32
00028 # include <windows.h>
00029 # endif
00030 # ifdef FC_OS_MACOSX
00031 # include <OpenGL/gl.h>
00032 # else
00033 # include <GL/gl.h>
00034 # endif
00035 # include <cfloat>
00036 # include <algorithm>
00037 # include <QFontMetrics>
00038 # include <QGLWidget>
00039 # include <QPainter>
00040 # include <QPen>
00041 # include <Inventor/actions/SoGLRenderAction.h>
00042 # include <Inventor/bundles/SoMaterialBundle.h>
00043 # include <Inventor/elements/SoLazyElement.h>
00044 # include <Inventor/nodes/SoSurroundScale.h>
00045 # include <Inventor/misc/SoState.h>
00046 #endif
00047
00048 #include <Inventor/draggers/SoTranslate2Dragger.h>
00049 #include <Inventor/elements/SoFontNameElement.h>
00050 #include <Inventor/elements/SoFontSizeElement.h>
00051 #include <Inventor/elements/SoCullElement.h>
00052 #include <Inventor/elements/SoModelMatrixElement.h>
00053 #include <Inventor/elements/SoProjectionMatrixElement.h>
00054 #include <Inventor/elements/SoViewingMatrixElement.h>
00055 #include <Inventor/elements/SoViewVolumeElement.h>
00056 #include <Inventor/elements/SoViewportRegionElement.h>
00057 #include <Inventor/elements/SoGLTextureEnabledElement.h>
00058 #include <Inventor/elements/SoGLTexture3EnabledElement.h>
00059
00060 #include "SoTextLabel.h"
00061 #include "SoFCInteractiveElement.h"
00062 #include "BitmapFactory.h"
00063
00064 using namespace Gui;
00065
00092 SO_NODE_SOURCE(SoTextLabel);
00093
00094 void SoTextLabel::initClass()
00095 {
00096 SO_NODE_INIT_CLASS(SoTextLabel, SoText2, "Text2");
00097 }
00098
00099 SoTextLabel::SoTextLabel()
00100 {
00101 SO_NODE_CONSTRUCTOR(SoTextLabel);
00102 SO_NODE_ADD_FIELD(backgroundColor, (SbVec3f(1.0f,1.0f,1.0f)));
00103 SO_NODE_ADD_FIELD(background, (TRUE));
00104 SO_NODE_ADD_FIELD(frameSize, (10.0f));
00105 }
00106
00110 void SoTextLabel::GLRender(SoGLRenderAction *action)
00111 {
00112 if (!this->shouldGLRender(action)) return;
00113
00114
00115 if (!this->background.getValue()) {
00116 inherited::GLRender(action);
00117 return;
00118 }
00119
00120 SoState * state = action->getState();
00121
00122 state->push();
00123 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00124
00125 SbBox3f box;
00126 SbVec3f center;
00127 this->computeBBox(action, box, center);
00128
00129 if (!SoCullElement::cullTest(state, box, TRUE)) {
00130 SoMaterialBundle mb(action);
00131 mb.sendFirst();
00132 const SbMatrix & mat = SoModelMatrixElement::get(state);
00133
00134 const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) *
00135 SoProjectionMatrixElement::get(state));
00136 const SbViewportRegion & vp = SoViewportRegionElement::get(state);
00137 SbVec2s vpsize = vp.getViewportSizePixels();
00138
00139
00140
00141
00142 SbName fontname = SoFontNameElement::get(state);
00143 int lines = this->string.getNum();
00144
00145
00146 SbVec3f nilpoint(0.0f, 0.0f, 0.0f);
00147 projmatrix.multVecMatrix(nilpoint, nilpoint);
00148 nilpoint[0] = (nilpoint[0] + 1.0f) * 0.5f * vpsize[0];
00149 nilpoint[1] = (nilpoint[1] + 1.0f) * 0.5f * vpsize[1];
00150
00151 #if 1
00152
00153
00154
00155
00156
00157
00158
00159 state->push();
00160 SoModelMatrixElement::set(state,this,SbMatrix::identity());
00161 SoViewingMatrixElement::set(state,this,SbMatrix::identity());
00162 SoProjectionMatrixElement::set(state,this,SbMatrix::identity());
00163 SbViewVolume vv;
00164 vv.ortho(-1,1,-1,1,-1,1);
00165 SoViewVolumeElement::set(state,this,vv);
00166
00167 SbBox3f box;
00168 SbVec3f center;
00169 this->computeBBox(action, box, center);
00170 state->pop();
00171
00172 float xmin,ymin,zmin,xmax,ymax,zmax;
00173 box.getBounds(xmin,ymin,zmin,xmax,ymax,zmax);
00174 SbVec3f v0(xmin,ymax,zmax);
00175 SbVec3f v1(xmax,ymax,zmax);
00176 SbVec3f v2(xmax,ymin,zmax);
00177 SbVec3f v3(xmin,ymin,zmax);
00178 vv.projectToScreen(v0,v0);
00179 vv.projectToScreen(v1,v1);
00180 vv.projectToScreen(v2,v2);
00181 vv.projectToScreen(v3,v3);
00182
00183 float width,height;
00184 width = (v1[0]-v0[0])*vpsize[0];
00185 height = (v1[1]-v3[1])*vpsize[1];
00186 switch (this->justification.getValue()) {
00187 case SoText2::RIGHT:
00188 nilpoint[0] -= width;
00189 break;
00190 case SoText2::CENTER:
00191 nilpoint[0] -= 0.5f*width;
00192 break;
00193 default:
00194 break;
00195 }
00196
00197 if (lines > 1) {
00198 nilpoint[1] -= (float(lines-1)/(float)lines*height);
00199 }
00200 #else
00201
00202
00203
00204
00205
00206 QFont font;
00207 QString fn = QString::fromAscii(fontname.getString());
00208 int pos = fn.indexOf(QLatin1Char(':'));
00209 if (pos > -1) {
00210 if (fn.indexOf(QLatin1String("Bold"),pos,Qt::CaseInsensitive) > pos)
00211 font.setBold(true);
00212 if (fn.indexOf(QLatin1String("Italic"),pos,Qt::CaseInsensitive) > pos)
00213 font.setItalic(true);
00214 fn = fn.left(pos);
00215 }
00216 font.setFamily(fn);
00217 font.setPixelSize((int)fontsize);
00218 QFontMetrics fm(font);
00219
00220 float width = 0.0f;
00221 float height = 0.75f*fontsize*lines + (lines-1)*space;
00222 float hh=0;
00223 for (int i = 0; i < lines; i++) {
00224 SbString str = this->string[i];
00225 float w = fm.width(QLatin1String(this->string[i].getString()));
00226 width = std::max<float>(width, w);
00227 hh = fm.height();
00228 }
00229
00230 if (lines > 1) {
00231 nilpoint[1] -= ((lines-1)*fontsize*0.75f+space);
00232 }
00233 #endif
00234
00235 SbVec3f toppoint = nilpoint;
00236 toppoint[0] += width;
00237 toppoint[1] += height;
00238
00239
00240 glMatrixMode(GL_MODELVIEW);
00241 glPushMatrix();
00242 glLoadIdentity();
00243 glMatrixMode(GL_PROJECTION);
00244 glPushMatrix();
00245 glLoadIdentity();
00246 glOrtho(0, vpsize[0], 0, vpsize[1], -1.0f, 1.0f);
00247 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00248
00249 state->push();
00250
00251
00252 SoGLTextureEnabledElement::set(state, this, FALSE);
00253 SoGLTexture3EnabledElement::set(state, this, FALSE);
00254
00255 glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
00256 glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
00257
00258
00259 SbColor color = this->backgroundColor.getValue();
00260 float fs = this->frameSize.getValue();
00261
00262
00263 glColor3f(color[0], color[1], color[2]);
00264 glBegin(GL_QUADS);
00265 glVertex3f(nilpoint[0]-fs,nilpoint[1]-fs,0.0f);
00266 glVertex3f(toppoint[0]+fs,nilpoint[1]-fs,0.0f);
00267 glVertex3f(toppoint[0]+fs,toppoint[1]+fs,0.0f);
00268 glVertex3f(nilpoint[0]-fs,toppoint[1]+fs,0.0f);
00269 glEnd();
00270
00271
00272 glPopClientAttrib();
00273 glPopAttrib();
00274 state->pop();
00275
00276 glPixelStorei(GL_UNPACK_ALIGNMENT,4);
00277
00278 glMatrixMode(GL_PROJECTION);
00279 glPopMatrix();
00280 glMatrixMode(GL_MODELVIEW);
00281 glPopMatrix();
00282 }
00283
00284 state->pop();
00285
00286 inherited::GLRender(action);
00287 }
00288
00289
00290
00291 SO_NODE_SOURCE(SoStringLabel);
00292
00293 void SoStringLabel::initClass()
00294 {
00295 SO_NODE_INIT_CLASS(SoStringLabel, SoNode, "Node");
00296 }
00297
00298 SoStringLabel::SoStringLabel()
00299 {
00300 SO_NODE_CONSTRUCTOR(SoStringLabel);
00301 SO_NODE_ADD_FIELD(string, (""));
00302 SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
00303 SO_NODE_ADD_FIELD(name, ("Helvetica"));
00304 SO_NODE_ADD_FIELD(size, (12));
00305 }
00306
00310 void SoStringLabel::GLRender(SoGLRenderAction *action)
00311 {
00312 QGLWidget* window;
00313 SoState * state = action->getState();
00314 state->push();
00315 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00316 SoGLWidgetElement::get(state, window);
00317 if (!window) {
00318 state->pop();
00319 return;
00320 }
00321
00322
00323 glMatrixMode(GL_PROJECTION);
00324 glPushMatrix();
00325 glLoadIdentity();
00326 glOrtho(-1,1,-1,1,-1,1);
00327 glMatrixMode(GL_MODELVIEW);
00328 glPushMatrix();
00329 glLoadIdentity();
00330 glPushAttrib(GL_ENABLE_BIT);
00331 glDisable(GL_DEPTH_TEST);
00332 glDisable(GL_LIGHTING);
00333 glDisable(GL_TEXTURE_2D);
00334 glEnable(GL_BLEND);
00335
00336 QFont font;
00337 font.setStyleStrategy(QFont::NoAntialias);
00338 font.setFamily(QLatin1String(this->name.getValue()));
00339 font.setPixelSize(this->size.getValue());
00340
00341 glBlendFunc(GL_ONE,GL_SRC_ALPHA);
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 SbColor color = this->textColor.getValue();
00360 glColor4f(color[0], color[1], color[2],1);
00361
00362 const SbMatrix & mat = SoModelMatrixElement::get(state);
00363 const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) *
00364 SoProjectionMatrixElement::get(state));
00365 SbVec3f nil(0.0f, 0.0f, 0.0f);
00366 projmatrix.multVecMatrix(nil, nil);
00367 QStringList list;
00368 for (int i=0; i<this->string.getNum(); i++)
00369 list << QLatin1String(this->string[i].getString());
00370 window->renderText(nil[0],nil[1],nil[2],list.join(QLatin1String("\n")),font);
00371
00372
00373 glPopAttrib();
00374 glPopMatrix();
00375 glMatrixMode(GL_PROJECTION);
00376 glPopMatrix();
00377 glMatrixMode(GL_MODELVIEW);
00378
00379 state->pop();
00380 }
00381
00382
00383
00384 SO_NODE_SOURCE(SoFrameLabel);
00385
00386 void SoFrameLabel::initClass()
00387 {
00388 SO_NODE_INIT_CLASS(SoFrameLabel, SoImage, "Image");
00389 }
00390
00391 SoFrameLabel::SoFrameLabel()
00392 {
00393 SO_NODE_CONSTRUCTOR(SoFrameLabel);
00394 SO_NODE_ADD_FIELD(string, (""));
00395 SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
00396 SO_NODE_ADD_FIELD(backgroundColor, (SbVec3f(0.0f,0.333f,1.0f)));
00397 SO_NODE_ADD_FIELD(justification, (LEFT));
00398 SO_NODE_ADD_FIELD(name, ("Helvetica"));
00399 SO_NODE_ADD_FIELD(size, (12));
00400 SO_NODE_ADD_FIELD(frame, (TRUE));
00401
00402 }
00403
00404 void SoFrameLabel::notify(SoNotList * list)
00405 {
00406 SoField *f = list->getLastField();
00407 if (f == &this->string ||
00408 f == &this->textColor ||
00409 f == &this->backgroundColor ||
00410 f == &this->justification ||
00411 f == &this->name ||
00412 f == &this->size ||
00413 f == &this->frame) {
00414 drawImage();
00415 }
00416 inherited::notify(list);
00417 }
00418
00419 void SoFrameLabel::drawImage()
00420 {
00421 const SbString* s = string.getValues(0);
00422 int num = string.getNum();
00423 if (num == 0) {
00424 this->image = SoSFImage();
00425 return;
00426 }
00427
00428 QFont font(QString::fromAscii(name.getValue()), size.getValue());
00429 QFontMetrics fm(font);
00430 int w = 0;
00431 int h = fm.height() * num;
00432 const SbColor& b = backgroundColor.getValue();
00433 QColor brush;
00434 brush.setRgbF(b[0],b[1],b[2]);
00435 const SbColor& t = textColor.getValue();
00436 QColor front;
00437 front.setRgbF(t[0],t[1],t[2]);
00438
00439 QStringList lines;
00440 for (int i=0; i<num; i++) {
00441 QString line = QString::fromUtf8(s[i].getString());
00442 w = std::max<int>(w, fm.width(line));
00443 lines << line;
00444 }
00445
00446 QImage image(w+10,h+10,QImage::Format_ARGB32_Premultiplied);
00447 image.fill(0x00000000);
00448 QPainter painter(&image);
00449 painter.setRenderHint(QPainter::Antialiasing);
00450
00451 SbBool drawFrame = frame.getValue();
00452 if (drawFrame) {
00453 painter.setPen(QPen(QColor(0,0,127), 2, Qt::SolidLine, Qt::RoundCap,
00454 Qt::RoundJoin));
00455 painter.setBrush(QBrush(brush, Qt::SolidPattern));
00456 QRectF rectangle(0.0, 0.0, w+10, h+10);
00457 painter.drawRoundedRect(rectangle, 5, 5);
00458 }
00459
00460 painter.setPen(front);
00461
00462 Qt::Alignment align = Qt::AlignVCenter;
00463 if (justification.getValue() == 0)
00464 align = Qt::AlignVCenter | Qt::AlignLeft;
00465 else if (justification.getValue() == 1)
00466 align = Qt::AlignVCenter | Qt::AlignRight;
00467 else
00468 align = Qt::AlignVCenter | Qt::AlignHCenter;
00469 QString text = lines.join(QLatin1String("\n"));
00470 painter.setFont(font);
00471 painter.drawText(5,5,w,h,align,text);
00472 painter.end();
00473
00474 SoSFImage sfimage;
00475 Gui::BitmapFactory().convert(image, sfimage);
00476 this->image = sfimage;
00477 }
00478
00482 void SoFrameLabel::GLRender(SoGLRenderAction *action)
00483 {
00484 inherited::GLRender(action);
00485 #if 0
00486 QGLWidget* window;
00487 SoState * state = action->getState();
00488 state->push();
00489 SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
00490 SoGLWidgetElement::get(state, window);
00491 if (!window) {
00492 state->pop();
00493 return;
00494 }
00495
00496
00497 glMatrixMode(GL_PROJECTION);
00498 glPushMatrix();
00499 glLoadIdentity();
00500 glOrtho(-1,1,-1,1,-1,1);
00501 glMatrixMode(GL_MODELVIEW);
00502 glPushMatrix();
00503 glLoadIdentity();
00504 glPushAttrib(GL_ENABLE_BIT);
00505 glDisable(GL_DEPTH_TEST);
00506 glDisable(GL_LIGHTING);
00507 glDisable(GL_TEXTURE_2D);
00508 glEnable(GL_BLEND);
00509
00510 QFont font;
00511 font.setStyleStrategy(QFont::NoAntialias);
00512 font.setFamily(QLatin1String(this->name.getValue()));
00513 font.setPixelSize(this->size.getValue());
00514
00515 glBlendFunc(GL_ONE,GL_SRC_ALPHA);
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 SbColor color = this->textColor.getValue();
00534 glColor4f(color[0], color[1], color[2],1);
00535
00536 const SbMatrix & mat = SoModelMatrixElement::get(state);
00537 const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) *
00538 SoProjectionMatrixElement::get(state));
00539 SbVec3f nil(0.0f, 0.0f, 0.0f);
00540 projmatrix.multVecMatrix(nil, nil);
00541 QStringList list;
00542 for (int i=0; i<this->string.getNum(); i++)
00543 list << QLatin1String(this->string[i].getString());
00544 window->renderText(nil[0],nil[1],nil[2],list.join(QLatin1String("\n")),font);
00545
00546
00547 glPopAttrib();
00548 glPopMatrix();
00549 glMatrixMode(GL_PROJECTION);
00550 glPopMatrix();
00551 glMatrixMode(GL_MODELVIEW);
00552
00553 state->pop();
00554 #endif
00555 }
00556
00557
00558
00559 SO_NODE_SOURCE(TranslateManip);
00560
00561 void
00562 TranslateManip::initClass()
00563 {
00564 SO_NODE_INIT_CLASS(TranslateManip, SoTransformManip,
00565 "TransformManip");
00566 }
00567
00568 TranslateManip::TranslateManip()
00569 {
00570 SO_NODE_CONSTRUCTOR(TranslateManip);
00571
00572 SoTranslate2Dragger *myDrag = new SoTranslate2Dragger;
00573 setDragger(myDrag);
00574 }
00575
00576 TranslateManip::~TranslateManip()
00577 {
00578 }