Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

WinDraw.cxx

Go to the documentation of this file.
00001 //  $Header: /nfs/slac/g/glast/ground/cvs/gui/src/WinDraw.cxx,v 1.2 2001/08/11 15:26:04 burnett Exp $
00002 //   Author: Toby Burnett
00003 //
00004 #ifdef WIN32  // stupid to prevent compilation on unix platforms 
00005 #include "WinDraw.h"
00006 #include "gui/DisplayRep.h"
00007 #include <cassert>
00008 #include <vector>
00009 #include <cmath>
00010 
00011 static float scale;
00012 
00013 // specific brushes should be done more generally
00014 static HBRUSH hbrBlack=0, hbrRed=0, hbrGreen=0, 
00015 hbrBlue=0, hbrDashed, hbrDotted, hbrLtGray;
00016 static HGDIOBJ hpenOld=0,hpen;
00017 
00018 // table of brushes created from pallete table
00019 static std::vector<HBRUSH > hbrTable;
00020 
00021 // rectangles used in display
00022 static RECT screen;
00023 static RECT currentQuad;
00024 static RECT quadrant[4];
00025 static RECT selectedQuad;
00026 static bool flSingle=true;
00027 
00028 inline int xscale(float x){ return (int)((x+1.0)*scale)+currentQuad.left;}
00029 inline int yscale(float y){ return (int)((1.0-y)*scale)+currentQuad.top;}
00030 
00031 static bool inline inside(float x, float y){return fabs(x)<1.01 && fabs(y)<1.01;}
00032 // Special clipping routine to fix high magnification
00033 bool WinDraw::clip(float x, float y,
00034                  int& ix1, int& iy1, int& ix2, int& iy2)
00035 {
00036   bool b1=inside(x,y), b2=inside(m_lastx,m_lasty);
00037   if( b1 && b2) {
00038     ix2 = xscale(x);
00039     iy2 = yscale(y);
00040     ix1 = xscale(m_lastx);
00041     iy1 = yscale(m_lasty);
00042     return true; // both endpoints are inside: done
00043   }
00044   // either or both is outside
00045   float dx=m_lastx-x, dy=m_lasty-y;
00046   // find parametric values for intersections with scene boundaries at +-1
00047   float s[]={-1,-1,-1,-1};
00048   int k=0; // count of intersections
00049   if( dx!=0){s[k++]=(1-x)/dx; s[k++] = (-1-x)/dx;}
00050   if( dy!=0){s[k++]=(1-y)/dy; s[k++] = (-1-y)/dy;}
00051 
00052   float t[4];
00053   int j=0;
00054   if( b1) t[j++]=0;
00055   if( b2) t[j++]=1;
00056   
00057   // if endpoint in region, already have it. now find 1 or 2 others
00058   for( int i=0; i<k; ++i){
00059     if(s[i]>0 && s[i]<1 && inside(x+s[i]*dx,y+s[i]*dy)) t[j++]=s[i];
00060   }
00061   if( j<2 )return false;
00062   ix1 = xscale(x+t[0]*dx);
00063   iy1 = yscale(y+t[0]*dy);
00064   ix2 = xscale(x+t[1]*dx);
00065   iy2 = yscale(y+t[1]*dy);
00066   return true;
00067 } 
00068 
00069 void WinDraw::move_to(float x, float y)
00070 {
00071   m_lastx=x; m_lasty=y;
00072 }
00073 
00074 void WinDraw::line_to(float x, float y)
00075 {
00076   int x1,y1,x2,y2;
00077   if( clip(x,y, x1,y1,x2,y2) ) {
00078       ::MoveToEx(m_hdc, x1,y1, NULL);
00079       ::LineTo(m_hdc, x2,y2);
00080   }   
00081   m_lastx = x;
00082   m_lasty = y;
00083 
00084 }
00085 
00086 float WinDraw::xnorm(int ix)
00087 {
00088     return (ix-selectedQuad.left)/scale-1.0;
00089 }
00090 float WinDraw::ynorm(int iy)
00091 {
00092     return 1.0 - (iy-selectedQuad.top)/scale;
00093 }
00094 
00095 WinDraw::WinDraw(HWND win):m_win(win){};
00096 WinDraw::~WinDraw() {}
00097 
00098 
00099 static float fmin(float x, float y){return x<y?x:y;}
00100 static float fmax(float x, float y){return x>y?x:y;}
00101 
00102 void
00103 WinDraw::setHDC(HDC hDC)
00104 {   m_hdc = hDC;
00105     ::GetClientRect(m_win, &screen);
00106 
00107     int xsize = screen.right, 
00108         ysize = screen.bottom;
00109     quadrant[0].left = 0;          quadrant[0].top = 0;          quadrant[0].right = xsize/2;  quadrant[0].bottom = ysize/2;
00110     quadrant[1].left = xsize/2+1;  quadrant[1].top = 0;          quadrant[1].right = xsize;    quadrant[1].bottom = ysize/2;
00111     quadrant[2].left = 0;          quadrant[2].top = ysize/2+1;  quadrant[2].right = xsize/2;  quadrant[2].bottom = ysize;
00112     quadrant[3].left = xsize/2+1;  quadrant[3].top = ysize/2+1;  quadrant[3].right = xsize;    quadrant[3].bottom = ysize;
00113     
00114     currentQuad = screen;
00115     scale = 0.5*fmin(xsize, ysize);
00116     flSingle = true;
00117     
00118     if( hbrBlack ) return;
00119     
00120     // define all pens using the static pallete defined in DisplayRep
00121     // TODO: only create pens as needed
00122     int i=0;
00123     do{ 
00124         DisplayRep::ColorInfo& cinfo = DisplayRep::pallete[i++];
00125         if( cinfo.name == 0 ) break;
00126         hbrTable.push_back(
00127             (HBRUSH)CreatePen( PS_SOLID, 1,RGB(cinfo.r,cinfo.g,cinfo.b) ) 
00128             );
00129     }while(1);
00130     
00131     // (old style pens)
00132     hbrBlack = (HBRUSH)GetStockObject(BLACK_PEN);
00133     hbrLtGray =(HBRUSH)GetStockObject (LTGRAY_BRUSH);
00134     hbrDashed = (HBRUSH)CreatePen(PS_DASH, 1, RGB(0,0,0));
00135     hbrDotted = (HBRUSH)CreatePen(PS_DOT, 1, RGB(0,0,0));
00136     hbrRed =   (HBRUSH)CreatePen(PS_SOLID, 2, RGB(255,0,0));
00137     hbrGreen = (HBRUSH)CreatePen(PS_SOLID, 2, RGB(0,255,0));
00138     hbrBlue =  (HBRUSH)CreatePen(PS_SOLID, 2, RGB(0,0,255));
00139 }
00140 
00141 void WinDraw::drawTitle(const char * title, int selected)
00142 {
00143     //draw_string(0.f,0.95f,title);
00144     draw_string(-0.90f,-0.90f,title);
00145 }
00146 void WinDraw::set_quad(int quadnr, const char* title, int selected)
00147 {
00148     // select the specified quadrant to draw in
00149     if (quadnr==0)      {
00150         
00151         // 0 -- full screen with one view
00152         flSingle    = true;
00153         currentQuad = screen;
00154         selectedQuad = screen;
00155     }else {
00156         // 1-4-- drawing view quadnr in corresponding screen quadrant
00157         flSingle    = false;
00158         currentQuad = quadrant [ quadnr-1];
00159         if( selected) selectedQuad = currentQuad;
00160     }
00161     
00162     
00163     // set to clip to the dimensions of the region
00164     ::BeginPath(m_hdc);
00165     ::Rectangle(m_hdc,currentQuad.left, currentQuad.top, currentQuad.right, currentQuad.bottom);
00166     ::EndPath(m_hdc);
00167     ::SelectClipPath(m_hdc, RGN_COPY); 
00168     
00169     
00170     scale = 0.5*fmin(currentQuad.right-currentQuad.left, currentQuad.bottom-currentQuad.top);
00171     
00172     // if title specfied, draw  the title
00173     if( title )
00174         drawTitle(title, selected);
00175     if(selected) {
00176         drawRectangle();  
00177     }
00178 }
00179 
00180 void WinDraw::drawRectangle()
00181 {
00182     static int b=1, c=2; // pixels in from borders
00183     ::SelectObject(m_hdc, hbrBlack);
00184     ::MoveToEx(m_hdc,currentQuad.left+b,    currentQuad.top+b,   NULL);
00185     ::LineTo(m_hdc,  currentQuad.right-c,    currentQuad.top+b);
00186     ::LineTo(m_hdc,  currentQuad.right-c,    currentQuad.bottom-c);
00187     ::LineTo(m_hdc,  currentQuad.left+b,            currentQuad.bottom-c);
00188     ::LineTo(m_hdc,  currentQuad.left+b,            currentQuad.top+b);
00189     
00190 }
00191 void WinDraw::fill_polygon(const float* xy, int npoints, Shading pattern)
00192 {
00193     tagPOINT* points = new tagPOINT[npoints];
00194     tagPOINT* pt = points;
00195     for(int i = 0; i<npoints; ++i, ++pt) {
00196         pt->x = xscale(*xy++);
00197         pt->y = yscale(*xy++);
00198     }
00199     if( pattern==NONE){
00200         ::MoveToEx(m_hdc, points->x, points->y,NULL);
00201         ::PolylineTo(m_hdc, points, npoints);
00202         ::LineTo(m_hdc, points->x, points->y);
00203     }else {
00204         switch (pattern) {
00205         case BRIGHT: ::SelectObject(m_hdc, (HBRUSH)GetStockObject (WHITE_BRUSH)); break;
00206         case MEDIUM: ::SelectObject(m_hdc, hbrLtGray); break;
00207         case DARK:   ::SelectObject(m_hdc, (HBRUSH)GetStockObject (BLACK_BRUSH));
00208         }
00209         ::Polygon(m_hdc, points, npoints);
00210     }
00211     delete points;
00212 
00213 }
00214 
00215 void WinDraw::clearArea()
00216 {
00217 }
00218 
00219 
00220 void WinDraw::draw_string(const char* s, int)
00221 { 
00222     const int vertOffset=-5; // arbitray to center vertically
00223     // ::TextOut(m_hdc,lastx,lasty+vertOffset,s,strlen(s));
00224     HFONT hfnt= (HFONT)GetStockObject(ANSI_VAR_FONT),
00225         hOldFont = (HFONT)SelectObject(m_hdc, hfnt);
00226     COLORREF hOldbk = (COLORREF)::SetBkColor(m_hdc, RGB(192,192,192) );
00227 
00228     //uncomment for center ::SetTextAlign(m_hdc,TA_CENTER ); 
00229     ::TextOut(m_hdc,xscale(m_lastx), yscale(m_lasty)+vertOffset,s,strlen(s));
00230     SelectObject(m_hdc, hOldFont); 
00231     
00232 }
00233 void WinDraw::draw_string(float x,float y,const char *s, int)
00234 {
00235     move_to(x,y);
00236     draw_string(s);
00237 }
00238 
00239 void WinDraw::clearArea(int x, int y, int width, int height)
00240 {
00241 }
00242 
00243 
00244 static float ms=0.015f;
00245 void WinDraw::draw_marker(float x, float y)
00246 {
00247     move_to(x-ms,y);    line_to(x+ms,y);
00248     move_to(x,   y-ms); line_to(x,   y+ms);
00249     move_to(x-ms,y-ms); line_to(x+ms,y+ms);
00250     move_to(x+ms,y-ms); line_to(x-ms,y+ms);
00251 }
00252 
00253 
00254 void WinDraw::set_defaults()
00255 {   
00256     ::SelectObject(m_hdc, hbrBlack);
00257 }
00258 
00259 void WinDraw::set_line_width(float w)
00260 {
00261 }
00262 
00263 // set the line width
00264 void WinDraw::set_line_style( int s)
00265 {
00266     switch( s)
00267     {case 0/*SOLID_LINE*/:  
00268     ::SelectObject(m_hdc, hbrBlack);
00269     break;
00270     case 1/*DOTTED_LINE*/: 
00271         ::SelectObject(m_hdc, hbrDotted);
00272         break;
00273     case 3/*DASHED_LINE*/: 
00274         ::SelectObject(m_hdc, hbrDashed);
00275         break;
00276     case 2/*CENTER_LINE*/:  break;
00277     }
00278 }
00279 
00280 void WinDraw::set_col_index(int i)
00281 {
00282     assert( i<hbrTable.size() );
00283     ::SelectObject(m_hdc, hbrTable[i] );
00284 }
00285 
00286 void WinDraw::set_rgb(float r, float g, float b)
00287 {
00288     if( r==0 && g==0 && b==0 )         hpen = hbrBlack;
00289     else if (r==1 && g==0 && b==0)      hpen = hbrRed;
00290     else if (r==0 && g==1 && b==0)      hpen = hbrGreen;
00291     else if (r==0 && g==0 && b==1)      hpen = hbrBlue;
00292     else if (r==1 && g==1 && b==1)      hpen = hbrBlack;  // why here?
00293     else
00294         hpen =  CreatePen(PS_SOLID, 1, 
00295         RGB(static_cast<int>(r*256.),
00296         static_cast<int>(g*256.),
00297         static_cast<int>(b*256.)));
00298     
00299     ::SelectObject(m_hdc, hpen);
00300     
00301 }
00302 
00303 void WinDraw::set_marker_size(float ){
00304 }
00305 
00306 void WinDraw::invalidate()
00307 {
00308     ::InvalidateRect(m_win, NULL, TRUE);
00309 }
00310 
00311 
00312 #endif // NT_MSVCPP

Generated at Mon Nov 26 18:18:11 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000