GLICT/container.cpp

Go to the documentation of this file.
00001 /*
00002         GLICT - Graphics Library Interface Creation Toolkit
00003         Copyright (C) 2006-2007 OBJECT Networks
00004 
00005         This library is free software; you can redistribute it and/or
00006         modify it under the terms of the GNU Library General Public
00007         License as published by the Free Software Foundation; either
00008         version 2 of the License, or (at your option) any later version.
00009 
00010         This library is distributed in the hope that it will be useful,
00011         but WITHOUT ANY WARRANTY; without even the implied warranty of
00012         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013         Library General Public License for more details.
00014 
00015         You should have received a copy of the GNU Library General Public
00016         License along with this library; if not, write to the Free
00017         Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 
00021 
00029 #include <stdlib.h>
00030 #ifdef WIN32
00031     #include <windows.h>
00032 #endif
00033 #include <GL/gl.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <math.h>
00037 //#include <time.h>
00038 #include "container.h"
00039 #include "types.h"
00040 #include "globals.h"
00041 
00042 
00043 #include <stdlib.h>
00044 
00045 #ifndef min
00046 #define min(a,b) (a<b ? a : b)
00047 #define max(a,b) (a>b ? a : b)
00048 #endif
00049 
00053 glictContainer::glictContainer() {
00054         this->height = 32;
00055         this->width = 32;
00056         this->x = 0;
00057         this->y = 0;
00058         strcpy(this->objtype,"Container");
00059 
00060         this->parent = NULL;
00061 
00062         this->OnClick = NULL;
00063         this->OnPaint = NULL;
00064         this->OnMouseDown = NULL;
00065         this->OnMouseUp = NULL;
00066 
00067         this->guid = rand();
00068 
00069         this->ResetTransformations();
00070 
00071         this->SetCaption("");
00072 
00073         this->focusable = false;
00074 
00075         this->SetVisible(true);
00076         this->SetEnabled(true);
00077 
00078         this->containeroffsetx = 0;
00079         this->containeroffsety = 0;
00080 
00081         this->SetRect(this->x, this->y, this->x + this->width, this->y + this->height);
00082         this->SetClip(this->left, this->top, this->right, this->bottom);
00083 
00084         virtualsize.x = 0;
00085         virtualsize.y = 0;
00086 
00087         virtualpos.x = 0;
00088         virtualpos.y = 0;
00089 
00090         fontname = "system";
00091         fontsize = 10;
00092 
00093         previous = NULL;
00094         next = NULL;
00095 
00096         //printf("Container created.\n");
00097 
00098 }
00099 
00104 glictContainer::~glictContainer() {
00105         if (this == glictGlobals.topFocused) {
00106                 glictGlobals.topFocused = NULL;
00107         }
00108 }
00109 
00113 void glictContainer::ResetTransformations() {
00114         int i=0;
00115         ModelviewMatrix[i++] = 1; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0;
00116         ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 1; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0;
00117         ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 1; ModelviewMatrix[i++] = 0;
00118         ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 1;
00119 }
00129 void glictContainer::AddObject(glictContainer* obj) {
00130         obj->parent = this;
00131         obj->ResetTransformations();
00132         this->objects.insert(this->objects.end(), obj);
00133 
00134         //this->SetPos(x,y); // just force the clipping code to execute
00135         this->RecursiveBoundaryFix();
00136     //if (parent) parent->SetPos(parent->x, parent->y);
00137 }
00148 void glictContainer::RemoveObject(glictContainer* object) {
00149         /*vector<glictContainer*>::iterator it;
00150 
00151         for (it=objects.begin(); it!=objects.end(); it++) {
00152                 if ((*it)==object) {
00153                         //delete *it;
00154                         objects.erase(it);
00155                         return;
00156                 }
00157         }*/
00158 
00159         delayedremove.insert(delayedremove.end(), object);
00160 }
00161 
00165 void glictContainer::DelayedRemove() {
00166         if (delayedremove.size()) {
00167                 for (vector<glictContainer*>::iterator it = delayedremove.begin(); delayedremove.size(); ) {
00168                         for (std::vector<glictContainer*>::iterator it2 = objects.begin(); it2 != objects.end(); ) {
00169                                 if ((*it) == (*it2)) {
00170                                         objects.erase(it2);
00171                                         it2 = objects.begin();
00172                                 }
00173                                 else {
00174                                         it2++;
00175                                 }
00176                         }
00177                         delayedremove.erase(it);
00178 
00179                 }
00180         }
00181 }
00182 
00190 void glictContainer::SetHeight(float h) {
00191         this->height = h;
00192     this->RecursiveBoundaryFix();
00193 }
00194 
00202 void glictContainer::SetWidth(float w) {
00203         this->width = w;
00204         this->RecursiveBoundaryFix();
00205 }
00206 
00215 void glictContainer::SetPos(float x, float y) {
00216 
00217         //printf("Postavka pozicije %s (%s) %s na %d %d\n", objtype, (parent ? parent->objtype : "NULL"), this->caption.c_str(), x, y);
00218         //printf("This->x %d This->y %d\n", this->x, this->y);
00219 
00220     this->FixContainerOffsets(); // in case the skin got just turned on, we'll have to fix the container offsets
00221 
00222     if (!parent) {
00223             this->SetRect(x, y, x+width, y+height);
00224 
00225         this->x = x;
00226         this->y = y;
00227     } else {
00228         this->SetRect(
00229             parent->left + x + parent->containeroffsetx - parent->virtualpos.x,
00230             parent->top + y + parent->containeroffsety  - parent->virtualpos.y,
00231             parent->left + x + width+ parent->containeroffsetx -  parent->virtualpos.x + containeroffsetx*2,
00232             parent->top + y + height+ parent->containeroffsety -  parent->virtualpos.y + containeroffsety*2 // FIXME containeroffsety*2 should be replaced by containeroffsety + bottomheight
00233         );
00234 
00235 
00236         this->x = x;
00237         this->y = y;
00238     }
00239 
00240 
00241 
00242         glictSize size;
00243         for (std::vector<glictContainer*>::iterator it=objects.begin(); it!=objects.end(); it++) {
00244 
00245                 (*it)->GetPos(&x, &y);
00246 #if 1
00247                 (*it)->SetPos(x,y);
00248 #else
00249 // FIXME: this way, we have less ops but it's not recursive properly and does not fix the boundaries as it ought to.
00250 //  check if we can still keep this way of doing things instead of sicko "setpos" recursively
00251                 (*it)->GetSize(&size);
00252 
00253                 (*it)->SetRect(this->left + x, this->top, this->left + x + size.w, this->top + y + size.h );
00254 #endif
00255         }
00256 }
00257 
00265 void glictContainer::SetPos(glictPos pos) {
00266         this->SetPos(pos.x,pos.y);
00267 }
00268 
00280 void glictContainer::GetPos(float* x, float* y) {
00281         *x = this->x;
00282         *y = this->y;
00283 }
00284 
00292 void glictContainer::GetPos(glictPos* pos) {
00293         pos->x = this->x;
00294         pos->y = this->y;
00295 }
00296 /* TODO (Khaos#2#): GetSize(w,h); */
00297 
00305 void glictContainer::GetSize(glictSize* size) {
00306         size->w = this->width;
00307         size->h = this->height;
00308 }
00309 
00316 float glictContainer::GetWidth() {
00317     return width;
00318 }
00319 
00326 float glictContainer::GetHeight() {
00327     return height;
00328 }
00329 
00348 void glictContainer::SetRect(float left, float top, float right, float bottom) {
00349         //printf("%s s parentom %s postaje %d %d %d %d\n", this->objtype, (parent ? parent->objtype : "NULL"), left, right, top, bottom);
00350         this->left = left;
00351         this->right = right;
00352         this->top = top;
00353         this->bottom = bottom;
00354 
00355 
00356     //printf("Sada, %s s parentom %s sebe postavlja na clip %d %d %d %d\n", this->objtype, (parent ? parent->objtype : "NULL"), left, right, top, bottom);
00357     this->SetClip(
00358         max(left, (parent ? parent->clipleft : 0)),
00359         max(top, (parent ? parent->cliptop:0)),
00360         min(right, (parent ? parent->clipright: right)),
00361         min(bottom, (parent ? parent->clipbottom:bottom)) );
00362 
00363 }
00364 
00383 void glictContainer::SetClip(float left, float top, float right, float bottom) {
00384 
00385         this->clipleft = left;
00386         this->clipright = right ;
00387         this->cliptop = top ;
00388         this->clipbottom = bottom ;
00389 
00390         //printf("%s s parentom %s clippa kao %d %d %d %d\n", this->objtype, (parent ? parent->objtype : "NULL"), clipleft, clipright, cliptop, clipbottom);
00391 
00392 /*      glictSize size;
00393         int x, y;
00394         if (objects.size()) for (vector<glictContainer*>::iterator it=objects.begin(); it!=objects.end(); it++) {
00395                 (*it)->GetPos(&x, &y);
00396                 (*it)->GetSize(&size);
00397 
00398 
00399                 (*it)->SetRect(this->left + x, this->top + y, this->left + x + size.w, this->top + y + size.h);
00400                 (*it)->SetClip(max(this->left + (*it)->x, this->clipleft), max(this->top + (*it)->y, this->cliptop), min(this->left + (*it)->x + size.w, this->clipright), min(this->top + (*it)->y + size.h, this->clipbottom));
00401         }
00402 */
00403 
00404 }
00405 
00427 void glictContainer::SetScissor() {
00428         //printf("SCISSOR SET\n");
00429 #ifdef NO_GL
00430         return;
00431 #else
00432         if (glictGlobals.clippingMode==GLICT_SCISSORTEST) {
00433                 //printf("Scissor testing %s (%s), %d %d %d %d\n", this->objtype, (this->parent ? this->parent->objtype : "NULL"), clipleft, clipright, cliptop, clipbottom);
00434                 //glMatrixMode(GL_MODELVIEW);
00435                 //glPushMatrix();
00436                 //glLoadIdentity();
00437                 glScissor(
00438                         (int)this->clipleft,
00439                         (int)glictGlobals.h - (int)this->clipbottom,
00440                         (int)this->clipright - (int)this->clipleft,
00441                         (int)this->clipbottom - (int)this->cliptop
00442                 );
00443                 //glPopMatrix();
00444 
00445         } else
00446         if (glictGlobals.clippingMode==GLICT_STENCILTEST) {
00447                 //glLoadName(this->guid);
00448                 //printf("Stencil testing %s (%s); %d %d %d %d\n", this->objtype, (this->parent ? this->parent->objtype : "NULL"), clipleft, clipright, cliptop, clipbottom);
00449                 glClear(GL_STENCIL_BUFFER_BIT);
00450                 //glDisable(GL_SCISSOR_TEST);
00451                 //glEnable(GL_STENCIL_TEST); // was Disable
00452                 glStencilFunc(GL_ALWAYS, 1, 1);
00453                 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
00454                 glColorMask(0,0,0,0);
00455                 glDepthMask(0);
00456 
00457                 //glColor3b(rand(), rand(), rand());
00458                 glMatrixMode(GL_MODELVIEW);
00459                 glPushMatrix();
00460                         //glLoadIdentity();
00461                         glLoadMatrixf(ModelviewMatrix);
00462                         glictGlobals.PaintRect(this->clipleft, this->clipright, this->cliptop, this->clipbottom);
00463                 glPopMatrix();
00464 
00465                 //glEnable(GL_STENCIL_TEST);
00466                 glColorMask(1,1,1,1);
00467                 glDepthMask(1);
00468 
00469                 glStencilFunc(GL_EQUAL, 1, 1);
00470                 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
00471 
00472 
00473         }// else printf("CLIP TEST IS OFF!!\n");
00474 #endif
00475 }
00476 
00493 void glictContainer::Paint() {
00494         if (!GetVisible()) return;
00495         this->SetScissor();
00496 
00497         this->CPaint();
00498 
00499 }
00500 
00520 void glictContainer::CPaint() {
00521 
00522         //printf("Rendering %s (child of %s)\n", objtype, parent ? parent->objtype : "NULL");
00523 
00524         DelayedRemove();
00525 
00526 #if 0
00527 // below is debug code ...
00528         glMatrixMode(GL_MODELVIEW);
00529 
00530         glPushMatrix();
00531         glLoadIdentity();
00532 
00533 
00534         if (glictGlobals.clippingMode==GLICT_SCISSORTEST) glDisable(GL_SCISSOR_TEST);
00535         if (glictGlobals.clippingMode==GLICT_STENCILTEST) glDisable(GL_STENCIL_TEST);
00536 
00537 
00538     glBegin(GL_LINES);
00539                 glColor3f(1.0,0.0,0.0);
00540                 glVertex2f(this->clipleft,this->clipbottom);
00541                 glVertex2f(this->clipleft,this->cliptop);
00542 
00543                 glColor3f(0.0,1.0,0.0);
00544                 glVertex2f(this->clipright,this->clipbottom);
00545                 glVertex2f(this->clipleft,this->clipbottom);
00546 
00547 
00548                 glColor3f(0.0,0.0,1.0);
00549                 glVertex2f(this->clipright,this->cliptop);
00550                 glVertex2f(this->clipright,this->clipbottom);
00551 
00552 
00553                 glColor3f(1.0,1.0,0.0);
00554                 glVertex2f(this->clipleft,this->cliptop);
00555                 glVertex2f(this->clipright,this->cliptop);
00556 
00557         glEnd();
00558 
00559         if (glictGlobals.clippingMode==GLICT_SCISSORTEST) glEnable(GL_SCISSOR_TEST);
00560         if (glictGlobals.clippingMode==GLICT_STENCILTEST) glEnable(GL_STENCIL_TEST);
00561         glPopMatrix();
00562 #endif
00563 
00564         if (objects.size()) {
00565 
00566         glictGlobals.Translatef(this->x + containeroffsetx - virtualpos.x, this->y + containeroffsety - virtualpos.y,0.0);
00567 
00568         std::vector<glictContainer*>::iterator it;
00569         for (it=objects.begin(); it!=objects.end(); it++) {
00570 
00571                 if (!glictGlobals.drawPartialOut) {
00572                                 if ((*it)->GetX()+(*it)->GetWidth() > virtualpos.x + GetWidth())
00573                                         continue;
00574                         if ((*it)->GetY()+(*it)->GetHeight() > virtualpos.y + GetHeight())
00575                                         continue;
00576                                 if ((*it)->GetX() < virtualpos.x )
00577                                         continue;
00578                                 if ((*it)->GetY() < virtualpos.y )
00579                                         continue;
00580                 }
00581 
00582             (*it)->SetScissor();
00583             (*it)->Paint();
00584         }
00585         glictGlobals.Translatef(-this->x - containeroffsetx + virtualpos.x, -this->y - containeroffsety + virtualpos.y,0.0);
00586 
00587         }
00588 }
00589 
00619 bool glictContainer::DefaultCastEvent(glictEvents evt, void* wparam, long lparam, void* returnvalue) {
00620         //printf("Default event of type %s passing through %s (%s) with %d children\n", EvtTypeDescriptor(evt), objtype, parent ? parent->objtype : "NULL", this->objects.size());
00621         switch (evt) {
00622                 case GLICT_KEYPRESS:
00623                         // as default behaviour is that widget doesnt know what to do with
00624                         // a key, it'll pass exec to the top focused item, whatever it
00625                         // might be
00626                         if (glictGlobals.topFocused)
00627                                 if (this!=glictGlobals.topFocused)
00628                                         return glictGlobals.topFocused->CastEvent(evt, wparam, lparam, returnvalue);
00629                         // if it cant find top focused item, or that it is actually the
00630                         // focused item, then it will report that it
00631                         // doesnt know how to proc the event
00632                         return false;
00633                 case GLICT_KEYDOWN:
00634 
00635                         return false;
00636                 case GLICT_KEYUP:
00637 
00638                         return false;
00639 
00640                 case GLICT_MOUSEUP:
00641                 case GLICT_MOUSEDOWN:
00642                 case GLICT_MOUSECLICK:
00643                         {
00644                         std::vector<glictContainer*>::reverse_iterator it;
00645                         //vector<glictContainer*>::iterator it;
00646 
00647 
00648                         if  (((glictPos*)wparam)->x > this->clipleft &&
00649                  ((glictPos*)wparam)->x < this->clipright &&
00650                  ((glictPos*)wparam)->y > this->cliptop &&
00651                  ((glictPos*)wparam)->y < this->clipbottom) {
00652                                         if (objects.size()) {
00653                                                 for (it=objects.rbegin(); it != objects.rend(); it++) {
00654                                                 //for (it=objects.begin(); it!=objects.end(); it++) {
00655                                                         if (it != objects.rend() && *it ) {
00656 
00657                                                                 //printf("Testing %s (%s)\n", (*it)->objtype, this->objtype );
00658 
00659 
00660                                                                 if ((*it)->CastEvent(evt, wparam, lparam, returnvalue)) {
00661                                                                         //printf("%s (%s) returned true\n", (*it)->objtype, this->objtype );
00662                                                                         return true;
00663                                                                 }
00664 
00665 
00666                                                         }
00667                                                 }
00668                                         }
00669 
00670                         }
00671 
00672 
00673                         //printf("Passing on to specific mouseevent processing in %s (%s).\n", objtype, parent ? parent->objtype : "NULL");
00674                         if (evt == GLICT_MOUSEDOWN) {
00675                                 //printf("Mouse down\n");
00676                                 glictGlobals.lastMousePos.x = ((glictPos*)wparam)->x ; // remembers x and y when pressing the mouse down
00677                                 glictGlobals.lastMousePos.y = ((glictPos*)wparam)->y ;
00678                                 if (focusable) {
00679                                         if (((glictPos*)wparam)->x > this->clipleft &&
00680                                          ((glictPos*)wparam)->x < this->clipright &&
00681                                          ((glictPos*)wparam)->y > this->cliptop &&
00682                                          ((glictPos*)wparam)->y < this->clipbottom ) {
00683 
00684 
00685                                                 if (this->OnMouseDown) {
00686 
00687                             glictPos relpos;
00688                             relpos.x = ((glictPos*)wparam)->x - this->left - this->containeroffsetx + this->virtualpos.x;
00689                             relpos.y = ((glictPos*)wparam)->y - this->top - this->containeroffsety + this->virtualpos.y;
00690                             this->OnMouseDown(&relpos, this);
00691                         }
00692 
00693                                                 this->Focus(NULL);
00694                                                 return true;
00695                                          }
00696                                 }
00697                         } else if (evt == GLICT_MOUSEUP) {
00698                                 //printf("Mouse up on %s\n", objtype);
00699 
00700 
00701                                 if (fabs (((glictPos*)wparam)->x - glictGlobals.lastMousePos.x) < 3 && // upon release verifies the location of mouse, and if nearby then it's a click - cast a click event
00702                                         fabs (((glictPos*)wparam)->y - glictGlobals.lastMousePos.y) < 3 ) { // if up to 2 pixels diff
00703                                         //printf("Considering it a click\n");
00704                                         //if (!parent) {
00705                                                 //printf("Casting click event.\n");
00706 
00707                                                 return this->CastEvent(GLICT_MOUSECLICK, wparam, lparam, returnvalue);
00708                                         //} else {
00709                                                 //Not toplevel! Has a parent. Thus ignoring a click, letting toplevel parse properly.
00710                                         //}
00711 
00712                                 } else {
00713                                         //Considering it dragging. Ignoring it!
00714                                 }
00715 
00716                 if (((glictPos*)wparam)->x > this->clipleft &&
00717                  ((glictPos*)wparam)->x < this->clipright &&
00718                  ((glictPos*)wparam)->y > this->cliptop &&
00719                  ((glictPos*)wparam)->y < this->clipbottom ) {
00720 
00721                     if (this->OnMouseUp) {
00722                         glictPos relpos;
00723                         relpos.x = ((glictPos*)wparam)->x - this->left - this->containeroffsetx + this->virtualpos.x;
00724                         relpos.y = ((glictPos*)wparam)->y - this->top - this->containeroffsety + this->virtualpos.y;
00725                         this->OnMouseUp(&relpos, this);
00726                     }
00727                 }
00728 
00729 
00730 
00731                         } else { // not mousedown , not mouseup? mouseclick!
00732 
00733 
00734                                 if (((glictPos*)wparam)->x > this->clipleft &&
00735                                         ((glictPos*)wparam)->x < this->clipright &&
00736                                         ((glictPos*)wparam)->y > this->cliptop &&
00737                                         ((glictPos*)wparam)->y < this->clipbottom ) {
00738                                         if (this->OnClick) {
00739                                                 //printf("Click on %s.\n", objtype);
00740                                                 glictPos relpos;
00741                                                 relpos.x = ((glictPos*)wparam)->x - this->left - this->containeroffsetx + this->virtualpos.x;
00742                                                 relpos.y = ((glictPos*)wparam)->y - this->top - this->containeroffsety + this->virtualpos.y;
00743                                                 this->OnClick(&relpos, this);
00744                                                 return true;
00745                                         }
00746                                         // if it happened within our boundaries, let it be as if we proc'ed it!
00747                                         // of course, only if we're not a container
00748 
00749                                         if (strcmp(objtype, "Container")) {// FIXME this is ugly lowperformance check, we should make it a bool or sth
00750                         //printf("Announcing click in %s\n", objtype);
00751                                             return true;
00752                                         }
00753                                 }
00754                                 // it didnt? then lets ignore it
00755 
00756                                 return false;
00757 
00758                         }
00759                         return false; // came here? defaultcastevent caught nothing
00760                         }
00761 
00762 
00763                 default:
00764                         printf("Unhandled event\n");
00765                         return false; // unprocessed, unknown event
00766         }
00767 
00768         // should never come here, but just in case:
00769         return false;
00770 }
00771 
00787 bool glictContainer::CastEvent(glictEvents evt, void* wparam, long lparam) {
00788    return this->CastEvent(evt, wparam, lparam, NULL);
00789 }
00790 
00820 bool glictContainer::CastEvent(glictEvents evt, void* wparam, long lparam, void* returnvalue) {
00821         if (!GetVisible() || !GetEnabled()) 
00822                 return false;
00823         //printf("Event of type %s passing through %s (%s)\n", EvtTypeDescriptor(evt), objtype, parent ? parent->objtype : "NULL");
00824         switch (evt) {
00825                 default:
00826                         return DefaultCastEvent(evt, wparam, lparam, returnvalue); // use default processing for all events
00827                 case GLICT_MOUSECLICK:
00828                         return DefaultCastEvent(evt, wparam, lparam, returnvalue); // we never catch a mouse click in glictContainer... but some child might do so
00829                         break;
00830         }
00831 }
00832 
00836 void glictContainer::SetOnClick(void(*f)(glictPos* relmousepos, glictContainer* callerclass)) {
00837         this->OnClick = f;
00838 }
00839 
00843 void glictContainer::SetOnMouseDown(void(*f)(glictPos* relmousepos, glictContainer* callerclass)) {
00844         this->OnMouseDown = f;
00845 }
00849 void glictContainer::SetOnMouseUp(void(*f)(glictPos* relmousepos, glictContainer* callerclass)) {
00850         this->OnMouseUp = f;
00851 }
00852 
00858 void glictContainer::SetOnPaint(void(*f)(glictRect* real, glictRect* clipped, glictContainer* callerclass)) {
00859         this->OnPaint = f;
00860 }
00861 
00873 void glictContainer::RememberTransformations() {
00874 
00875         std::vector<glictContainer*>::iterator it;
00876 #ifdef NO_GL
00877         int i=0;
00878         ModelviewMatrix[i++] = 1; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0;
00879         ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 1; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0;
00880         ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 1; ModelviewMatrix[i++] = 0;
00881         ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 0; ModelviewMatrix[i++] = 1;
00882 #else
00883         glGetFloatv(GL_MODELVIEW_MATRIX, ModelviewMatrix);
00884 #endif
00885         //printf("Remembering %s's modelview matrix (child of %s)\n", objtype, parent ? parent->objtype : "NULL");
00886 
00887         for (it=objects.begin(); it!=objects.end(); it++) {
00888                 (*it)->RememberTransformations();
00889         }
00890 }
00891 
00896 void glictContainer::ReportDebug() {
00897 
00898         printf("--%s--\n", objtype);
00899         printf("Height: %d\n", height);
00900         printf("Width: %d\n", width);
00901         printf("Pos: %d %d\n", x, y);
00902         printf("Rect TBLR: %d %d %d %d\n", top, bottom, left, right);
00903         printf("Clip TBLR: %d %d %d %d\n", cliptop, clipbottom, clipleft, clipright);
00904         printf("GUID: %d\n", guid);
00905         std::vector<glictContainer*>::iterator it;
00906         for (it=objects.begin(); it!=objects.end(); it++) {
00907                 (*it)->ReportDebug();
00908         }
00909 }
00910 
00931 void glictContainer::TransformScreenCoords(glictPos *pos) {
00932 
00933 
00934         int i,j,k;
00935 
00936         /*printf("original\n");
00937         for (i=0;i<4;i++) {
00938                 for (j=0;j<4;j++)
00939                         printf("%.02f ", ModelviewMatrix[i*4 + j]);
00940                 printf("\n");
00941         }
00942         //system("pause");
00943 */
00944 
00945 /*
00946 
00947         ModelviewMatrix[0] = 1;
00948         ModelviewMatrix[1] = 2;
00949         ModelviewMatrix[2] = 3;
00950         ModelviewMatrix[3] = 4;
00951         ModelviewMatrix[4] = 5;
00952         ModelviewMatrix[5] = 6;
00953         ModelviewMatrix[6] = 7;
00954         ModelviewMatrix[7] = 8;
00955         ModelviewMatrix[8] = 9;
00956         ModelviewMatrix[9] = 10;
00957         ModelviewMatrix[10] = 11;
00958         ModelviewMatrix[11] = 12;
00959         ModelviewMatrix[12] = 13;
00960         ModelviewMatrix[13] = 14;
00961         ModelviewMatrix[14] = 15;
00962         ModelviewMatrix[15] = 16;
00963 */
00964         // copy matrix for inversion; copy matrix in left part, and fill rest with identity matrix
00965         double m[32];
00966         m[0] = this->ModelviewMatrix[0];
00967         m[1] = this->ModelviewMatrix[1];
00968         m[2] = this->ModelviewMatrix[2];
00969         m[3] = this->ModelviewMatrix[3];
00970         m[4] = 1;
00971         m[5] = 0;
00972         m[6] = 0;
00973         m[7] = 0;
00974 
00975         m[8] = this->ModelviewMatrix[4];
00976         m[9] = this->ModelviewMatrix[5];
00977         m[10] = this->ModelviewMatrix[6];
00978         m[11] = this->ModelviewMatrix[7];
00979         m[12] = 0;
00980         m[13] = 1;
00981         m[14] = 0;
00982         m[15] = 0;
00983 
00984         m[16] = this->ModelviewMatrix[8];
00985         m[17] = this->ModelviewMatrix[9];
00986         m[18] = this->ModelviewMatrix[10];
00987         m[19] = this->ModelviewMatrix[11];
00988         m[20] = 0;
00989         m[21] = 0;
00990         m[22] = 1;
00991         m[23] = 0;
00992 
00993         m[24] = this->ModelviewMatrix[12];
00994         m[25] = this->ModelviewMatrix[13];
00995         m[26] = this->ModelviewMatrix[14];
00996         m[27] = this->ModelviewMatrix[15];
00997         m[28] = 0;
00998         m[29] = 0;
00999         m[30] = 0;
01000         m[31] = 1;
01001 
01002 
01003 
01004         int ti,tj;
01005 
01006         // invert matrix
01007         float tmprowel, tmprowel2; // temp row's element
01008         for (i=0;i<4;i++) { // go through each row
01009                 for (j=0;j<8;j++) {
01010                         m[i*8 + j] /= m[i * 8 + i]; // divide the row by [row][row], that's where we want a 1
01011                 }
01012 
01013                 // go through all other rows except the one we're currently in
01014                 for (j=0;j<4;j++) if (j!=i) {
01015                         tmprowel2 = m[j*8+i];
01016                         for (k=0;k<8;k++) {
01017                                 // multiply the row's elements by [row][row2]
01018                                 tmprowel = m[i*8 + k] * tmprowel2 * -1;
01019                                 // sum resulting row with row2
01020                                 m[j*8 + k] += tmprowel;
01021                         }
01022                 }
01023         }
01024 
01025 
01026         // right part is the resulting matrix
01027         double result[16];
01028         result[0] = m[4];
01029         result[1] = m[5];
01030         result[2] = m[6];
01031         result[3] = m[7];
01032         result[4] = m[12];
01033         result[5] = m[13];
01034         result[6] = m[14];
01035         result[7] = m[15];
01036         result[8] = m[20];
01037         result[9] = m[21];
01038         result[10] = m[22];
01039         result[11] = m[23];
01040         result[12] = m[28];
01041         result[13] = m[29];
01042         result[14] = m[30];
01043         result[15] = m[31];
01044 
01045 
01046 
01047 
01048 
01049         /*printf("inverse\n");
01050         for (i=0;i<4;i++) {
01051                 for (j=0;j<4;j++)
01052                         printf("%.02f ", result[i*4 + j]);
01053                 printf("\n");
01054         }
01055         //system("pause");
01056 */
01057 
01058 
01059         // multiply matrix by coordinates
01060         pos->x = (int)((double)(pos->x) * result[0 * 4 + 0]
01061                         + (double)(pos->y) * result[1 * 4 + 0]
01062                         + (double)(0     ) * result[2 * 4 + 0]
01063                         + (double)(1     ) * result[3 * 4 + 0]);
01064         pos->y = (int)((double)(pos->x) * result[0 * 4 + 1]
01065                         + (double)(pos->y) * result[1 * 4 + 1]
01066                         + (double)(0     ) * result[2 * 4 + 1]
01067                         + (double)(1     ) * result[3 * 4 + 1]);
01068 
01069 }
01070 
01077 void glictContainer::SetCaption(const std::string caption) {
01078         this->caption = caption;
01079 }
01086 std::string glictContainer::GetCaption() {
01087         return caption;
01088 }
01089 
01093 glictContainer* glictContainer::GetParent() {
01094         return parent;
01095 }
01096 
01107 void glictContainer::Focus(glictContainer* callerchild) {
01108     //printf("FOCUSING ON %s\n", this->objtype);
01109         if (callerchild && callerchild->focusable && objects.size()) {
01110                 std::vector<glictContainer*>::iterator it;
01111                 bool heredone=false;
01112                 for (it=objects.begin(); it!=objects.end(); it++) {
01113                         if ((*it)==callerchild) {
01114                                 objects.erase(it);
01115                                 heredone=true;
01116                                 break;
01117                         }
01118                 }
01119                 if (heredone)
01120                         objects.insert(objects.end(), callerchild);
01121         }
01122 
01123 
01124         if (parent) {
01125                 parent->Focus(this);
01126         } else { // we're on top level
01127         }
01128 
01129         //if (!callerchild) printf("Focused on %s\n", this->objtype);
01130         glictGlobals.topFocused = this;
01131 }
01132 
01139 void glictContainer::SetVisible(bool vsbl) {
01140         this->visible = vsbl;
01141 }
01142 
01149 bool glictContainer::GetVisible() {
01150         return this->visible;
01151 }
01152 
01159 void glictContainer::SetEnabled(bool enabled) {
01160         this->enabled = enabled;
01161 }
01162 
01171 bool glictContainer::GetEnabled() {
01172         return this->enabled;
01173 }
01174 
01188 const char* glictContainer::EvtTypeDescriptor(glictEvents evt) {
01189 
01190         if (evt==GLICT_MOUSEDOWN) return "mousedown";
01191         if (evt==GLICT_MOUSEUP) return "mouseup";
01192         if (evt==GLICT_MOUSECLICK) return "mouseclick";
01193         return "UNKNOWN";
01194 }
01195 
01196 
01197 
01198 
01205 void glictContainer::RecursiveBoundaryFix() {
01206     if (parent)
01207         parent->RecursiveBoundaryFix();
01208     else
01209         this->SetPos(x,y);
01210 }
01211 
01218 void glictContainer::FixContainerOffsets() {
01219 
01220 }
01221 
01222 
01223 
01227 void glictContainer::SetCustomData(void *param) {
01228     this->customdata = param;
01229 }
01230 
01234 void* glictContainer::GetCustomData() {
01235     return customdata;
01236 }
01237 
01238 
01251 void glictContainer::SetVirtualSize(float w, float h) {
01252     virtualsize.w = w;
01253     virtualsize.h = h;
01254 }
01259 void glictContainer::VirtualScrollBottom() {
01260 
01261 }
01262 
01269 void glictContainer::SetFont(std::string name, unsigned int size) {
01270         this->fontname = name;
01271         this->fontsize = size;
01272 }
01273 
01279 void glictContainer::SetPrevious(glictContainer* p) {
01280         previous = p;
01281 }
01282 
01288 void glictContainer::SetNext(glictContainer *n) {
01289         next = n;
01290 }

SourceForge.net Logo
generated with doxygen 1.5.3 on Mon Oct 29 18:09:26 2007