Index: binaries/data/mods/public/gui/reference/viewer/viewer.js =================================================================== --- binaries/data/mods/public/gui/reference/viewer/viewer.js +++ binaries/data/mods/public/gui/reference/viewer/viewer.js @@ -98,8 +98,6 @@ /** * Populate the UI elements. - * - * @todo (c++ change) Implement and use a function that fetches height of rendered text block from text object. */ function draw() { @@ -111,12 +109,10 @@ let entityStats = Engine.GetGUIObjectByName("entityStats"); entityStats.caption = buildText(g_Template, g_StatsFunctions); - // This is something of a crude hack. See above todo. let entityInfo = Engine.GetGUIObjectByName("entityInfo"); - let lines = entityStats.caption.split("\n").length; - let fontSize = +entityStats.font.split("-")[1] + 4; let infoSize = entityInfo.size; - infoSize.top = Math.max(entityIcon.size.bottom, lines * fontSize + entityStats.size.top) + 8; + // The magic '8' below provides a gap between the bottom of the icon, and the start of the info text. + infoSize.top = Math.max(entityIcon.size.bottom + 8, entityStats.size.top + entityStats.getTextSize().height); entityInfo.size = infoSize; entityInfo.caption = buildText(g_Template, g_InfoFunctions, "\n\n"); Index: source/gui/CGUI.h =================================================================== --- source/gui/CGUI.h +++ source/gui/CGUI.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -68,7 +68,6 @@ NONCOPYABLE(CGUI); friend class IGUIObject; - friend class IGUIScrollBarOwner; friend class CInternalCGUIAccessorBase; private: @@ -173,6 +172,8 @@ */ IGUIObject* FindObjectUnderMouse() const; + const SGUIScrollBarStyle* GetScrollBarStyle(const CStr& style) const; + /** * The GUI needs to have all object types inputted and * their constructors. Also it needs to associate a type Index: source/gui/CGUI.cpp =================================================================== --- source/gui/CGUI.cpp +++ source/gui/CGUI.cpp @@ -475,6 +475,15 @@ } } +const SGUIScrollBarStyle* CGUI::GetScrollBarStyle(const CStr& style) const +{ + std::map::const_iterator it = m_ScrollBarStyles.find(style); + if (it == m_ScrollBarStyles.end()) + return nullptr; + + return &it->second; +} + // private struct used only in GenerateText(...) struct SGenerateTextImage { @@ -540,8 +549,9 @@ // get the alignment type for the control we are computing the text for since // we are computing the horizontal alignment in this method in order to not have // to run through the TextCalls a second time in the CalculateTextPosition method again - EAlign align; - GUI::GetSetting(pObject, "text_align", align); + EAlign align = EAlign_Left; + if (pObject->SettingExists("text_align")) + GUI::GetSetting(pObject, "text_align", align); // Go through string word by word for (int i = 0; i < (int)string.m_Words.size()-1 && !done; ++i) Index: source/gui/IGUIObject.h =================================================================== --- source/gui/IGUIObject.h +++ source/gui/IGUIObject.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -87,6 +87,7 @@ friend bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp); friend bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool UNUSED(strict), JS::MutableHandleValue vp); friend bool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, JS::Value* vp); + friend bool JSI_IGUIObject::getTextSize(JSContext* cx, uint argc, JS::Value* vp); public: IGUIObject(); Index: source/gui/IGUIScrollBarOwner.cpp =================================================================== --- source/gui/IGUIScrollBarOwner.cpp +++ source/gui/IGUIScrollBarOwner.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -47,19 +47,9 @@ const SGUIScrollBarStyle* IGUIScrollBarOwner::GetScrollBarStyle(const CStr& style) const { if (!GetGUI()) - { - // TODO Gee: Output in log return NULL; - } - std::map::const_iterator it = GetGUI()->m_ScrollBarStyles.find(style); - if (it == GetGUI()->m_ScrollBarStyles.end()) - { - // TODO Gee: Output in log - return NULL; - } - - return &it->second; + return GetGUI()->GetScrollBarStyle(style); } void IGUIScrollBarOwner::HandleMessage(SGUIMessage& msg) Index: source/gui/scripting/JSInterface_IGUIObject.h =================================================================== --- source/gui/scripting/JSInterface_IGUIObject.h +++ source/gui/scripting/JSInterface_IGUIObject.h @@ -32,6 +32,7 @@ bool focus(JSContext* cx, uint argc, JS::Value* vp); bool blur(JSContext* cx, uint argc, JS::Value* vp); bool getComputedSize(JSContext* cx, uint argc, JS::Value* vp); + bool getTextSize(JSContext* cx, uint argc, JS::Value* vp); void init(ScriptInterface& scriptInterface); } Index: source/gui/scripting/JSInterface_IGUIObject.cpp =================================================================== --- source/gui/scripting/JSInterface_IGUIObject.cpp +++ source/gui/scripting/JSInterface_IGUIObject.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -50,6 +50,7 @@ JS_FS("focus", JSI_IGUIObject::focus, 0, 0), JS_FS("blur", JSI_IGUIObject::blur, 0, 0), JS_FS("getComputedSize", JSI_IGUIObject::getComputedSize, 0, 0), + JS_FS("getTextSize", JSI_IGUIObject::getTextSize, 0, 0), JS_FS_END }; @@ -81,6 +82,7 @@ propName == "toJSON" || propName == "focus" || propName == "blur" || + propName == "getTextSize" || propName == "getComputedSize" ) return true; @@ -690,6 +692,76 @@ return true; } +bool JSI_IGUIObject::getTextSize(JSContext* cx, uint UNUSED(argc), JS::Value* vp) +{ + JSAutoRequest rq(cx); + JS::CallReceiver rec = JS::CallReceiverFromVp(vp); + + JS::RootedObject thisObj(cx, JS_THIS_OBJECT(cx, vp)); + + IGUIObject* obj = (IGUIObject*)JS_GetInstancePrivate(cx, thisObj, &JSI_IGUIObject::JSI_class, NULL); + + if (!obj || !obj->SettingExists("caption")) + return false; + + CStrW font; + if (GUI::GetSetting(obj, "font", font) != PSRETURN_OK || font.empty()) + font = L"default"; + + CGUIString caption; + EGUISettingType Type; + obj->GetSettingType("caption", Type); + if (Type == GUIST_CGUIString) + // CText, CButton, CCheckBox, CRadioButton + GUI::GetSetting(obj, "caption", caption); + else if (Type == GUIST_CStrW) + { + // CInput + CStrW captionStr; + GUI::GetSetting(obj, "caption", captionStr); + caption.SetValue(captionStr); + } + else + return false; + + obj->UpdateCachedSize(); + float width = obj->m_CachedActualSize.GetWidth(); + + if (obj->SettingExists("scrollbar")) + { + bool scrollbar; + GUI::GetSetting(obj, "scrollbar", scrollbar); + if (scrollbar) + { + CStr scrollbar_style; + GUI::GetSetting(obj, "scrollbar_style", scrollbar_style); + const SGUIScrollBarStyle* scrollbar_style_object = obj->GetGUI()->GetScrollBarStyle(scrollbar_style); + if (scrollbar_style_object) + width -= scrollbar_style_object->m_Width; + } + } + + float buffer_zone = 0.f; + GUI::GetSetting(obj, "buffer_zone", buffer_zone); + SGUIText text = obj->GetGUI()->GenerateText(caption, font, width, buffer_zone, obj); + + JS::RootedValue objVal(cx, JS::ObjectValue(*JS_NewPlainObject(cx))); + try + { + ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; + pScriptInterface->SetProperty(objVal, "width", text.m_Size.cx, false, true); + pScriptInterface->SetProperty(objVal, "height", text.m_Size.cy, false, true); + } + catch (PSERROR_Scripting_ConversionFailed&) + { + debug_warn(L"Error creating size object!"); + return false; + } + + rec.rval().set(objVal); + return true; +} + bool JSI_IGUIObject::getComputedSize(JSContext* cx, uint UNUSED(argc), JS::Value* vp) { JSAutoRequest rq(cx); @@ -708,6 +780,8 @@ try { ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface; + pScriptInterface->SetProperty(objVal, "width", size.GetWidth(), false, true); + pScriptInterface->SetProperty(objVal, "height", size.GetHeight(), false, true); pScriptInterface->SetProperty(objVal, "left", size.left, false, true); pScriptInterface->SetProperty(objVal, "right", size.right, false, true); pScriptInterface->SetProperty(objVal, "top", size.top, false, true);