BaseGUIElement.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. #include "BaseGUIElement.h"
  2. #include "BaseGUICursor.h"
  3. MOP_BEGINLIST(GUIFocusHolder, "", '1.00', 0)
  4. MOP_ENDLIST(GUIFocusHolder)
  5. #include "../utils/InterfaceUtils.h"
  6. BaseGUIElement:: BaseGUIElement(void) : m_children(_FL_)
  7. {
  8. m_parent.Reset();
  9. m_focusHolder.Reset();
  10. nativeShow = false; drawLevel = ML_GUI2;
  11. m_clipping = false;
  12. m_scale = -1.0f; // по умолчанию скейл не используется
  13. m_offsetX = 0.0f;
  14. m_offsetY = 0.0f;
  15. m_isLooped = false;
  16. //// дефолтные значения, должны переопределяться ////
  17. m_aspect = 1.0f;
  18. m_aspect_native = 1.0f;
  19. m_natPos.x = 0.0f;
  20. m_natPos.y = 0.0f;
  21. m_natSize.w = 0.0f;
  22. m_natSize.h = 0.0f;
  23. m_natLay = OnLeft;
  24. /////////////////////////////////////////////////////
  25. m_shiftAspect = true;
  26. m_widthAspect = true;
  27. m_widthAspectKoef = 1.0f;
  28. m_layout = OnCenter;
  29. m_restricts = preserveNone;
  30. m_fadeState = FadingFinished;
  31. /////
  32. memset(&m_params, 0, sizeof(m_params));
  33. m_params.parent.Empty();
  34. m_baseCursor = null;
  35. data_a = -1;
  36. data_b = -1;
  37. }
  38. BaseGUIElement::~BaseGUIElement(void)
  39. {
  40. NotifyChildren(ParentDeleted);
  41. if( m_focusHolder.Validate() && ((GUIFocusHolder *)m_focusHolder.Ptr())->GetFocused() == this )
  42. SetElementInFocus(null);
  43. if( BaseGUIElement *p = GetParent())
  44. p->UnRegister(this);
  45. }
  46. void BaseGUIElement::InitAspect(void)
  47. {
  48. // все элементы создаются из расчета этого аспекта
  49. const float def_aspect = 16.0f/9.0f;
  50. float cx;
  51. float cy;
  52. if( EditMode_IsOn())
  53. {
  54. // cx = (float)Render().GetViewport().Width;
  55. // cy = (float)Render().GetViewport().Height;
  56. cx = (float)Render().GetFullScreenViewPort_2D().Width;
  57. cy = (float)Render().GetFullScreenViewPort_2D().Height;
  58. }
  59. else
  60. {
  61. cx = (float)Render().GetFullScreenViewPort_2D().Width;
  62. cy = (float)Render().GetFullScreenViewPort_2D().Height;
  63. }
  64. // аспект разрешения экрана
  65. float scr_aspect = cx/cy;
  66. // api->Trace("");
  67. // api->Trace(" WINDOW: asp = %f res = %.0fx%.0f",scr_aspect,cx,cy);
  68. // аспект пикселя
  69. float dot_aspect = InterfaceUtils::AspectRatio(Render());
  70. // api->Trace(" DOT: asp = %f",dot_aspect);
  71. // api->Trace("");
  72. // реальный аспект
  73. float cur_aspect = scr_aspect/dot_aspect;
  74. m_aspect = def_aspect/cur_aspect;
  75. m_aspect_native = cur_aspect;
  76. }
  77. void BaseGUIElement::SkipMOPs(MOPReader &reader)
  78. {
  79. reader.Enum(); // layout
  80. reader.Float(); // x
  81. reader.Float(); // y
  82. m_params.alpha = reader.Float();
  83. reader.String().c_str(); // parent name
  84. }
  85. void BaseGUIElement::ReadMOPs(MOPReader &reader)
  86. {
  87. m_parent.Reset();
  88. InitAspect();
  89. // bool shift = reader.Bool();
  90. bool shift = true;
  91. // bool width = reader.Bool();
  92. bool width = true;
  93. Layout layout;
  94. switch( reader.Enum().c_str()[0] )
  95. {
  96. case 'C':
  97. layout = OnCenter;
  98. break;
  99. case 'L':
  100. layout = OnLeft;
  101. break;
  102. case 'R':
  103. layout = OnRight;
  104. break;
  105. };
  106. if( !Restricted(preserveLayout))
  107. {
  108. m_shiftAspect = shift;
  109. m_widthAspect = width;
  110. m_layout = layout;
  111. }
  112. m_natLay = layout;
  113. float x = reader.Float();
  114. float y = reader.Float();
  115. if( !Restricted(preservePos))
  116. {
  117. m_params.x = x;
  118. m_params.y = y;
  119. }
  120. m_natPos.x = x;
  121. m_natPos.y = y;
  122. m_params.alpha = reader.Float();
  123. ConstString s = reader.String();
  124. if( !Restricted(preserveParent))
  125. m_params.parent = s;
  126. m_offsetX = 0.0f;
  127. m_offsetY = 0.0f;
  128. data_a = -1;
  129. data_b = -1;
  130. }
  131. bool BaseGUIElement::Create (MOPReader &reader)
  132. {
  133. ReadMOPs(reader);
  134. return true;
  135. }
  136. bool BaseGUIElement::EditMode_Update(MOPReader &reader)
  137. {
  138. ReadMOPs(reader);
  139. return true;
  140. }
  141. void BaseGUIElement::PostCreate()
  142. {
  143. MOSafePointer sp;
  144. FindObject(InterfaceUtils::GetCursorName(),sp);
  145. m_baseCursor = (BaseGUICursor *)sp.Ptr();
  146. }
  147. BaseGUIElement *BaseGUIElement::FindParent()
  148. {
  149. if( FindObject(m_params.parent,m_parent))
  150. {
  151. if( !m_parent.Ptr()->Is(InterfaceUtils::GetBaseId()))
  152. m_parent.Reset();
  153. }
  154. return (BaseGUIElement *)m_parent.Ptr();
  155. }
  156. /*
  157. void BaseGUIElement::GetRect(Rect &rect, bool useOffset) const
  158. {
  159. float parent_w = 100.0f;
  160. if( m_parent )
  161. {
  162. m_parent->GetRect(rect,useOffset); parent_w = m_parent->GetWidth();
  163. }
  164. else
  165. {
  166. rect.l = 0.0f; rect.r = 100.0f;
  167. rect.t = 0.0f; rect.b = 100.0f;
  168. }
  169. float width = rect.r - rect.l;
  170. float x = m_params.x;
  171. float y = m_params.y;
  172. if( useOffset )
  173. {
  174. x += GetOffsetX();
  175. y += GetOffsetY();
  176. }
  177. float w = m_params.w;
  178. float h = m_params.h;
  179. if( m_widthAspect )
  180. {
  181. w /= m_aspect;
  182. switch( m_layout )
  183. {
  184. case OnCenter:
  185. x = x + 0.5f*(m_params.w - w);
  186. x += rect.l;
  187. break;
  188. case OnLeft:
  189. if( m_shiftAspect )
  190. x /= m_aspect;
  191. x += rect.l;
  192. break;
  193. case OnRight:
  194. x = parent_w - (x + m_params.w);
  195. if( m_shiftAspect )
  196. x = rect.r - x/m_aspect;
  197. else
  198. x = rect.r - x;
  199. x -= w;
  200. break;
  201. }
  202. }
  203. else
  204. {
  205. if( m_shiftAspect )
  206. {
  207. switch( m_layout )
  208. {
  209. case OnCenter:
  210. x /= m_aspect;
  211. // w = parent_w - (parent_w - w)/m_aspect;
  212. w = width - (parent_w - w)/m_aspect;
  213. x += rect.l;
  214. break;
  215. case OnLeft:
  216. w = x + w - x/m_aspect;
  217. x /= m_aspect;
  218. x += rect.l;
  219. break;
  220. case OnRight:
  221. w = parent_w - (parent_w - (x + w))/m_aspect - x;
  222. x = rect.r - (parent_w - (x + m_params.w))/m_aspect - w;
  223. break;
  224. }
  225. }
  226. else
  227. {
  228. x += rect.l;
  229. }
  230. }
  231. rect.l = x;
  232. rect.t += y;
  233. rect.r = rect.l + w;
  234. rect.b = rect.t + h;
  235. }
  236. */
  237. void BaseGUIElement::GetRect(Rect &rect, bool useOffset)// const
  238. {
  239. if( EditMode_IsOn())
  240. ValidateParent();
  241. float px = 0.0f;
  242. float py = 0.0f;
  243. BaseGUIElement *parent = (BaseGUIElement *)m_parent.Ptr();
  244. if( parent )
  245. {
  246. parent->GetRect(rect,useOffset);
  247. // parent->GetRect(rect);
  248. px = rect.l;
  249. py = rect.t;
  250. }
  251. else
  252. {
  253. rect.l = 0.0f; rect.r = 100.0f;
  254. rect.t = 0.0f; rect.b = 100.0f;
  255. }
  256. /* float x = m_params.x*m_aspect;
  257. float y = m_params.y;*/
  258. float x;
  259. float y;
  260. GetPosition(x,y);
  261. x *= 100.0f*m_aspect*m_widthAspectKoef;
  262. y *= 100.0f;
  263. if( useOffset )
  264. {
  265. x += GetOffsetX();
  266. y += GetOffsetY();
  267. }
  268. float w = m_params.w*m_aspect*m_widthAspectKoef;
  269. float h = m_params.h;
  270. if( parent )
  271. {
  272. float scale = parent->m_scale;
  273. // if( scale != 1.0f )
  274. if( scale >= 0.0f )
  275. {
  276. x *= scale; w *= scale;
  277. y *= scale; h *= scale;
  278. SetFontScale(scale);
  279. }
  280. }
  281. float center = (rect.l + rect.r)*0.5f;
  282. switch( m_layout )
  283. {
  284. case OnLeft:
  285. x = rect.l + x;
  286. break;
  287. case OnCenter:
  288. x = center + x - w*0.5f;
  289. break;
  290. case OnRight:
  291. x = rect.r - x - w;
  292. break;
  293. }
  294. rect.l = x;
  295. rect.t += y;
  296. rect.r = rect.l + w;
  297. rect.b = rect.t + h;
  298. if( parent && parent->m_isLooped )
  299. {
  300. float ox = x - px;
  301. float oy = y;
  302. Rect rt; parent->GetPanelRect(rt);
  303. float cntx = 0.5f*(rt.l + rt.r);
  304. float cnty = 0.5f*(rt.t + rt.b);
  305. if( rect.l > cntx )
  306. {
  307. float l = rect.r - parent->GetFullW();
  308. if( rect.l - cntx > cntx - l )
  309. {
  310. rect.r = l; rect.l = rect.r - w;
  311. }
  312. }
  313. else
  314. if( rect.r < cntx )
  315. {
  316. float r = rect.l + parent->GetFullW();
  317. if( cntx - rect.r > r - cntx )
  318. {
  319. rect.l = r; rect.r = rect.l + w;
  320. }
  321. }
  322. if( rect.t > cnty )
  323. {
  324. float t = rect.b - parent->GetFullH();
  325. if( rect.t - cnty > cnty - t )
  326. {
  327. rect.b = t; rect.t = rect.b - h;
  328. }
  329. }
  330. else
  331. if( rect.b < cnty )
  332. {
  333. float b = rect.t + parent->GetFullH();
  334. if( cnty - rect.b > b - cnty )
  335. {
  336. rect.t = b; rect.b = rect.t + h;
  337. }
  338. }
  339. }
  340. }
  341. void BaseGUIElement::GetParentRect(Rect &rect, bool useOffset)// const
  342. {
  343. BaseGUIElement *p = (BaseGUIElement *)m_parent.Ptr();
  344. if( p )
  345. p->GetRect(rect,useOffset);
  346. else
  347. {
  348. rect.l = 0.0f; rect.r = 100.0f;
  349. rect.t = 0.0f; rect.b = 100.0f;
  350. }
  351. }
  352. void BaseGUIElement::GetPanelRect(Rect &rect)
  353. {
  354. if( EditMode_IsOn())
  355. ValidateParent();
  356. BaseGUIElement *p = (BaseGUIElement *)m_parent.Ptr();
  357. if( p )
  358. {
  359. // p->GetRect(rect,useOffset);
  360. p->GetRect(rect);
  361. }
  362. else
  363. {
  364. rect.l = 0.0f; rect.r = 100.0f;
  365. rect.t = 0.0f; rect.b = 100.0f;
  366. }
  367. float x = m_params.x*m_aspect;
  368. float y = m_params.y;
  369. /* if( useOffset )
  370. {
  371. x += GetOffsetX();
  372. y += GetOffsetY();
  373. }*/
  374. float w = m_params.w*m_aspect;
  375. float h = m_params.h;
  376. float center = (rect.l + rect.r)*0.5f;
  377. switch( m_layout )
  378. {
  379. case OnLeft:
  380. x = rect.l + x;
  381. break;
  382. case OnCenter:
  383. x = center + x - w*0.5f;
  384. break;
  385. case OnRight:
  386. x = rect.r - x - w;
  387. break;
  388. }
  389. rect.l = x;
  390. rect.t += y;
  391. rect.r = rect.l + w;
  392. rect.b = rect.t + h;
  393. }
  394. void BaseGUIElement::OnParentNotify(Notification event)
  395. {
  396. switch( event )
  397. {
  398. case ParentShowed:
  399. Show(nativeShow);
  400. break;
  401. case ParentHided:
  402. {
  403. bool show = nativeShow;
  404. Show(false);
  405. nativeShow = show;
  406. } break;
  407. case ParentDeleted:
  408. if( BaseGUIElement *p = GetParent())
  409. {
  410. p->UnRegister(this);
  411. m_parent.Reset();
  412. }
  413. break;
  414. case SilentShow:
  415. // if( GetNativeAlpha() > 0.0f )
  416. if( IsShow())
  417. {
  418. SetDrawUpdate();
  419. NotifyChildren(SilentShow);
  420. }
  421. break;
  422. case SilentHide:
  423. // if( GetNativeAlpha() > 0.0f )
  424. if( IsShow())
  425. {
  426. DelDrawUpdate();
  427. NotifyChildren(SilentHide);
  428. }
  429. break;
  430. }
  431. }
  432. void BaseGUIElement::NotifyChildren(Notification event)
  433. {
  434. for( dword i = 0; i < m_children.Size() ; i++ )
  435. {
  436. if( m_children[i].object.Validate())
  437. ((BaseGUIElement *)m_children[i].object.Ptr())->OnParentNotify(event);
  438. }
  439. }
  440. void BaseGUIElement::NotifyParent(BaseGUIElement *p, ChildNotification event)
  441. {
  442. BaseGUIElement *parent = (BaseGUIElement *)m_parent.Ptr();
  443. if( parent )
  444. parent->OnChildNotify(p,event);
  445. }
  446. void BaseGUIElement::Show(bool isShow)
  447. {
  448. bool prevShow = IsShow();
  449. if( isShow )
  450. {
  451. LogicDebug("Show");
  452. }
  453. else
  454. {
  455. LogicDebug("Hide");
  456. }
  457. nativeShow = isShow;
  458. if( nativeShow )
  459. {
  460. const BaseGUIElement *parent = FindParent();
  461. bool parentVisible = true;
  462. if( parent )
  463. parentVisible = parent->IsShow();
  464. isShow = isShow && parentVisible;
  465. if( isShow == false )
  466. {
  467. LogicDebug("Stay invisible: parent hided");
  468. }
  469. }
  470. MissionObject::Show(isShow);
  471. // for( dword i = 0 ; i < m_children.Size() ; i++ )
  472. // m_children[i].object->Show(isShow);
  473. // NotifyChildren(isShow ? ParentShowed : ParentHided);
  474. if( isShow )
  475. {
  476. if( !prevShow )
  477. NotifyChildren(ParentShowed);
  478. }
  479. else
  480. {
  481. if( prevShow )
  482. NotifyChildren(ParentHided);
  483. }
  484. }
  485. void BaseGUIElement::Activate(bool isActive)
  486. {
  487. if( isActive )
  488. {
  489. LogicDebug("Activate");
  490. }
  491. else
  492. {
  493. LogicDebug("Deactivate");
  494. }
  495. MissionObject::Activate(isActive);
  496. for( int i = 0 ; i < m_children ; i++ )
  497. {
  498. ((BaseGUIElement *)m_children[i].object.Ptr())->Activate(isActive);
  499. }
  500. }
  501. float BaseGUIElement::GetAlpha()
  502. {
  503. float alpha = m_params.alpha;
  504. if( BaseGUIElement *p = GetParent())
  505. alpha *= p->GetAlpha();
  506. return alpha;
  507. }
  508. bool BaseGUIElement::ParentIsActive()
  509. {
  510. if( BaseGUIElement *p = GetParent())
  511. {
  512. if( !p->IsActive())
  513. return false;
  514. else
  515. return p->ParentIsActive();
  516. }
  517. return true;
  518. }
  519. void BaseGUIElement::SetElementInFocus(BaseGUIElement *p)
  520. {
  521. GetFocusHolder()->SetFocused(p);
  522. }
  523. BaseGUIElement *BaseGUIElement::GetElementInFocus()
  524. {
  525. return GetFocusHolder()->GetFocused();
  526. }
  527. GUIFocusHolder *BaseGUIElement::GetFocusHolder()
  528. {
  529. GUIFocusHolder *holder = (GUIFocusHolder *)m_focusHolder.Ptr();
  530. if( !holder )
  531. {
  532. static const ConstString objName("GUIFocusHolder");
  533. Mission().CreateObject(m_focusHolder,"GUIFocusHolder",objName);
  534. holder = (GUIFocusHolder *)m_focusHolder.Ptr();
  535. Assert(holder)
  536. }
  537. return holder;
  538. }
  539. void BaseGUIElement:: Register(BaseGUIElement* object)
  540. {
  541. Assert(object)
  542. if( object != this )
  543. {
  544. for( int i = 0 ; i < m_children ; i++ )
  545. if( m_children[i].object.Ptr() == object )
  546. break;
  547. if( i >= m_children )
  548. {
  549. m_children.Add(object);
  550. }
  551. }
  552. }
  553. void BaseGUIElement::UnRegister(BaseGUIElement* object)
  554. {
  555. Assert(object)
  556. // m_children.Del(object);
  557. for( int i = 0 ; i < m_children ; i++ )
  558. {
  559. if(((BaseGUIElement *)m_children[i].object.Ptr()) == object )
  560. {
  561. m_children.DelIndex(i); break;
  562. }
  563. }
  564. }
  565. void BaseGUIElement::SetParent(const ConstString & parent)
  566. {
  567. BaseGUIElement *oldParent = GetParent();
  568. m_params.parent = parent;
  569. BaseGUIElement *newParent = FindParent();
  570. if( newParent != oldParent )
  571. {
  572. if( oldParent )
  573. oldParent->UnRegister(this);
  574. if( newParent )
  575. newParent-> Register(this);
  576. }
  577. }
  578. float BaseGUIElement::GetX(bool useOffset)// const
  579. {
  580. Rect r; GetRect(r,useOffset);
  581. return r.l;
  582. }
  583. float BaseGUIElement::GetY(bool useOffset)// const
  584. {
  585. Rect r; GetRect(r,useOffset);
  586. return r.t;
  587. }
  588. static LONG round(float x)
  589. {
  590. float f = floorf(x);
  591. if( x - f > 0.5f )
  592. return LONG(f + 1.0f);
  593. else
  594. return LONG(f);
  595. }
  596. /*
  597. void BaseGUIElement::SetClipRect(Rect *r)
  598. {
  599. if( !r )
  600. {
  601. Render().SetStateHack(SH_SCISSORRECT,0);
  602. return;
  603. }
  604. IRender* render = (IRender*)api->GetService("DX9Render");
  605. Assert(render);
  606. const RENDERVIEWPORT vp = render->GetViewport();
  607. RECT rect;
  608. rect.left = vp.X + round(r->l*0.01f*vp.Width );
  609. rect.top = vp.Y + round(r->t*0.01f*vp.Height);
  610. rect.right = vp.X + round(r->r*0.01f*vp.Width );
  611. rect.bottom = vp.Y + round(r->b*0.01f*vp.Height);
  612. Render().SetStateHack(SH_SCISSORRECT,1);
  613. Render().SetScissorRect(&rect);
  614. }
  615. */
  616. void BaseGUIElement::SetClipRect(Rect *r)
  617. {
  618. IRender* render = (IRender*)api->GetService("DX9Render");
  619. Assert(render);
  620. const RENDERVIEWPORT vp = render->GetViewport();
  621. RECT rect;
  622. if( !r )
  623. {
  624. rect.left = vp.X;
  625. rect.top = vp.Y;
  626. rect.right = vp.X + vp.Width;
  627. rect.bottom = vp.Y + vp.Height;
  628. Render().SetScissorRect(&rect);
  629. // Render().SetStateHack(SH_SCISSORRECT, 0);
  630. Render().SetStateHack(SH_SCISSORRECT,-1);
  631. return;
  632. }
  633. rect.left = vp.X + round(r->l*0.01f*vp.Width );
  634. rect.top = vp.Y + round(r->t*0.01f*vp.Height);
  635. rect.right = vp.X + round(r->r*0.01f*vp.Width );
  636. rect.bottom = vp.Y + round(r->b*0.01f*vp.Height);
  637. Render().SetStateHack(SH_SCISSORRECT,1);
  638. Render().SetScissorRect(&rect);
  639. }
  640. /*
  641. void BaseGUIElement::GetClipRect(Rect &rect)
  642. {
  643. if( m_parent && ValidatePointer(m_parent,m_parentHash))
  644. m_parent->GetClipRect(rect);
  645. else
  646. {
  647. rect.l = 0.0f; rect.r = 100.0f;
  648. rect.t = 0.0f; rect.b = 100.0f;
  649. }
  650. if( m_clipping )
  651. {
  652. float pw = m_params.w;
  653. float ph = m_params.h;
  654. float px = m_params.x;
  655. float py = m_params.y;
  656. px = px + 0.5f*pw*(1.0f - 1.0f/m_aspect);
  657. float x = px;
  658. float y = py;
  659. float w = pw/m_aspect;
  660. float h = ph;
  661. if( x > 0 )
  662. rect.l += x;
  663. if( y > 0 )
  664. rect.t += y;
  665. float dx = rect.r - rect.l - w;
  666. float dy = rect.b - rect.t - h;
  667. if( dx > 0 )
  668. rect.r -= dx;
  669. if( dy > 0 )
  670. rect.b -= dy;
  671. }
  672. }
  673. */
  674. void BaseGUIElement::GetClipRect(Rect &rect)
  675. {
  676. if( BaseGUIElement *p = GetParent())
  677. p->GetClipRect(rect);
  678. else
  679. {
  680. rect.l = 0.0f; rect.r = 100.0f;
  681. rect.t = 0.0f; rect.b = 100.0f;
  682. }
  683. if( m_clipping )
  684. {
  685. Rect r; GetRect(r,false);
  686. if( rect.l < r.l )
  687. rect.l = r.l;
  688. if( rect.t < r.t )
  689. rect.t = r.t;
  690. /* float dx = rect.r - rect.l - (r.r - r.l);
  691. float dy = rect.b - rect.t - (r.b - r.t);
  692. if( dx > 0 )
  693. rect.r -= dx;
  694. if( dy > 0 )
  695. rect.b -= dy;*/
  696. if( rect.r > r.r )
  697. rect.r = r.r;
  698. if( rect.b > r.b )
  699. rect.b = r.b;
  700. if( rect.r < rect.l )
  701. rect.r = rect.l;
  702. if( rect.b < rect.t )
  703. rect.b = rect.t;
  704. }
  705. }
  706. void BaseGUIElement::GetParentClipRect(Rect &rect)
  707. {
  708. BaseGUIElement *parent = (BaseGUIElement *)m_parent.Ptr();
  709. if( parent )
  710. parent->GetClipRect(rect);
  711. else
  712. {
  713. rect.l = 0.0f; rect.r = 100.0f;
  714. rect.t = 0.0f; rect.b = 100.0f;
  715. }
  716. }
  717. bool BaseGUIElement::PointInRect(float x, float y, const Rect &r)
  718. {
  719. if( x < r.l ) return false;
  720. if( x > r.r ) return false;
  721. if( y < r.t ) return false;
  722. if( y > r.b ) return false;
  723. return true;
  724. }
  725. bool BaseGUIElement::RectInRect(
  726. float l1, float t1, float r1, float b1,
  727. float l2, float t2, float r2, float b2)
  728. {
  729. float rx1 = (r1 - l1)*0.5f;
  730. float ry1 = (b1 - t1)*0.5f;
  731. float rx2 = (r2 - l2)*0.5f;
  732. float ry2 = (b2 - t2)*0.5f;
  733. float dx = fabsf(l1 + rx1 - (l2 + rx2));
  734. float dy = fabsf(t1 + ry1 - (t2 + ry2));
  735. return dx <= rx1 + rx2 &&
  736. dy <= ry1 + ry2;
  737. }
  738. BaseGUIElement::Rect BaseGUIElement::GetFullRect()
  739. {
  740. Rect rect; GetRect(rect,false);
  741. float x = rect.l;
  742. float y = rect.t;
  743. rect.r -= rect.l; rect.l = 0.0f;
  744. rect.b -= rect.t; rect.t = 0.0f;
  745. for( int i = 0; i < m_children ; i++ )
  746. {
  747. if( m_children[i].object.Validate())
  748. {
  749. Rect r; ((BaseGUIElement *)m_children[i].object.Ptr())->GetRect(r,false);
  750. r.l -= x; r.r -= x;
  751. r.t -= y; r.b -= y;
  752. if( rect.l > r.l )
  753. rect.l = r.l;
  754. if( rect.t > r.t )
  755. rect.t = r.t;
  756. if( rect.r < r.r )
  757. rect.r = r.r;
  758. if( rect.b < r.b )
  759. rect.b = r.b;
  760. }
  761. }
  762. return rect;
  763. }
  764. void BaseGUIElement::ValidateParent()
  765. {
  766. if( !m_parent.Validate())
  767. {
  768. FindObject(m_params.parent,m_parent);
  769. }
  770. }
  771. void BaseGUIElement::Command(const char *id, dword numParams, const char **params)
  772. {
  773. if( string::IsEmpty(id))
  774. return;
  775. if( string::IsEqual(id,"setfxa"))
  776. {
  777. if( numParams < 1 )
  778. {
  779. LogicDebugError("Command BaseGUIElement::[setfxa] error. No alpha specified.");
  780. return;
  781. }
  782. bool visible = GetAlpha() > 0.0f;
  783. float alpha = (float)atof(params[0]);
  784. SetAlpha(alpha);
  785. if( alpha > 0.0f )
  786. {
  787. if( IsShow() && !visible )
  788. {
  789. SetDrawUpdate();
  790. NotifyChildren(SilentShow);
  791. }
  792. }
  793. else
  794. {
  795. if( IsShow() && visible )
  796. {
  797. DelDrawUpdate();
  798. NotifyChildren(SilentHide);
  799. }
  800. }
  801. }
  802. else
  803. if( string::IsEqual(id,"setcursor"))
  804. {
  805. /* if( m_baseCursor )
  806. {
  807. Rect r; GetRect(r);
  808. m_baseCursor->SetPosition(
  809. 0.5f*0.01f*(r.l + r.r),
  810. 0.5f*0.01f*(r.t + r.b));
  811. }*/
  812. SetCursor();
  813. }
  814. else
  815. if( string::IsEqual(id,"restart"))
  816. {
  817. Restart();
  818. }
  819. }
  820. void BaseGUIElement::SetCursor()
  821. {
  822. if( m_baseCursor )
  823. {
  824. Rect r; GetRect(r);
  825. m_baseCursor->SetPosition(
  826. 0.5f*0.01f*(r.l + r.r),
  827. 0.5f*0.01f*(r.t + r.b));
  828. }
  829. }