00001
00002
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
00014 static HBRUSH hbrBlack=0, hbrRed=0, hbrGreen=0,
00015 hbrBlue=0, hbrDashed, hbrDotted, hbrLtGray;
00016 static HGDIOBJ hpenOld=0,hpen;
00017
00018
00019 static std::vector<HBRUSH > hbrTable;
00020
00021
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
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;
00043 }
00044
00045 float dx=m_lastx-x, dy=m_lasty-y;
00046
00047 float s[]={-1,-1,-1,-1};
00048 int k=0;
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
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
00121
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
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
00144 draw_string(-0.90f,-0.90f,title);
00145 }
00146 void WinDraw::set_quad(int quadnr, const char* title, int selected)
00147 {
00148
00149 if (quadnr==0) {
00150
00151
00152 flSingle = true;
00153 currentQuad = screen;
00154 selectedQuad = screen;
00155 }else {
00156
00157 flSingle = false;
00158 currentQuad = quadrant [ quadnr-1];
00159 if( selected) selectedQuad = currentQuad;
00160 }
00161
00162
00163
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
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;
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;
00223
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
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
00264 void WinDraw::set_line_style( int s)
00265 {
00266 switch( s)
00267 {case 0:
00268 ::SelectObject(m_hdc, hbrBlack);
00269 break;
00270 case 1:
00271 ::SelectObject(m_hdc, hbrDotted);
00272 break;
00273 case 3:
00274 ::SelectObject(m_hdc, hbrDashed);
00275 break;
00276 case 2: 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;
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