UIView.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. #include <TurboBadger/tb_core.h>
  2. #include <TurboBadger/tb_system.h>
  3. #include <TurboBadger/tb_debug.h>
  4. #include <TurboBadger/animation/tb_widget_animation.h>
  5. #include <TurboBadger/renderers/tb_renderer_batcher.h>
  6. #include <TurboBadger/tb_font_renderer.h>
  7. #include <TurboBadger/tb_node_tree.h>
  8. #include <TurboBadger/tb_widgets_reader.h>
  9. #include <TurboBadger/tb_window.h>
  10. void register_tbbf_font_renderer();
  11. void register_stb_font_renderer();
  12. void register_freetype_font_renderer();
  13. using namespace tb;
  14. #include "../Core/CoreEvents.h"
  15. #include "../Input/Input.h"
  16. #include "../Input/InputEvents.h"
  17. #include "../Resource/ResourceCache.h"
  18. #include "../Graphics/Graphics.h"
  19. #include "../Graphics/GraphicsEvents.h"
  20. #include "../Graphics/Texture2D.h"
  21. #include "../Graphics/VertexBuffer.h"
  22. #include "UIRenderer.h"
  23. #include "UIView.h"
  24. namespace Atomic
  25. {
  26. WeakPtr<Context> UIView::readerContext_;
  27. UIView::UIView(Context* context) :
  28. Object(context),
  29. rootWidget_(0),
  30. inputDisabled_(false),
  31. keyboardDisabled_(false)
  32. {
  33. Graphics* graphics = GetSubsystem<Graphics>();
  34. assert(graphics);
  35. assert(graphics->IsInitialized());
  36. graphics_ = graphics;
  37. vertexBuffer_ = new VertexBuffer(context_);
  38. }
  39. UIView::~UIView()
  40. {
  41. }
  42. // refactor
  43. void UIView::Initialize()
  44. {
  45. readerContext_ = context_;
  46. TBFile::SetReaderFunction(TBFileReader);
  47. TBWidgetsAnimationManager::Init();
  48. renderer_ = new UIRenderer(graphics_->GetContext());
  49. tb_core_init(renderer_, "AtomicEditor/resources/language/lng_en.tb.txt");
  50. // Load the default skin, and override skin that contains the graphics specific to the demo.
  51. tb::g_tb_skin->Load("AtomicEditor/resources/default_skin/skin.tb.txt", "AtomicEditor/editor/skin/skin.tb.txt");
  52. //register_tbbf_font_renderer();
  53. //register_stb_font_renderer();
  54. register_freetype_font_renderer();
  55. tb::g_font_manager->AddFontInfo("AtomicEditor/resources/MesloLGS-Regular.ttf", "Monaco");
  56. tb::g_font_manager->AddFontInfo("AtomicEditor/resources/vera.ttf", "Vera");
  57. tb::TBFontDescription fd;
  58. fd.SetID(tb::TBIDC("Vera"));
  59. fd.SetSize(tb::g_tb_skin->GetDimensionConverter()->DpToPx(12));
  60. tb::g_font_manager->SetDefaultFontDescription(fd);
  61. // Create the font now.
  62. tb::TBFontFace *font = tb::g_font_manager->CreateFontFace(tb::g_font_manager->GetDefaultFontDescription());
  63. // Render some glyphs in one go now since we know we are going to use them. It would work fine
  64. // without this since glyphs are rendered when needed, but with some extra updating of the glyph bitmap.
  65. if (font)
  66. font->RenderGlyphs(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~•·åäöÅÄÖ");
  67. rootWidget_ = new TBWidget();
  68. //rootWidget_->SetSkinBg(tb::TBIDC("background"));
  69. int width = graphics_->GetWidth();
  70. int height = graphics_->GetHeight();
  71. rootWidget_->SetSize(width, height);
  72. //SetSize(width, height);
  73. rootWidget_->SetVisibilility(tb::WIDGET_VISIBILITY_VISIBLE);
  74. SubscribeToEvent(E_MOUSEBUTTONDOWN, HANDLER(UIView, HandleMouseButtonDown));
  75. SubscribeToEvent(E_MOUSEBUTTONUP, HANDLER(UIView, HandleMouseButtonUp));
  76. SubscribeToEvent(E_MOUSEMOVE, HANDLER(UIView, HandleMouseMove));
  77. SubscribeToEvent(E_MOUSEWHEEL, HANDLER(UIView, HandleMouseWheel));
  78. SubscribeToEvent(E_KEYDOWN, HANDLER(UIView, HandleKeyDown));
  79. SubscribeToEvent(E_KEYUP, HANDLER(UIView, HandleKeyUp));
  80. SubscribeToEvent(E_TEXTINPUT, HANDLER(UIView, HandleTextInput));
  81. SubscribeToEvent(E_UPDATE, HANDLER(UIView, HandleUpdate));
  82. SubscribeToEvent(E_RENDERUPDATE, HANDLER(UIView, HandleRenderUpdate));
  83. //TB_DEBUG_SETTING(LAYOUT_BOUNDS) = 1;
  84. }
  85. void UIView::Render(VertexBuffer* buffer, const PODVector<UIBatch>& batches, unsigned batchStart, unsigned batchEnd)
  86. {
  87. if (batches.Empty())
  88. return;
  89. Vector2 invScreenSize(1.0f / (float)graphics_->GetWidth(), 1.0f / (float)graphics_->GetHeight());
  90. Vector2 scale(2.0f * invScreenSize.x_, -2.0f * invScreenSize.y_);
  91. Vector2 offset(-1.0f, 1.0f);
  92. Matrix4 projection(Matrix4::IDENTITY);
  93. projection.m00_ = scale.x_;
  94. projection.m03_ = offset.x_;
  95. projection.m11_ = scale.y_;
  96. projection.m13_ = offset.y_;
  97. projection.m22_ = 1.0f;
  98. projection.m23_ = 0.0f;
  99. projection.m33_ = 1.0f;
  100. graphics_->ClearParameterSources();
  101. graphics_->SetColorWrite(true);
  102. graphics_->SetCullMode(CULL_NONE);
  103. graphics_->SetDepthTest(CMP_ALWAYS);
  104. graphics_->SetDepthWrite(false);
  105. graphics_->SetDrawAntialiased(false);
  106. graphics_->SetFillMode(FILL_SOLID);
  107. graphics_->SetStencilTest(false);
  108. graphics_->ResetRenderTargets();
  109. graphics_->SetVertexBuffer(buffer);
  110. ShaderVariation* noTextureVS = graphics_->GetShader(VS, "Basic", "VERTEXCOLOR");
  111. ShaderVariation* diffTextureVS = graphics_->GetShader(VS, "Basic", "DIFFMAP VERTEXCOLOR");
  112. ShaderVariation* noTexturePS = graphics_->GetShader(PS, "Basic", "VERTEXCOLOR");
  113. ShaderVariation* diffTexturePS = graphics_->GetShader(PS, "Basic", "DIFFMAP VERTEXCOLOR");
  114. ShaderVariation* diffMaskTexturePS = graphics_->GetShader(PS, "Basic", "DIFFMAP ALPHAMASK VERTEXCOLOR");
  115. ShaderVariation* alphaTexturePS = graphics_->GetShader(PS, "Basic", "ALPHAMAP VERTEXCOLOR");
  116. unsigned alphaFormat = Graphics::GetAlphaFormat();
  117. for (unsigned i = batchStart; i < batchEnd; ++i)
  118. {
  119. const UIBatch& batch = batches[i];
  120. if (batch.vertexStart_ == batch.vertexEnd_)
  121. continue;
  122. ShaderVariation* ps;
  123. ShaderVariation* vs;
  124. if (!batch.texture_)
  125. {
  126. ps = noTexturePS;
  127. vs = noTextureVS;
  128. }
  129. else
  130. {
  131. // If texture contains only an alpha channel, use alpha shader (for fonts)
  132. vs = diffTextureVS;
  133. if (batch.texture_->GetFormat() == alphaFormat)
  134. ps = alphaTexturePS;
  135. else if (batch.blendMode_ != BLEND_ALPHA && batch.blendMode_ != BLEND_ADDALPHA && batch.blendMode_ != BLEND_PREMULALPHA)
  136. ps = diffMaskTexturePS;
  137. else
  138. ps = diffTexturePS;
  139. }
  140. graphics_->SetShaders(vs, ps);
  141. if (graphics_->NeedParameterUpdate(SP_OBJECTTRANSFORM, this))
  142. graphics_->SetShaderParameter(VSP_MODEL, Matrix3x4::IDENTITY);
  143. if (graphics_->NeedParameterUpdate(SP_CAMERA, this))
  144. graphics_->SetShaderParameter(VSP_VIEWPROJ, projection);
  145. if (graphics_->NeedParameterUpdate(SP_MATERIAL, this))
  146. graphics_->SetShaderParameter(PSP_MATDIFFCOLOR, Color(1.0f, 1.0f, 1.0f, 1.0f));
  147. graphics_->SetBlendMode(batch.blendMode_);
  148. graphics_->SetScissorTest(true, batch.scissor_);
  149. graphics_->SetTexture(0, batch.texture_);
  150. graphics_->Draw(TRIANGLE_LIST, batch.vertexStart_ / UI_VERTEX_SIZE, (batch.vertexEnd_ - batch.vertexStart_) /
  151. UI_VERTEX_SIZE);
  152. }
  153. }
  154. void UIView::SetVertexData(VertexBuffer* dest, const PODVector<float>& vertexData)
  155. {
  156. if (vertexData.Empty())
  157. return;
  158. // Update quad geometry into the vertex buffer
  159. // Resize the vertex buffer first if too small or much too large
  160. unsigned numVertices = vertexData.Size() / UI_VERTEX_SIZE;
  161. if (dest->GetVertexCount() < numVertices || dest->GetVertexCount() > numVertices * 2)
  162. dest->SetSize(numVertices, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1, true);
  163. dest->SetData(&vertexData[0]);
  164. }
  165. void UIView::Render()
  166. {
  167. SetVertexData(vertexBuffer_, vertexData_);
  168. Render(vertexBuffer_, batches_, 0, batches_.Size());
  169. }
  170. void UIView::HandleRenderUpdate(StringHash eventType, VariantMap& eventData)
  171. {
  172. // Get rendering batches from the non-modal UI elements
  173. batches_.Clear();
  174. vertexData_.Clear();
  175. tb::TBRect rect = rootWidget_->GetRect();
  176. IntRect currentScissor = IntRect(0, 0, rect.w, rect.h);
  177. GetBatches(batches_, vertexData_, currentScissor);
  178. }
  179. void UIView::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
  180. {
  181. //if (!initialized_)
  182. // return;
  183. // TBAnimationManager::Update();
  184. rootWidget_->InvokeProcessStates();
  185. rootWidget_->InvokeProcess();
  186. tb::g_renderer->BeginPaint(rootWidget_->GetRect().w, rootWidget_->GetRect().h);
  187. renderer_->currentScissor_ = currentScissor;
  188. renderer_->batches_ = &batches;
  189. renderer_->vertexData_ = &vertexData;
  190. rootWidget_->InvokePaint(tb::TBWidget::PaintProps());
  191. tb::g_renderer->EndPaint();
  192. }
  193. void UIView::SubmitBatchVertexData(Texture* texture, const PODVector<float>& vertexData)
  194. {
  195. UIBatch b(BLEND_ALPHA , renderer_->currentScissor_, texture, &vertexData_);
  196. unsigned begin = b.vertexData_->Size();
  197. b.vertexData_->Resize(begin + vertexData.Size());
  198. float* dest = &(b.vertexData_->At(begin));
  199. b.vertexEnd_ = b.vertexData_->Size();
  200. for (unsigned i = 0; i < vertexData.Size(); i++, dest++)
  201. {
  202. *dest = vertexData[i];
  203. }
  204. UIBatch::AddOrMerge(b, batches_);
  205. }
  206. void UIView::TBFileReader(const char* filename, void** data, unsigned* length)
  207. {
  208. *data = 0;
  209. *length = 0;
  210. ResourceCache* cache = readerContext_->GetSubsystem<ResourceCache>();
  211. SharedPtr<File> file = cache->GetFile(filename);
  212. if (!file || !file->IsOpen())
  213. return;
  214. unsigned size = file->GetSize();
  215. if (!size)
  216. return;
  217. void* _data = malloc(size);
  218. if (!_data)
  219. return;
  220. if (file->Read(_data, size) != size)
  221. {
  222. free(_data);
  223. return;
  224. }
  225. *length = size;
  226. *data = _data;
  227. }
  228. void UIView::HandleScreenMode(StringHash eventType, VariantMap& eventData)
  229. {
  230. using namespace ScreenMode;
  231. rootWidget_->SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
  232. //SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
  233. }
  234. static MODIFIER_KEYS GetModifierKeys(int qualifiers, bool superKey)
  235. {
  236. MODIFIER_KEYS code = TB_MODIFIER_NONE;
  237. if (qualifiers & QUAL_ALT) code |= TB_ALT;
  238. if (qualifiers & QUAL_CTRL) code |= TB_CTRL;
  239. if (qualifiers & QUAL_SHIFT) code |= TB_SHIFT;
  240. if (superKey) code |= TB_SUPER;
  241. return code;
  242. }
  243. // @return Return the upper case of a ascii charcter. Only for shortcut handling.
  244. static int toupr_ascii(int ascii)
  245. {
  246. if (ascii >= 'a' && ascii <= 'z')
  247. return ascii + 'A' - 'a';
  248. return ascii;
  249. }
  250. void UIView::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
  251. {
  252. if (inputDisabled_)
  253. return;
  254. using namespace MouseButtonDown;
  255. unsigned button = eventData[P_BUTTON].GetUInt();
  256. IntVector2 pos;
  257. pos = GetSubsystem<Input>()->GetMousePosition();
  258. Input* input = GetSubsystem<Input>();
  259. int qualifiers = input->GetQualifiers();
  260. #ifdef ATOMIC_PLATFORM_WINDOWS
  261. bool superdown = input->GetKeyDown(KEY_LCTRL) || input->GetKeyDown(KEY_RCTRL);
  262. #else
  263. bool superdown = input->GetKeyDown(KEY_LGUI) || input->GetKeyDown(KEY_RGUI);
  264. #endif
  265. MODIFIER_KEYS mod = GetModifierKeys(qualifiers, superdown);
  266. static double last_time = 0;
  267. static int counter = 1;
  268. Time* t = GetSubsystem<Time>();
  269. double time = t->GetElapsedTime() * 1000;
  270. if (time < last_time + 600)
  271. counter++;
  272. else
  273. counter = 1;
  274. last_time = time;
  275. if (button == MOUSEB_RIGHT)
  276. rootWidget_->InvokeRightPointerDown(pos.x_, pos.y_, counter, mod);
  277. else
  278. rootWidget_->InvokePointerDown(pos.x_, pos.y_, counter, mod, false);
  279. }
  280. void UIView::HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
  281. {
  282. if (inputDisabled_)
  283. return;
  284. using namespace MouseButtonUp;
  285. unsigned button = eventData[P_BUTTON].GetUInt();
  286. IntVector2 pos;
  287. Input* input = GetSubsystem<Input>();
  288. pos = input->GetMousePosition();
  289. int qualifiers = input->GetQualifiers();
  290. #ifdef ATOMIC_PLATFORM_WINDOWS
  291. bool superdown = input->GetKeyDown(KEY_LCTRL) || input->GetKeyDown(KEY_RCTRL);
  292. #else
  293. bool superdown = input->GetKeyDown(KEY_LGUI) || input->GetKeyDown(KEY_RGUI);
  294. #endif
  295. MODIFIER_KEYS mod = GetModifierKeys(qualifiers, superdown);
  296. if (button == MOUSEB_RIGHT)
  297. rootWidget_->InvokeRightPointerUp(pos.x_, pos.y_, mod);
  298. else
  299. rootWidget_->InvokePointerUp(pos.x_, pos.y_, mod, false);
  300. }
  301. void UIView::HandleMouseMove(StringHash eventType, VariantMap& eventData)
  302. {
  303. using namespace MouseMove;
  304. if (inputDisabled_)
  305. return;
  306. int px = eventData[P_X].GetInt();
  307. int py = eventData[P_Y].GetInt();
  308. rootWidget_->InvokePointerMove(px, py, tb::TB_MODIFIER_NONE, false);
  309. }
  310. void UIView::HandleMouseWheel(StringHash eventType, VariantMap& eventData)
  311. {
  312. if (inputDisabled_)
  313. return;
  314. using namespace MouseWheel;
  315. int delta = eventData[P_WHEEL].GetInt();
  316. Input* input = GetSubsystem<Input>();
  317. rootWidget_->InvokeWheel(input->GetMousePosition().x_, input->GetMousePosition().y_, 0, delta > 0 ? -1 : 1, tb::TB_MODIFIER_NONE);
  318. }
  319. static bool InvokeShortcut(int key, SPECIAL_KEY special_key, MODIFIER_KEYS modifierkeys, bool down)
  320. {
  321. #ifdef __APPLE__
  322. bool shortcut_key = (modifierkeys & TB_SUPER) ? true : false;
  323. #else
  324. bool shortcut_key = (modifierkeys & TB_CTRL) ? true : false;
  325. #endif
  326. if (!TBWidget::focused_widget || !down || (!shortcut_key && special_key ==TB_KEY_UNDEFINED))
  327. return false;
  328. bool reverse_key = (modifierkeys & TB_SHIFT) ? true : false;
  329. int upper_key = toupr_ascii(key);
  330. TBID id;
  331. if (upper_key == 'X')
  332. id = TBIDC("cut");
  333. else if (upper_key == 'C' || special_key == TB_KEY_INSERT)
  334. id = TBIDC("copy");
  335. else if (upper_key == 'V' || (special_key == TB_KEY_INSERT && reverse_key))
  336. id = TBIDC("paste");
  337. else if (upper_key == 'A')
  338. id = TBIDC("selectall");
  339. else if (upper_key == 'Z' || upper_key == 'Y')
  340. {
  341. bool undo = upper_key == 'Z';
  342. if (reverse_key)
  343. undo = !undo;
  344. id = undo ? TBIDC("undo") : TBIDC("redo");
  345. }
  346. else if (upper_key == 'N')
  347. id = TBIDC("new");
  348. else if (upper_key == 'O')
  349. id = TBIDC("open");
  350. else if (upper_key == 'S')
  351. id = TBIDC("save");
  352. else if (upper_key == 'W')
  353. id = TBIDC("close");
  354. else if (upper_key == 'F')
  355. id = TBIDC("find");
  356. #ifdef ATOMIC_PLATFORM_OSX
  357. else if (upper_key == 'G' && (modifierkeys & TB_SHIFT))
  358. id = TBIDC("findprev");
  359. else if (upper_key == 'G')
  360. id = TBIDC("findnext");
  361. #else
  362. else if (special_key == TB_KEY_F3 && (modifierkeys & TB_SHIFT))
  363. id = TBIDC("findprev");
  364. else if (special_key == TB_KEY_F3)
  365. id = TBIDC("findnext");
  366. #endif
  367. else if (upper_key == 'P')
  368. id = TBIDC("play");
  369. else if (upper_key == 'I')
  370. id = TBIDC("beautify");
  371. else if (special_key == TB_KEY_PAGE_UP)
  372. id = TBIDC("prev_doc");
  373. else if (special_key == TB_KEY_PAGE_DOWN)
  374. id = TBIDC("next_doc");
  375. else
  376. return false;
  377. TBWidgetEvent ev(EVENT_TYPE_SHORTCUT);
  378. ev.modifierkeys = modifierkeys;
  379. ev.ref_id = id;
  380. return TBWidget::focused_widget->InvokeEvent(ev);
  381. }
  382. static bool InvokeKey(TBWidget* root, unsigned int key, SPECIAL_KEY special_key, MODIFIER_KEYS modifierkeys, bool keydown)
  383. {
  384. if (InvokeShortcut(key, special_key, modifierkeys, keydown))
  385. return true;
  386. root->InvokeKey(key, special_key, modifierkeys, keydown);
  387. return true;
  388. }
  389. void UIView::HandleKey(bool keydown, int keycode, int scancode)
  390. {
  391. #ifdef ATOMIC_PLATFORM_WINDOWS
  392. if (keycode == KEY_LCTRL || keycode == KEY_RCTRL)
  393. return;
  394. #else
  395. if (keycode == KEY_LGUI || keycode == KEY_RGUI)
  396. return;
  397. #endif
  398. Input* input = GetSubsystem<Input>();
  399. int qualifiers = input->GetQualifiers();
  400. #ifdef ATOMIC_PLATFORM_WINDOWS
  401. bool superdown = input->GetKeyDown(KEY_LCTRL) || input->GetKeyDown(KEY_RCTRL);
  402. #else
  403. bool superdown = input->GetKeyDown(KEY_LGUI) || input->GetKeyDown(KEY_RGUI);
  404. #endif
  405. MODIFIER_KEYS mod = GetModifierKeys(qualifiers, superdown);
  406. switch (keycode)
  407. {
  408. case KEY_RETURN:
  409. case KEY_RETURN2:
  410. case KEY_KP_ENTER:
  411. InvokeKey(rootWidget_, 0, TB_KEY_ENTER, mod, keydown);
  412. break;
  413. case KEY_F1:
  414. InvokeKey(rootWidget_, 0, TB_KEY_F1, mod, keydown);
  415. break;
  416. case KEY_F2:
  417. InvokeKey(rootWidget_, 0, TB_KEY_F2, mod, keydown);
  418. break;
  419. case KEY_F3:
  420. InvokeKey(rootWidget_, 0, TB_KEY_F3, mod, keydown);
  421. break;
  422. case KEY_F4:
  423. InvokeKey(rootWidget_, 0, TB_KEY_F4, mod, keydown);
  424. break;
  425. case KEY_F5:
  426. InvokeKey(rootWidget_, 0, TB_KEY_F5, mod, keydown);
  427. break;
  428. case KEY_F6:
  429. InvokeKey(rootWidget_, 0, TB_KEY_F6, mod, keydown);
  430. break;
  431. case KEY_F7:
  432. InvokeKey(rootWidget_, 0, TB_KEY_F7, mod, keydown);
  433. break;
  434. case KEY_F8:
  435. InvokeKey(rootWidget_, 0, TB_KEY_F8, mod, keydown);
  436. break;
  437. case KEY_F9:
  438. InvokeKey(rootWidget_, 0, TB_KEY_F9, mod, keydown);
  439. break;
  440. case KEY_F10:
  441. InvokeKey(rootWidget_, 0, TB_KEY_F10, mod, keydown);
  442. break;
  443. case KEY_F11:
  444. InvokeKey(rootWidget_, 0, TB_KEY_F11, mod, keydown);
  445. break;
  446. case KEY_F12:
  447. InvokeKey(rootWidget_, 0, TB_KEY_F12, mod, keydown);
  448. break;
  449. case KEY_LEFT:
  450. InvokeKey(rootWidget_, 0, TB_KEY_LEFT, mod, keydown);
  451. break;
  452. case KEY_UP:
  453. InvokeKey(rootWidget_, 0, TB_KEY_UP, mod, keydown);
  454. break;
  455. case KEY_RIGHT:
  456. InvokeKey(rootWidget_, 0, TB_KEY_RIGHT, mod, keydown);
  457. break;
  458. case KEY_DOWN:
  459. InvokeKey(rootWidget_, 0, TB_KEY_DOWN, mod, keydown);
  460. break;
  461. case KEY_PAGEUP:
  462. InvokeKey(rootWidget_, 0, TB_KEY_PAGE_UP, mod, keydown);
  463. break;
  464. case KEY_PAGEDOWN:
  465. InvokeKey(rootWidget_, 0, TB_KEY_PAGE_DOWN, mod, keydown);
  466. break;
  467. case KEY_HOME:
  468. InvokeKey(rootWidget_, 0, TB_KEY_HOME, mod, keydown);
  469. break;
  470. case KEY_END:
  471. InvokeKey(rootWidget_, 0, TB_KEY_END, mod, keydown);
  472. break;
  473. case KEY_INSERT:
  474. InvokeKey(rootWidget_, 0, TB_KEY_INSERT, mod, keydown);
  475. break;
  476. case KEY_TAB:
  477. InvokeKey(rootWidget_, 0, TB_KEY_TAB, mod, keydown);
  478. break;
  479. case KEY_DELETE:
  480. InvokeKey(rootWidget_, 0, TB_KEY_DELETE, mod, keydown);
  481. break;
  482. case KEY_BACKSPACE:
  483. InvokeKey(rootWidget_, 0, TB_KEY_BACKSPACE, mod, keydown);
  484. break;
  485. case KEY_ESC:
  486. InvokeKey(rootWidget_, 0, TB_KEY_ESC, mod, keydown);
  487. break;
  488. default:
  489. if (mod & TB_SUPER)
  490. {
  491. InvokeKey(rootWidget_, keycode, TB_KEY_UNDEFINED, mod, keydown);
  492. }
  493. }
  494. }
  495. void UIView::HandleKeyDown(StringHash eventType, VariantMap& eventData)
  496. {
  497. if (inputDisabled_ || keyboardDisabled_)
  498. return;
  499. using namespace KeyDown;
  500. int keycode = eventData[P_KEY].GetInt();
  501. int scancode = eventData[P_SCANCODE].GetInt();
  502. HandleKey(true, keycode, scancode);
  503. }
  504. void UIView::HandleKeyUp(StringHash eventType, VariantMap& eventData)
  505. {
  506. if (inputDisabled_ || keyboardDisabled_)
  507. return;
  508. using namespace KeyUp;
  509. int keycode = eventData[P_KEY].GetInt();
  510. int scancode = eventData[P_SCANCODE].GetInt();
  511. HandleKey(false, keycode, scancode);
  512. }
  513. void UIView::HandleTextInput(StringHash eventType, VariantMap& eventData)
  514. {
  515. if (inputDisabled_ || keyboardDisabled_)
  516. return;
  517. using namespace TextInput;
  518. const String& text = eventData[P_TEXT].GetString();
  519. for (unsigned i = 0; i < text.Length(); i++)
  520. {
  521. InvokeKey(rootWidget_, text[i], TB_KEY_UNDEFINED, TB_MODIFIER_NONE, true);
  522. InvokeKey(rootWidget_, text[i], TB_KEY_UNDEFINED, TB_MODIFIER_NONE, false);
  523. }
  524. }
  525. void UIView::HandleUpdate(StringHash eventType, VariantMap& eventData)
  526. {
  527. TBMessageHandler::ProcessMessages();
  528. }
  529. }