00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(SJPANEL_H_INCLUDED)
00012 #define SJPANEL_H_INCLUDED
00013
00014 namespace sjgui{
00015
00028 template<class Tslider,class Tbase>
00029 class CPanelCtrlTmpl : public Tbase
00030 {
00031
00032
00033 int m_AreaWidth;
00034 int m_AreaHeight;
00035 int m_VShift;
00036 int m_HShift;
00037 bool m_yClip;
00038 int m_iHDist;
00039 void Adjust();
00040 protected:
00041 Tslider m_VScrlBar;
00042 Tslider m_HScrlBar;
00043 public:
00044 CPanelCtrlTmpl();
00046 virtual void OnReshape();
00050 virtual void Draw();
00055 void EnableScrlBars(bool h=true,bool v=true){m_VScrlBar.Enable(h);m_HScrlBar.Enable(v);}
00057 bool IsVScrlBarVisible(){return m_VScrlBar.IsVisible();};
00059 bool IsHScrlBarVisible(){return m_HScrlBar.IsVisible();};
00061 virtual void OnKeyUp(int &iKey);
00063 virtual CWnd* GetFirstChild()
00064 {
00065 CWnd* p=Tbase::GetFirstChild();
00066 while(p!=NULL && (p==&m_VScrlBar || p==&m_HScrlBar))
00067 p=Tbase::GetNextChild(p);
00068 return p;
00069 }
00071 virtual CWnd* GetNextChild(CWnd* pWnd)
00072 {
00073 CWnd* p=Tbase::GetNextChild(pWnd);
00074 while(p!=NULL && (p==&m_VScrlBar || p==&m_HScrlBar))
00075 p=Tbase::GetNextChild(p);
00076 return p;
00077 }
00079 virtual CWnd* GetLastChild()
00080 {
00081 CWnd* p=Tbase::GetLastChild();
00082 while(p!=NULL && (p==&m_VScrlBar || p==&m_HScrlBar))
00083 p=Tbase::GetPrevChild(p);
00084 return p;
00085 }
00087 virtual CWnd* GetPrevChild(CWnd* pWnd)
00088 {
00089 CWnd* p=Tbase::GetPrevChild(pWnd);
00090 while(p!=NULL && (p==&m_VScrlBar || p==&m_HScrlBar))
00091 p=Tbase::GetPrevChild(p);
00092 return p;
00093 }
00094 };
00095
00106 template<class Tslider,class Tbase>
00107 class CStackPanelCtrlTmpl : public CPanelCtrlTmpl<Tslider, Tbase>
00108 {
00109 int m_iDist;
00110 int m_iSideDist;
00111 int m_iOffset;
00112 CWnd::eAligns m_eVAlign;
00113 CWnd::eAligns m_eHAlign;
00114 bool m_yReverse;
00115 bool m_yVertMode;
00116 public:
00117 CStackPanelCtrlTmpl():CPanelCtrlTmpl<Tslider, Tbase>()
00118 {
00119 m_iOffset=0;
00120 m_iDist=0;
00121 m_iSideDist=0;
00122 m_yReverse=false;
00123 m_yVertMode=false;
00124 SetAlign();
00125 EnableScrlBars(false,false);
00126 }
00129 virtual void OnUpdatePos()
00130 {
00131 CPanelCtrlTmpl<Tslider, Tbase>::OnUpdatePos();
00132 if(IsVertMode())
00133 {
00134 m_ClAr.SetPos(GetSideDist(),GetDist());
00135 m_ClAr.SetHeight(m_ClAr.GetHeight()-GetDist()*2);
00136 m_ClAr.SetWidth(m_ClAr.GetWidth()-GetSideDist()*2);
00137 }
00138 else
00139 {
00140 m_ClAr.SetPos(GetDist(),GetSideDist());
00141 m_ClAr.SetHeight(m_ClAr.GetHeight()-GetSideDist()*2);
00142 m_ClAr.SetWidth(m_ClAr.GetWidth()-GetDist()*2);
00143 }
00144 }
00146 void SetVertMode(bool b=true){m_yVertMode=b;}
00148 bool IsVertMode(){return m_yVertMode;}
00160 void SetDist(int i){m_iDist=i;}
00172 void SetSideDist(int i){m_iSideDist=i;}
00174 int GetSideDist(){return m_iSideDist;}
00176 int GetDist(){return m_iDist;}
00178 int GetOffset(){return m_iOffset;}
00180 void SetOffset(int i){m_iOffset=i;}
00186 void ReverseOrder(bool y=true){m_yReverse=y;}
00187 virtual void OnReshape();
00188
00189 void SetHAlign(CWnd::eAligns e){m_eHAlign=e;}
00191 CWnd::eAligns GetHAlign(){return m_eHAlign;}
00196 void SetVAlign(CWnd::eAligns e){m_eVAlign=e;}
00201 CWnd::eAligns GetVAlign(){return m_eVAlign;}
00206 void SetAlign(CWnd::eAligns eH=ALIGN_LEFT,CWnd::eAligns eV=ALIGN_TOP)
00207 {m_eHAlign=eH;m_eVAlign=eV;}
00208 };
00209
00222 template<class Tslider,class Tbase>
00223 class CSqueezePanelCtrlTmpl : public CStackPanelCtrlTmpl<Tslider,Tbase>
00224 {
00225 bool m_yEven;
00226 void VerticalSqueeze()
00227 {
00228 CWnd* pWnd=NULL;
00229 int iSize=0;
00230 int iLen=GetDist();
00231 int iMax=0;
00232 int iSizeHeight=0;
00233 int iChildren=0;
00234
00235 pWnd=GetFirstChild();
00236 while(pWnd!=NULL)
00237 {
00238 iChildren++;
00239 iLen+=pWnd->GetHeight();
00240
00241 iMax=std::max(iMax,pWnd->GetMinWidth());
00242 pWnd=GetNextChild(pWnd);
00243 }
00244 if(iChildren==0)return;
00245
00246 iLen+=GetOffset()*(iChildren-1);
00247 iSize=GetClAr().GetWidth()-1;
00248 iSizeHeight=GetClAr().GetHeight();
00249 if(iMax>GetClAr().GetWidth() && m_VScrlBar.IsEnabled())
00250 {
00251 iLen+=m_VScrlBar.GetHeight();
00252 iSizeHeight-=m_VScrlBar.GetHeight();
00253 }
00254
00255 if(iLen>GetClAr().GetHeight() && m_VScrlBar.IsEnabled())
00256 iSize-=m_VScrlBar.GetWidth();
00257
00258 iSizeHeight/=iChildren;
00259
00260 pWnd=GetFirstChild();
00261 while(pWnd!=NULL)
00262 {
00263 pWnd->SetWidth(iSize);
00264 if(IsEven())pWnd->SetHeight(iSizeHeight);
00265 pWnd=GetNextChild(pWnd);
00266 }
00267 }
00268 void HorizontalSqueeze()
00269 {
00270 CWnd* pWnd=NULL;
00271 int iSizeHeight=0;
00272 int iLenWidth=GetDist();
00273 int iMaxHeight=0;
00274 int iSizeWidth=0;
00275 int iChildren=0;
00276
00277 pWnd=GetFirstChild();
00278 while(pWnd!=NULL)
00279 {
00280 iChildren++;
00281 iLenWidth+=pWnd->GetWidth();
00282
00283 iMaxHeight=std::max(iMaxHeight,pWnd->GetMinHeight());
00284 pWnd=GetNextChild(pWnd);
00285 }
00286 if(iChildren==0)return;
00287
00288 iLenWidth+=GetOffset()*(iChildren-1);
00289 iSizeHeight=GetClAr().GetHeight()-1;
00290 iSizeWidth=GetClAr().GetWidth()-GetOffset()*(iChildren-1);
00291 if(iMaxHeight>GetClAr().GetHeight() && m_VScrlBar.IsEnabled())
00292 {
00293 iLenWidth+=m_VScrlBar.GetWidth();
00294 iSizeWidth-=m_VScrlBar.GetWidth();
00295 }
00296
00297 if(iLenWidth>GetClAr().GetWidth() && m_HScrlBar.IsEnabled())
00298 iSizeHeight-=m_HScrlBar.GetHeight();
00299
00300 iSizeWidth/=iChildren;
00301
00302 pWnd=GetFirstChild();
00303 while(pWnd!=NULL)
00304 {
00305 pWnd->SetHeight(iSizeHeight);
00306 if(IsEven())pWnd->SetWidth(iSizeWidth);
00307 pWnd=GetNextChild(pWnd);
00308 }
00309 }
00310 public:
00311 CSqueezePanelCtrlTmpl():CStackPanelCtrlTmpl<Tslider,Tbase>(){m_yEven=false;}
00319 void SetEven(bool b=true){m_yEven=b;};
00321 bool IsEven(){return m_yEven;}
00322 virtual void OnReshape()
00323 {
00324 if(IsVertMode())
00325 VerticalSqueeze();
00326 else
00327 HorizontalSqueeze();
00328 CStackPanelCtrlTmpl<Tslider,Tbase>::OnReshape();
00329 }
00330 };
00331
00332 template<class Tslider,class Tbase>
00333 inline void CStackPanelCtrlTmpl<Tslider,Tbase>::OnReshape()
00334 {
00335
00336 int iCurX=0;
00337 int iCurY=0;
00338 CWnd* pWnd=NULL;
00339 if(IsVertMode())
00340 {
00341 if(m_yReverse)
00342 pWnd=GetLastChild();
00343 else
00344 pWnd=GetFirstChild();
00345 while(pWnd!=NULL)
00346 {
00347
00348 switch(m_eHAlign)
00349 {
00350 case ALIGN_LEFT:
00351 iCurX=GetClAr().GetX();
00352 break;
00353 case ALIGN_RIGHT:
00354 iCurX=GetClAr().GetRight()-pWnd->GetWidth();
00355 break;
00356 case ALIGN_CENTER:
00357 iCurX=(int)((GetClAr().GetWidth()-pWnd->GetWidth())/2)+GetClAr().GetX();
00358 break;
00359 default:
00360 assert(false);
00361 }
00362 pWnd->SetPos(iCurX,iCurY);
00363 iCurY+=m_iOffset+pWnd->GetHeight()+1;
00364
00365 if(m_yReverse)
00366 pWnd=GetPrevChild(pWnd);
00367 else
00368 pWnd=GetNextChild(pWnd);
00369 }
00370
00371 switch(m_eVAlign)
00372 {
00373 case ALIGN_TOP:
00374 iCurY=GetClAr().GetY();
00375 break;
00376 case ALIGN_BOTTOM:
00377 iCurY=GetClAr().GetBottom()-iCurY;
00378 break;
00379 case ALIGN_CENTER:
00380 iCurY=(int)((GetClAr().GetHeight()-iCurY)/2)+GetClAr().GetY();
00381 break;
00382 default:
00383 assert(false);
00384 }
00385 if(m_yReverse)
00386 pWnd=GetLastChild();
00387 else
00388 pWnd=GetFirstChild();
00389 while(pWnd!=NULL)
00390 {
00391
00392 pWnd->SetPos(pWnd->GetX(),pWnd->GetY()+iCurY);
00393
00394 if(m_yReverse)
00395 pWnd=GetPrevChild(pWnd);
00396 else
00397 pWnd=GetNextChild(pWnd);
00398 }
00399 }
00400 else
00401 {
00402 if(m_yReverse)
00403 pWnd=GetLastChild();
00404 else
00405 pWnd=GetFirstChild();
00406 while(pWnd!=NULL)
00407 {
00408
00409 switch(m_eVAlign)
00410 {
00411 case ALIGN_TOP:
00412 iCurY=GetClAr().GetY();
00413 break;
00414 case ALIGN_BOTTOM:
00415 iCurY=GetClAr().GetBottom()-pWnd->GetHeight();
00416 break;
00417 case ALIGN_CENTER:
00418 iCurY=(int)((GetClAr().GetHeight()-pWnd->GetHeight())/2)+GetClAr().GetY();
00419 break;
00420 default:
00421 assert(false);
00422 }
00423 pWnd->SetPos(iCurX,iCurY);
00424 iCurX+=m_iOffset+pWnd->GetWidth()+1;
00425
00426 if(m_yReverse)
00427 pWnd=GetPrevChild(pWnd);
00428 else
00429 pWnd=GetNextChild(pWnd);
00430 }
00431
00432
00433
00434
00435 switch(m_eHAlign)
00436 {
00437 case ALIGN_LEFT:
00438 iCurX=GetClAr().GetX();
00439 break;
00440 case ALIGN_RIGHT:
00441 iCurX=GetClAr().GetRight()-iCurX;
00442 break;
00443 case ALIGN_CENTER:
00444 iCurX=(int)((GetClAr().GetRight()-iCurX)/2)+GetClAr().GetX();
00445 break;
00446 default:
00447 assert(false);
00448 }
00449 if(m_yReverse)
00450 pWnd=GetLastChild();
00451 else
00452 pWnd=GetFirstChild();
00453 while(pWnd!=NULL)
00454 {
00455
00456 pWnd->SetPos(pWnd->GetX()+iCurX,pWnd->GetY());
00457
00458 if(m_yReverse)
00459 pWnd=GetPrevChild(pWnd);
00460 else
00461 pWnd=GetNextChild(pWnd);
00462 }
00463 }
00464 CPanelCtrlTmpl<Tslider,Tbase>::OnReshape();
00465 }
00466
00467 template<class Tslider,class Tbase>
00468 inline void CPanelCtrlTmpl<Tslider,Tbase>::Adjust()
00469 {
00470
00471 if(m_HScrlBar.IsVisible() && m_HScrlBar.GetSliderPos()!=m_HShift)
00472 {
00473 int iTr=m_HScrlBar.GetSliderPos()-m_HShift;
00474
00475 for(CWnd::TWnds::iterator pos=m_Wnds.begin();pos!=m_Wnds.end();++pos)
00476
00477 if((*pos)!=&m_HScrlBar && (*pos)!=&m_VScrlBar)
00478 (*pos)->SetPos((*pos)->GetX()-iTr,(*pos)->GetY());
00479 m_HShift=m_HScrlBar.GetSliderPos();
00480 }
00481 if(m_VScrlBar.IsVisible() && m_VScrlBar.GetSliderPos()!=m_VShift)
00482 {
00483 int iTr=m_VScrlBar.GetSliderPos()-m_VShift;
00484
00485 for(CWnd::TWnds::iterator pos=m_Wnds.begin();pos!=m_Wnds.end();++pos)
00486
00487 if((*pos)!=&m_HScrlBar && (*pos)!=&m_VScrlBar)
00488 (*pos)->SetPos((*pos)->GetX(),(*pos)->GetY()-iTr);
00489 m_VShift=m_VScrlBar.GetSliderPos();
00490 }
00491 }
00492
00493 template<class Tslider,class Tbase>
00494 inline void CPanelCtrlTmpl<Tslider,Tbase>::OnKeyUp(int &iKey)
00495 {
00496 Tbase::OnKeyUp(iKey);
00497 Adjust();
00498 }
00499
00500 template<class Tslider,class Tbase>
00501 inline void CPanelCtrlTmpl<Tslider,Tbase>::OnReshape()
00502 {
00503
00504 CWnd::CRect Area(GetAbsPos().GetX()+GetBorderSize()-m_HShift,GetAbsPos().GetY()+GetBorderSize()-m_VShift,0,0);
00505 m_yClip=false;
00506 for(CWnd::TWnds::iterator pos=m_Wnds.begin();pos!=m_Wnds.end();++pos)
00507
00508 if((*pos)!=&m_HScrlBar && (*pos)!=&m_VScrlBar)
00509 {
00510 Area.SetRight(max(Area.GetRight(),(*pos)->GetAbsPos().GetRight()));
00511 Area.SetBottom(max(Area.GetBottom(),(*pos)->GetAbsPos().GetBottom()));
00512 Area.SetX(min(Area.GetX(),(*pos)->GetAbsPos().GetX()));
00513 Area.SetY(min(Area.GetY(),(*pos)->GetAbsPos().GetY()));
00514 }
00515
00516 Area.SetRight(max(Area.GetRight(),GetAbsPos().GetRight()-GetBorderSize()));
00517 Area.SetBottom(max(Area.GetBottom(),GetAbsPos().GetBottom()-GetBorderSize()));
00518 m_AreaWidth=GetWidth();
00519 m_AreaHeight=GetHeight();
00520 if(m_HScrlBar.IsEnabled() && Area.GetWidth()>GetClAr().GetWidth())
00521 {
00522 m_HScrlBar.Show();
00523 m_AreaHeight-=m_HScrlBar.GetHeight();
00524
00525 BringOnTop(&m_HScrlBar);
00526 m_yClip=true;
00527 }
00528 else
00529 {
00530 m_HScrlBar.Hide();
00531 m_HScrlBar.SetSliderPos(0);
00532
00533 if(m_HScrlBar.IsEnabled())
00534 m_HShift=0;
00535 else if(Area.GetWidth()>GetAbsPos().GetWidth())
00536 m_yClip=true;
00537 }
00538 if(m_VScrlBar.IsEnabled() && Area.GetHeight()>GetClAr().GetHeight())
00539 {
00540 m_VScrlBar.Show();
00541 m_AreaWidth-=m_VScrlBar.GetWidth();
00542
00543 BringOnTop(&m_VScrlBar);
00544 m_yClip=true;
00545 }
00546 else
00547 {
00548 m_VScrlBar.Hide();
00549 m_VScrlBar.SetSliderPos(0);
00550
00551 if(m_VScrlBar.IsEnabled())
00552 m_VShift=0;
00553 else if(Area.GetHeight()>GetClAr().GetHeight())
00554 m_yClip=true;
00555 }
00556
00557 m_HScrlBar.PosWnd(GetBorderSize(),GetHeight()-m_HScrlBar.GetHeight()-GetBorderSize(),GetWidth()-m_VScrlBar.GetWidth()-GetBorderSize()*2,m_HScrlBar.GetHeight());
00558 m_VScrlBar.PosWnd(GetWidth()-m_VScrlBar.GetWidth()+GetBorderSize(),GetBorderSize(),m_VScrlBar.GetWidth(),GetHeight()-GetBorderSize()*2);
00559 m_HScrlBar.SetMinMax(0,Area.GetWidth()-m_AreaWidth);
00560 m_HScrlBar.SetSliderLength(m_AreaWidth/(Area.GetWidth()!=0?Area.GetWidth():1.0f));
00561 m_VScrlBar.SetMinMax(0,Area.GetHeight()-m_AreaHeight);
00562 m_VScrlBar.SetSliderLength(m_AreaHeight/(Area.GetHeight()!=0?Area.GetHeight():1.0f));
00563 Adjust();
00564 Tbase::OnReshape();
00565 }
00566
00567 template<class Tslider,class Tbase>
00568 inline void CPanelCtrlTmpl<Tslider,Tbase>::Draw()
00569 {
00570 GLboolean ySc=false;
00571 GLint old_pos[4];
00572 if(m_yClip)
00573 {
00574 ySc=glIsEnabled(GL_SCISSOR_TEST);
00575 glGetIntegerv(GL_SCISSOR_BOX,old_pos);
00576 CWnd::CRect cur( m_AbsPos.GetX(),
00577 GetScreenHeight()-m_AbsPos.GetY()-m_AreaHeight,
00578 m_AreaWidth+1,
00579 m_AreaHeight+1);
00580 if(ySc)
00581 {
00582 cur.Intersection(CRect(old_pos));
00583 if(cur.IsEmpty())
00584
00585 return;
00586 }
00587
00588
00589 glScissor( cur.GetX(),
00590 cur.GetY(),
00591 cur.GetWidth(),
00592 cur.GetHeight());
00593
00594
00595
00596
00597
00598
00599 if(m_VScrlBar.IsVisible())m_VScrlBar.Draw();
00600 if(m_HScrlBar.IsVisible())m_HScrlBar.Draw();
00601 glEnable(GL_SCISSOR_TEST);
00602 }
00603 Tbase::Draw();
00604 if(m_yClip)
00605 {
00606
00607 if(!ySc)glDisable(GL_SCISSOR_TEST);
00608
00609 glScissor(old_pos[0],old_pos[1],old_pos[2],old_pos[3]);
00610 }
00611 }
00612
00613 template<class Tslider,class Tbase>
00614 inline CPanelCtrlTmpl<Tslider,Tbase>::CPanelCtrlTmpl<Tslider,Tbase>():Tbase()
00615 {
00616 m_yClip=false;
00617 m_VScrlBar.Hide();
00618 m_HScrlBar.Hide();
00619 RegisterChild(&m_VScrlBar);
00620 RegisterChild(&m_HScrlBar);
00621 m_HScrlBar.SetOrient(CWnd::HORIZONTAL);
00622 m_VScrlBar.SetOrient(CWnd::VERTICAL);
00623 m_AreaWidth=0;
00624 m_AreaHeight=0;
00625 m_HShift=0;
00626 m_VShift=0;
00627 }
00628
00629 }
00630
00631 #endif // !defined(SJPANEL_H_INCLUDED)