Base.cpp 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. /*
  2. GWEN
  3. Copyright (c) 2010 Facepunch Studios
  4. See license in Gwen.h
  5. */
  6. #include "Gwen/Controls/Base.h"
  7. #include "Gwen/Controls/Label.h"
  8. #include "Gwen/Gwen.h"
  9. #include "Gwen/BaseRender.h"
  10. #include "Gwen/Skin.h"
  11. #include "Gwen/Platform.h"
  12. #include "Gwen/DragAndDrop.h"
  13. #include "Gwen/ToolTip.h"
  14. #include "Gwen/Utility.h"
  15. #include <list>
  16. #ifndef GWEN_NO_ANIMATION
  17. #include "Gwen/Anim.h"
  18. #endif
  19. using namespace Gwen;
  20. using namespace Controls;
  21. Base::Base( Base* pParent )
  22. {
  23. m_Parent = NULL;
  24. m_ActualParent = NULL;
  25. m_InnerPanel = NULL;
  26. m_Skin = NULL;
  27. SetParent( pParent );
  28. m_bHidden = false;
  29. m_Bounds = Gwen::Rect(0,0,10,10);
  30. m_Padding = Padding( 0, 0, 0, 0 );
  31. m_Margin = Margin( 0, 0, 0, 0 );
  32. m_iDock = 0;
  33. m_DragAndDrop_Package = NULL;
  34. m_pUserData = NULL;
  35. RestrictToParent( false );
  36. SetMouseInputEnabled( true );
  37. SetKeyboardInputEnabled( false );
  38. Invalidate();
  39. SetCursor( Gwen::CursorType::Normal );
  40. SetToolTip( NULL );
  41. SetTabable( false );
  42. SetShouldDrawBackground( true );
  43. m_bDisabled = false;
  44. m_bCacheTextureDirty = true;
  45. m_bCacheToTexture = false;
  46. }
  47. Base::~Base()
  48. {
  49. {
  50. Canvas* canvas = GetCanvas();
  51. if ( canvas )
  52. canvas->PreDelete( this );
  53. }
  54. Base::List::iterator iter = Children.begin();
  55. while ( iter != Children.end() )
  56. {
  57. Base* pChild = *iter;
  58. iter = Children.erase( iter );
  59. delete pChild;
  60. }
  61. for ( AccelMap::iterator accelIt = m_Accelerators.begin(); accelIt != m_Accelerators.end(); ++accelIt )
  62. {
  63. delete accelIt->second;
  64. }
  65. m_Accelerators.clear();
  66. SetParent( NULL );
  67. if ( Gwen::HoveredControl == this )
  68. Gwen::HoveredControl = NULL;
  69. if ( Gwen::KeyboardFocus == this )
  70. Gwen::KeyboardFocus = NULL;
  71. if ( Gwen::MouseFocus == this ) Gwen::MouseFocus = NULL;
  72. DragAndDrop::ControlDeleted( this );
  73. ToolTip::ControlDeleted( this );
  74. #ifndef GWEN_NO_ANIMATION
  75. Anim::Cancel( this );
  76. #endif
  77. if ( m_DragAndDrop_Package )
  78. {
  79. delete m_DragAndDrop_Package;
  80. m_DragAndDrop_Package = NULL;
  81. }
  82. }
  83. extern int avoidUpdate;
  84. void Base::Invalidate()
  85. {
  86. m_bNeedsLayout = true;
  87. m_bCacheTextureDirty = true;
  88. avoidUpdate = -3;
  89. }
  90. void Base::DelayedDelete()
  91. {
  92. Canvas* canvas = GetCanvas();
  93. canvas->AddDelayedDelete( this );
  94. }
  95. Canvas* Base::GetCanvas()
  96. {
  97. Base* pCanvas = m_Parent;
  98. if ( !pCanvas ) return NULL;
  99. return pCanvas->GetCanvas();
  100. }
  101. void Base::SetParent(Base* pParent)
  102. {
  103. if ( m_Parent == pParent ) return;
  104. if ( m_Parent )
  105. {
  106. m_Parent->RemoveChild( this );
  107. }
  108. m_Parent = pParent;
  109. m_ActualParent = NULL;
  110. if ( m_Parent )
  111. {
  112. m_Parent->AddChild( this );
  113. }
  114. }
  115. void Base::Dock( int iDock )
  116. {
  117. if ( m_iDock == iDock ) return;
  118. m_iDock = iDock;
  119. Invalidate();
  120. InvalidateParent();
  121. }
  122. int Base::GetDock()
  123. {
  124. return m_iDock;
  125. }
  126. bool Base::Hidden() const
  127. {
  128. return m_bHidden;
  129. }
  130. bool Base::Visible() const
  131. {
  132. if ( Hidden() ) return false;
  133. if ( GetParent() )
  134. {
  135. return GetParent()->Visible();
  136. }
  137. return true;
  138. }
  139. void Base::InvalidateChildren( bool bRecursive )
  140. {
  141. for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
  142. {
  143. (*it)->Invalidate();
  144. if ( bRecursive )
  145. (*it)->InvalidateChildren( bRecursive );
  146. }
  147. if ( m_InnerPanel )
  148. {
  149. for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
  150. {
  151. (*it)->Invalidate();
  152. if ( bRecursive )
  153. (*it)->InvalidateChildren( bRecursive );
  154. }
  155. }
  156. }
  157. void Base::Position( int pos, int xpadding, int ypadding )
  158. {
  159. int w = GetParent()->Width();
  160. int h = GetParent()->Height();
  161. const Padding& padding = GetParent()->GetPadding();
  162. int x = X();
  163. int y = Y();
  164. if ( pos & Pos::Left ) x = padding.left + xpadding;
  165. if ( pos & Pos::Right ) x = w - Width() - padding.right - xpadding;
  166. if ( pos & Pos::CenterH ) x = padding.left + xpadding + (w - Width() - padding.left - padding.right) * 0.5;
  167. if ( pos & Pos::Top ) y = padding.top + ypadding;
  168. if ( pos & Pos::Bottom ) y = h - Height() - padding.bottom - ypadding;
  169. if ( pos & Pos::CenterV ) y = padding.top + ypadding + (h - Height() - padding.bottom - padding.top) * 0.5;
  170. SetPos( x, y );
  171. }
  172. void Base::SendToBack()
  173. {
  174. if ( !m_Parent ) return;
  175. if ( m_Parent->Children.front() == this ) return;
  176. m_Parent->Children.remove( this );
  177. m_Parent->Children.push_front( this );
  178. InvalidateParent();
  179. }
  180. void Base::BringToFront()
  181. {
  182. if ( !m_Parent ) return;
  183. if ( m_Parent->Children.back() == this ) return;
  184. m_Parent->Children.remove( this );
  185. m_Parent->Children.push_back( this );
  186. InvalidateParent();
  187. }
  188. Controls::Base* Base::FindChildByName( const Gwen::String& name, bool bRecursive )
  189. {
  190. Base::List::iterator iter;
  191. for (iter = Children.begin(); iter != Children.end(); ++iter)
  192. {
  193. Base* pChild = *iter;
  194. if ( pChild->GetName() == name )
  195. return pChild;
  196. if ( bRecursive )
  197. {
  198. Controls::Base* pSubChild = pChild->FindChildByName( name, true );
  199. if ( pSubChild )
  200. return pSubChild;
  201. }
  202. }
  203. return NULL;
  204. }
  205. void Base::BringNextToControl( Controls::Base* pChild, bool bBehind )
  206. {
  207. if ( !m_Parent ) return;
  208. m_Parent->Children.remove( this );
  209. Base::List::iterator it = std::find( m_Parent->Children.begin(), m_Parent->Children.end(), pChild );
  210. if ( it == m_Parent->Children.end() )
  211. return BringToFront();
  212. if ( bBehind )
  213. {
  214. ++it;
  215. if ( it == m_Parent->Children.end() )
  216. return BringToFront();
  217. }
  218. m_Parent->Children.insert( it, this );
  219. InvalidateParent();
  220. }
  221. void Base::AddChild(Base* pChild)
  222. {
  223. if ( m_InnerPanel )
  224. {
  225. m_InnerPanel->AddChild( pChild );
  226. return;
  227. }
  228. Children.push_back( pChild );
  229. OnChildAdded(pChild);
  230. pChild->m_ActualParent = this;
  231. }
  232. void Base::RemoveChild(Base* pChild)
  233. {
  234. // If we removed our innerpanel
  235. // remove our pointer to it
  236. if ( m_InnerPanel == pChild )
  237. {
  238. m_InnerPanel = NULL;
  239. }
  240. if ( m_InnerPanel )
  241. {
  242. m_InnerPanel->RemoveChild( pChild );
  243. }
  244. Children.remove( pChild );
  245. OnChildRemoved(pChild);
  246. }
  247. void Base::RemoveAllChildren()
  248. {
  249. while ( Children.size() > 0 )
  250. {
  251. RemoveChild( *Children.begin() );
  252. }
  253. }
  254. int Base::NumChildren()
  255. {
  256. // Include m_InnerPanel's children here?
  257. return Children.size();
  258. }
  259. void Base::OnChildAdded(Base* /*pChild*/)
  260. {
  261. Invalidate();
  262. }
  263. void Base::OnChildRemoved(Base* /*pChild*/)
  264. {
  265. Invalidate();
  266. }
  267. Skin::Base* Base::GetSkin( void )
  268. {
  269. if ( m_Skin ) return m_Skin;
  270. if ( m_Parent ) return m_Parent->GetSkin();
  271. Debug::AssertCheck( 0, "Base::GetSkin Returning NULL!\n" );
  272. return NULL;
  273. }
  274. void Base::MoveBy( int x, int y )
  275. {
  276. SetBounds( X() + x, Y() + y, Width(), Height() );
  277. }
  278. void Base::MoveTo( int x, int y )
  279. {
  280. if ( m_bRestrictToParent && GetParent() )
  281. {
  282. Base* pParent = GetParent();
  283. if ( x - GetPadding().left < pParent->GetMargin().left ) x = pParent->GetMargin().left + GetPadding().left;
  284. if ( y - GetPadding().top < pParent->GetMargin().top ) y = pParent->GetMargin().top + GetPadding().top;
  285. if ( x + Width() + GetPadding().right > pParent->Width() - pParent->GetMargin().right ) x = pParent->Width() - pParent->GetMargin().right - Width() - GetPadding().right;
  286. if ( y + Height() + GetPadding().bottom > pParent->Height() - pParent->GetMargin().bottom ) y = pParent->Height() - pParent->GetMargin().bottom - Height() - GetPadding().bottom;
  287. }
  288. SetBounds(x, y, Width(), Height());
  289. }
  290. void Base::SetPos( int x, int y )
  291. {
  292. SetBounds( x, y, Width(), Height() );
  293. }
  294. bool Base::SetSize( int w, int h )
  295. {
  296. return SetBounds( X(), Y(), w, h );
  297. }
  298. bool Base::SetBounds( const Gwen::Rect& bounds )
  299. {
  300. return SetBounds( bounds.x, bounds.y, bounds.w, bounds.h );
  301. }
  302. bool Base::SetBounds( int x, int y, int w, int h )
  303. {
  304. if ( m_Bounds.x == x &&
  305. m_Bounds.y == y &&
  306. m_Bounds.w == w &&
  307. m_Bounds.h == h )
  308. return false;
  309. Gwen::Rect oldBounds = GetBounds();
  310. m_Bounds.x = x;
  311. m_Bounds.y = y;
  312. m_Bounds.w = w;
  313. m_Bounds.h = h;
  314. OnBoundsChanged( oldBounds );
  315. return true;
  316. }
  317. void Base::OnBoundsChanged(Gwen::Rect oldBounds)
  318. {
  319. //Anything that needs to update on size changes
  320. //Iterate my children and tell them I've changed
  321. //
  322. if ( m_Bounds.w != oldBounds.w || m_Bounds.h != oldBounds.h )
  323. {
  324. if ( GetParent() )
  325. GetParent()->OnChildBoundsChanged( oldBounds, this );
  326. Invalidate();
  327. }
  328. Redraw();
  329. UpdateRenderBounds();
  330. }
  331. void Base::OnScaleChanged()
  332. {
  333. for ( Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter )
  334. {
  335. (*iter)->OnScaleChanged();
  336. }
  337. }
  338. void Base::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
  339. {
  340. }
  341. void Base::Render( Gwen::Skin::Base* /*skin*/ )
  342. {
  343. }
  344. void Base::DoCacheRender( Gwen::Skin::Base* skin, Gwen::Controls::Base* pMaster )
  345. {
  346. Gwen::Renderer::Base* render = skin->GetRender();
  347. Gwen::Renderer::ICacheToTexture* cache = render->GetCTT();
  348. if ( !cache ) return;
  349. Gwen::Point pOldRenderOffset = render->GetRenderOffset();
  350. Gwen::Rect rOldRegion = render->ClipRegion();
  351. if ( this != pMaster )
  352. {
  353. render->AddRenderOffset( GetBounds() );
  354. render->AddClipRegion( GetBounds() );
  355. }
  356. else
  357. {
  358. render->SetRenderOffset( Gwen::Point( 0, 0 ) );
  359. render->SetClipRegion( GetBounds() );
  360. }
  361. if ( m_bCacheTextureDirty && render->ClipRegionVisible() )
  362. {
  363. render->StartClip();
  364. if ( ShouldCacheToTexture() )
  365. cache->SetupCacheTexture( this );
  366. //Render myself first
  367. Render( skin );
  368. if ( !Children.empty() )
  369. {
  370. //Now render my kids
  371. for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
  372. {
  373. Base* pChild = *iter;
  374. if ( pChild->Hidden() ) continue;
  375. pChild->DoCacheRender( skin, pMaster );
  376. }
  377. }
  378. if ( ShouldCacheToTexture() )
  379. {
  380. cache->FinishCacheTexture( this );
  381. m_bCacheTextureDirty = false;
  382. }
  383. }
  384. render->SetClipRegion( rOldRegion );
  385. render->StartClip();
  386. render->SetRenderOffset( pOldRenderOffset );
  387. cache->DrawCachedControlTexture( this );
  388. }
  389. void Base::DoRender( Gwen::Skin::Base* skin )
  390. {
  391. // If this control has a different skin,
  392. // then so does its children.
  393. if ( m_Skin )
  394. skin = m_Skin;
  395. // Do think
  396. Think();
  397. Gwen::Renderer::Base* render = skin->GetRender();
  398. if ( render->GetCTT() && ShouldCacheToTexture() )
  399. {
  400. DoCacheRender( skin, this );
  401. return;
  402. }
  403. Gwen::Point pOldRenderOffset = render->GetRenderOffset();
  404. render->AddRenderOffset( GetBounds() );
  405. RenderUnder( skin );
  406. Gwen::Rect rOldRegion = render->ClipRegion();
  407. render->AddClipRegion( GetBounds() );
  408. if ( render->ClipRegionVisible() )
  409. {
  410. render->StartClip();
  411. //Render myself first
  412. Render( skin );
  413. if ( !Children.empty() )
  414. {
  415. //Now render my kids
  416. for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
  417. {
  418. Base* pChild = *iter;
  419. if ( pChild->Hidden() ) continue;
  420. pChild->DoRender( skin );
  421. }
  422. }
  423. render->SetClipRegion( rOldRegion );
  424. render->StartClip();
  425. RenderOver( skin );
  426. }
  427. else
  428. {
  429. render->SetClipRegion( rOldRegion );
  430. }
  431. RenderFocus( skin );
  432. render->SetRenderOffset( pOldRenderOffset );
  433. }
  434. void Base::SetSkin( Skin::Base* skin, bool doChildren )
  435. {
  436. if ( m_Skin == skin ) return;
  437. m_Skin = skin;
  438. Invalidate();
  439. Redraw();
  440. OnSkinChanged( skin );
  441. if ( doChildren )
  442. {
  443. for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
  444. {
  445. (*it)->SetSkin( skin, true);
  446. }
  447. }
  448. }
  449. void Base::OnSkinChanged( Skin::Base* /*skin*/ )
  450. {
  451. //Do something
  452. }
  453. bool Base::OnMouseWheeled( int iDelta )
  454. {
  455. if ( m_ActualParent )
  456. return m_ActualParent->OnMouseWheeled( iDelta );
  457. return false;
  458. }
  459. void Base::OnMouseMoved( int /*x*/, int /*y*/, int /*deltaX*/, int /*deltaY*/ )
  460. {
  461. }
  462. void Base::OnMouseEnter()
  463. {
  464. onHoverEnter.Call( this );
  465. if ( GetToolTip() )
  466. ToolTip::Enable( this );
  467. else if ( GetParent() && GetParent()->GetToolTip() )
  468. ToolTip::Enable( GetParent() );
  469. }
  470. void Base::OnMouseLeave()
  471. {
  472. onHoverLeave.Call( this );
  473. if ( GetToolTip() )
  474. ToolTip::Disable( this );
  475. }
  476. bool Base::IsHovered()
  477. {
  478. return Gwen::HoveredControl == this;
  479. }
  480. bool Base::ShouldDrawHover()
  481. {
  482. return Gwen::MouseFocus == this || Gwen::MouseFocus == NULL;
  483. }
  484. bool Base::HasFocus()
  485. {
  486. return Gwen::KeyboardFocus == this;
  487. }
  488. void Base::Focus()
  489. {
  490. if ( Gwen::KeyboardFocus == this ) return;
  491. if ( Gwen::KeyboardFocus )
  492. Gwen::KeyboardFocus->OnLostKeyboardFocus();
  493. Gwen::KeyboardFocus = this;
  494. OnKeyboardFocus();
  495. Redraw();
  496. }
  497. void Base::Blur()
  498. {
  499. if ( Gwen::KeyboardFocus != this ) return;
  500. Gwen::KeyboardFocus = NULL;
  501. OnLostKeyboardFocus();
  502. Redraw();
  503. }
  504. bool Base::IsOnTop()
  505. {
  506. Base::List::iterator iter = GetParent()->Children.begin();
  507. Base* pChild = *iter;
  508. if ( pChild == this )
  509. return true;
  510. return false;
  511. }
  512. void Base::Touch()
  513. {
  514. if ( GetParent() )
  515. GetParent()->OnChildTouched( this );
  516. }
  517. void Base::OnChildTouched( Controls::Base* /*pChild*/ )
  518. {
  519. Touch();
  520. }
  521. Base* Base::GetControlAt( int x, int y )
  522. {
  523. if ( Hidden() )
  524. return NULL;
  525. if ( x < 0 || y < 0 || x >= Width() || y >= Height() )
  526. return NULL;
  527. Base::List::reverse_iterator iter;
  528. for (iter = Children.rbegin(); iter != Children.rend(); ++iter)
  529. {
  530. Base* pChild = *iter;
  531. Base* pFound = NULL;
  532. pFound = pChild->GetControlAt( x - pChild->X(), y - pChild->Y() );
  533. if ( pFound ) return pFound;
  534. }
  535. if ( !GetMouseInputEnabled() )
  536. return NULL;
  537. return this;
  538. }
  539. void Base::Layout( Skin::Base* skin )
  540. {
  541. if ( skin->GetRender()->GetCTT() && ShouldCacheToTexture() )
  542. skin->GetRender()->GetCTT()->CreateControlCacheTexture( this );
  543. }
  544. int avoidUpdate = -15;
  545. void Base::RecurseLayout( Skin::Base* skin )
  546. {
  547. if ( m_Skin ) skin = m_Skin;
  548. if ( Hidden() ) return;
  549. if ( NeedsLayout() )
  550. {
  551. m_bNeedsLayout = false;
  552. Layout( skin );
  553. }
  554. if (avoidUpdate>0)
  555. return;
  556. Gwen::Rect rBounds = GetRenderBounds();
  557. // Adjust bounds for padding
  558. rBounds.x += m_Padding.left;
  559. rBounds.w -= m_Padding.left + m_Padding.right;
  560. rBounds.y += m_Padding.top;
  561. rBounds.h -= m_Padding.top + m_Padding.bottom;
  562. int sz = Children.size();
  563. if (sz>100)
  564. {
  565. // printf("!\n");
  566. }
  567. int curChild = 0;
  568. for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
  569. {
  570. Base* pChild = *iter;
  571. curChild++;
  572. if ( pChild->Hidden() )
  573. continue;
  574. int iDock = pChild->GetDock();
  575. if ( iDock & Pos::Fill )
  576. continue;
  577. if ( iDock & Pos::Top )
  578. {
  579. const Margin& margin = pChild->GetMargin();
  580. pChild->SetBounds( rBounds.x + margin.left, rBounds.y + margin.top, rBounds.w - margin.left - margin.right, pChild->Height() );
  581. int iHeight = margin.top + margin.bottom + pChild->Height();
  582. rBounds.y += iHeight;
  583. rBounds.h -= iHeight;
  584. }
  585. if ( iDock & Pos::Left )
  586. {
  587. const Margin& margin = pChild->GetMargin();
  588. pChild->SetBounds( rBounds.x + margin.left, rBounds.y + margin.top, pChild->Width(), rBounds.h - margin.top - margin.bottom );
  589. int iWidth = margin.left + margin.right + pChild->Width();
  590. rBounds.x += iWidth;
  591. rBounds.w -= iWidth;
  592. }
  593. if ( iDock & Pos::Right )
  594. {
  595. // TODO: THIS MARGIN CODE MIGHT NOT BE FULLY FUNCTIONAL
  596. const Margin& margin = pChild->GetMargin();
  597. pChild->SetBounds( (rBounds.x+rBounds.w)-pChild->Width()-margin.right, rBounds.y + margin.top, pChild->Width(), rBounds.h - margin.top - margin.bottom );
  598. int iWidth = margin.left + margin.right + pChild->Width();
  599. rBounds.w -= iWidth;
  600. }
  601. if ( iDock & Pos::Bottom )
  602. {
  603. // TODO: THIS MARGIN CODE MIGHT NOT BE FULLY FUNCTIONAL
  604. const Margin& margin = pChild->GetMargin();
  605. pChild->SetBounds( rBounds.x + margin.left, (rBounds.y+rBounds.h)-pChild->Height()-margin.bottom, rBounds.w - margin.left - margin.right, pChild->Height() );
  606. rBounds.h -= pChild->Height() + margin.bottom + margin.top;
  607. }
  608. pChild->RecurseLayout( skin );
  609. }
  610. m_InnerBounds = rBounds;
  611. curChild = 0;
  612. //
  613. // Fill uses the left over space, so do that now.
  614. //
  615. for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
  616. {
  617. Base* pChild = *iter;
  618. int iDock = pChild->GetDock();
  619. curChild++;
  620. if ( !(iDock & Pos::Fill) )
  621. continue;
  622. const Margin& margin = pChild->GetMargin();
  623. pChild->SetBounds( rBounds.x + margin.left, rBounds.y + margin.top, rBounds.w - margin.left - margin.right, rBounds.h - margin.top - margin.bottom );
  624. pChild->RecurseLayout( skin );
  625. }
  626. PostLayout( skin );
  627. if ( IsTabable() )
  628. {
  629. if ( !GetCanvas()->FirstTab ) GetCanvas()->FirstTab = this;
  630. if ( !GetCanvas()->NextTab ) GetCanvas()->NextTab = this;
  631. }
  632. if ( Gwen::KeyboardFocus == this )
  633. {
  634. GetCanvas()->NextTab = NULL;
  635. }
  636. }
  637. bool Base::IsChild( Controls::Base* pChild )
  638. {
  639. for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
  640. {
  641. if ( pChild == (*iter) ) return true;
  642. }
  643. return false;
  644. }
  645. Gwen::Point Base::LocalPosToCanvas( const Gwen::Point& pnt )
  646. {
  647. if ( m_Parent )
  648. {
  649. int x = pnt.x + X();
  650. int y = pnt.y + Y();
  651. // If our parent has an innerpanel and we're a child of it
  652. // add its offset onto us.
  653. //
  654. if ( m_Parent->m_InnerPanel && m_Parent->m_InnerPanel->IsChild( this ) )
  655. {
  656. x += m_Parent->m_InnerPanel->X();
  657. y += m_Parent->m_InnerPanel->Y();
  658. }
  659. return m_Parent->LocalPosToCanvas( Gwen::Point( x, y ) );
  660. }
  661. return pnt;
  662. }
  663. Gwen::Point Base::CanvasPosToLocal( const Gwen::Point& pnt )
  664. {
  665. if ( m_Parent )
  666. {
  667. int x = pnt.x - X();
  668. int y = pnt.y - Y();
  669. // If our parent has an innerpanel and we're a child of it
  670. // add its offset onto us.
  671. //
  672. if ( m_Parent->m_InnerPanel && m_Parent->m_InnerPanel->IsChild( this ) )
  673. {
  674. x -= m_Parent->m_InnerPanel->X();
  675. y -= m_Parent->m_InnerPanel->Y();
  676. }
  677. return m_Parent->CanvasPosToLocal( Gwen::Point( x, y ) );
  678. }
  679. return pnt;
  680. }
  681. bool Base::IsMenuComponent()
  682. {
  683. if ( !m_Parent ) return false;
  684. return m_Parent->IsMenuComponent();
  685. }
  686. void Base::CloseMenus()
  687. {
  688. for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
  689. {
  690. (*it)->CloseMenus();
  691. }
  692. }
  693. void Base::UpdateRenderBounds()
  694. {
  695. m_RenderBounds.x = 0;
  696. m_RenderBounds.x = 0;
  697. m_RenderBounds.w = m_Bounds.w;
  698. m_RenderBounds.h = m_Bounds.h;
  699. }
  700. void Base::UpdateCursor()
  701. {
  702. Platform::SetCursor( m_Cursor );
  703. }
  704. DragAndDrop::Package* Base::DragAndDrop_GetPackage( int /*x*/, int /*y*/ )
  705. {
  706. return m_DragAndDrop_Package;
  707. }
  708. bool Base::DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/ )
  709. {
  710. DragAndDrop::SourceControl->SetParent( this );
  711. return true;
  712. }
  713. bool Base::DragAndDrop_Draggable()
  714. {
  715. if ( !m_DragAndDrop_Package ) return false;
  716. return m_DragAndDrop_Package->draggable;
  717. }
  718. void Base::DragAndDrop_SetPackage( bool bDraggable, const String& strName, void* pUserData )
  719. {
  720. if ( !m_DragAndDrop_Package )
  721. {
  722. m_DragAndDrop_Package = new Gwen::DragAndDrop::Package();
  723. }
  724. m_DragAndDrop_Package->draggable = bDraggable;
  725. m_DragAndDrop_Package->name = strName;
  726. m_DragAndDrop_Package->userdata = pUserData;
  727. }
  728. void Base::DragAndDrop_StartDragging( Gwen::DragAndDrop::Package* pPackage, int x, int y )
  729. {
  730. pPackage->holdoffset = CanvasPosToLocal( Gwen::Point( x, y ) );
  731. pPackage->drawcontrol = this;
  732. }
  733. bool Base::SizeToChildren( bool w, bool h )
  734. {
  735. Gwen::Point size = ChildrenSize();
  736. return SetSize( w ? size.x : Width(), h ? size.y : Height() );
  737. }
  738. Gwen::Point Base::ChildrenSize()
  739. {
  740. Gwen::Point size;
  741. for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
  742. {
  743. Base* pChild = *iter;
  744. if ( pChild->Hidden() ) continue;
  745. size.x = GwenUtil_Max( size.x, pChild->Right() );
  746. size.y = GwenUtil_Max( size.y, pChild->Bottom() );
  747. }
  748. return size;
  749. }
  750. void Base::SetPadding( const Padding& padding )
  751. {
  752. if ( m_Padding.left == padding.left &&
  753. m_Padding.top == padding.top &&
  754. m_Padding.right == padding.right &&
  755. m_Padding.bottom == padding.bottom )
  756. return;
  757. m_Padding = padding;
  758. Invalidate();
  759. InvalidateParent();
  760. }
  761. void Base::SetMargin( const Margin& margin )
  762. {
  763. if ( m_Margin.top == margin.top &&
  764. m_Margin.left == margin.left &&
  765. m_Margin.bottom == margin.bottom &&
  766. m_Margin.right == margin.right )
  767. return;
  768. m_Margin = margin;
  769. Invalidate();
  770. InvalidateParent();
  771. }
  772. bool Base::HandleAccelerator( Gwen::UnicodeString& accelerator )
  773. {
  774. if ( Gwen::KeyboardFocus == this || !AccelOnlyFocus() )
  775. {
  776. AccelMap::iterator iter = m_Accelerators.find( accelerator );
  777. if ( iter != m_Accelerators.end() )
  778. {
  779. iter->second->Call( this );
  780. return true;
  781. }
  782. }
  783. for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
  784. {
  785. if ( (*it)->HandleAccelerator( accelerator ) )
  786. return true;
  787. }
  788. return false;
  789. }
  790. bool Base::OnKeyPress( int iKey, bool bPress )
  791. {
  792. bool bHandled = false;
  793. switch ( iKey )
  794. {
  795. case Key::Tab: bHandled = OnKeyTab( bPress ); break;
  796. case Key::Space: bHandled = OnKeySpace( bPress ); break;
  797. case Key::Home: bHandled = OnKeyHome( bPress ); break;
  798. case Key::End: bHandled = OnKeyEnd( bPress ); break;
  799. case Key::Return: bHandled = OnKeyReturn( bPress ); break;
  800. case Key::Backspace: bHandled = OnKeyBackspace( bPress ); break;
  801. case Key::Delete: bHandled = OnKeyDelete( bPress ); break;
  802. case Key::Right: bHandled = OnKeyRight( bPress ); break;
  803. case Key::Left: bHandled = OnKeyLeft( bPress ); break;
  804. case Key::Up: bHandled = OnKeyUp( bPress ); break;
  805. case Key::Down: bHandled = OnKeyDown( bPress ); break;
  806. case Key::Escape: bHandled = OnKeyEscape( bPress ); break;
  807. default: break;
  808. }
  809. if ( !bHandled && GetParent() )
  810. GetParent()->OnKeyPress( iKey, bPress );
  811. return bHandled;
  812. }
  813. bool Base::OnKeyRelease( int iKey )
  814. {
  815. return OnKeyPress( iKey, false );
  816. }
  817. bool Base::OnKeyTab( bool bDown )
  818. {
  819. if ( !bDown ) return true;
  820. if ( GetCanvas()->NextTab )
  821. {
  822. GetCanvas()->NextTab->Focus();
  823. Redraw();
  824. }
  825. return true;
  826. }
  827. void Base::RenderFocus( Gwen::Skin::Base* skin )
  828. {
  829. if ( Gwen::KeyboardFocus != this ) return;
  830. if ( !IsTabable() ) return;
  831. skin->DrawKeyboardHighlight( this, GetRenderBounds(), 3 );
  832. }
  833. void Base::SetToolTip( const String& strText )
  834. {
  835. SetToolTip( Gwen::Utility::StringToUnicode( strText ) );
  836. }
  837. void Base::SetToolTip( const UnicodeString& strText )
  838. {
  839. Label* tooltip = new Label( this );
  840. tooltip->SetText( strText );
  841. tooltip->SizeToContents();
  842. SetToolTip( tooltip );
  843. }
  844. #ifndef GWEN_NO_ANIMATION
  845. void Base::Anim_WidthIn( float fLength, float fDelay, float fEase )
  846. {
  847. Gwen::Anim::Add( this, new Gwen::Anim::Size::Width( 0, Width(), fLength, false, fDelay, fEase ) );
  848. SetWidth( 0 );
  849. }
  850. void Base::Anim_HeightIn( float fLength, float fDelay, float fEase )
  851. {
  852. Gwen::Anim::Add( this, new Gwen::Anim::Size::Height( 0, Height(), fLength, false, fDelay, fEase ) );
  853. SetHeight( 0 );
  854. }
  855. void Base::Anim_WidthOut( float fLength, bool bHide, float fDelay, float fEase )
  856. {
  857. Gwen::Anim::Add( this, new Gwen::Anim::Size::Width( Width(), 0, fLength, bHide, fDelay, fEase ) );
  858. }
  859. void Base::Anim_HeightOut( float fLength, bool bHide, float fDelay, float fEase )
  860. {
  861. Gwen::Anim::Add( this, new Gwen::Anim::Size::Height( Height(), 0, fLength, bHide, fDelay, fEase ) );
  862. }
  863. #endif