// // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #include using namespace tb; #include "../Core/Timer.h" #include "../Graphics/Graphics.h" #include "../IO/Log.h" #include "../Input/Input.h" #include "../Input/InputEvents.h" #include "UI.h" #include "UIEvents.h" #include "UIOffscreenView.h" namespace Atomic { static inline MODIFIER_KEYS GetModifierKeys(int qualifiers, bool superKey) { MODIFIER_KEYS code = TB_MODIFIER_NONE; if (qualifiers & QUAL_ALT) code |= TB_ALT; if (qualifiers & QUAL_CTRL) code |= TB_CTRL; if (qualifiers & QUAL_SHIFT) code |= TB_SHIFT; if (superKey) code |= TB_SUPER; return code; } // @return Return the upper case of a ascii charcter. Only for shortcut handling. static int toupr_ascii(int ascii) { if (ascii >= 'a' && ascii <= 'z') return ascii + 'A' - 'a'; return ascii; } UIOffscreenView* UI::FindOffscreenViewAtScreenPosition(const IntVector2& screenPos, IntVector2& viewPos) { for (HashSet::Iterator it = offscreenViews_.Begin(); it != offscreenViews_.End(); ++it) { UIOffscreenView* osView = *it; IntRect rect = osView->inputRect_; Camera* camera = osView->inputCamera_; Octree* octree = osView->inputOctree_; Drawable* drawable = osView->inputDrawable_; bool rectIsDefault = rect == IntRect::ZERO; if (!camera || !octree || !drawable || (!rectIsDefault && !rect.IsInside(screenPos))) continue; Vector2 normPos(screenPos.x_ - rect.left_, screenPos.y_ - rect.top_); normPos /= rectIsDefault ? Vector2(graphics_->GetWidth(), graphics_->GetHeight()) : Vector2(rect.Width(), rect.Height()); Ray ray(camera->GetScreenRay(normPos.x_, normPos.y_)); PODVector queryResultVector; RayOctreeQuery query(queryResultVector, ray, RAY_TRIANGLE_UV, M_INFINITY, DRAWABLE_GEOMETRY, DEFAULT_VIEWMASK); octree->RaycastSingle(query); if (queryResultVector.Empty()) continue; RayQueryResult& queryResult(queryResultVector.Front()); if (queryResult.drawable_ != drawable) continue; Vector2& uv = queryResult.textureUV_; viewPos = IntVector2(uv.x_ * osView->GetWidth(), uv.y_ * osView->GetHeight()); return osView; } return nullptr; } tb::TBWidget* UI::GetInternalWidgetAndProjectedPositionFor(const IntVector2& screenPos, IntVector2& viewPos) { UIOffscreenView* osView = FindOffscreenViewAtScreenPosition(screenPos, viewPos); if (osView) return osView->GetInternalWidget(); viewPos = screenPos; return rootWidget_; } void UI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData) { if (inputDisabled_ || consoleVisible_) return; using namespace MouseButtonDown; unsigned button = eventData[P_BUTTON].GetUInt(); IntVector2 pos; pos = GetSubsystem()->GetMousePosition(); Input* input = GetSubsystem(); int qualifiers = input->GetQualifiers(); #ifdef ATOMIC_PLATFORM_WINDOWS bool superdown = input->GetKeyDown(KEY_LCTRL) || input->GetKeyDown(KEY_RCTRL); #else bool superdown = input->GetKeyDown(KEY_LGUI) || input->GetKeyDown(KEY_RGUI); #endif MODIFIER_KEYS mod = GetModifierKeys(qualifiers, superdown); static double last_time = 0; static int counter = 1; Time* t = GetSubsystem