Index: binaries/data/mods/mod/gui/common/modern/setup.xml =================================================================== --- binaries/data/mods/mod/gui/common/modern/setup.xml +++ binaries/data/mods/mod/gui/common/modern/setup.xml @@ -1,5 +1,4 @@ - - + - + Index: binaries/data/mods/public/gui/pregame/mainmenu.js =================================================================== --- binaries/data/mods/public/gui/pregame/mainmenu.js +++ binaries/data/mods/public/gui/pregame/mainmenu.js @@ -42,6 +42,32 @@ guiObj.sprite = g_BackgroundLayerset[i].sprite; guiObj.z = i; } + + let tstCt = [ "blue", "red", "purple", "cyan", "rainbow", "tartan", "plaid", "brown", "black", "grey", "gray", "pink", "green", "magenta", "taupe", "mauve", "pecan", "orange" ]; + let tstDd = Engine.GetGUIObjectByName("testDrop"); + tstDd.list = tstCt; + tstDd.selected = 2; + + let tstLt = Engine.GetGUIObjectByName("testList"); + tstLt.list = tstCt; + tstLt.selected = 4; + + let tstOLt = Engine.GetGUIObjectByName("testOList"); + tstOLt.list_name = tstCt; + tstOLt.list_a = tstCt; + tstOLt.list_b = tstCt.reverse(); + tstOLt.list = tstCt; + tstOLt.selected = 1; + + let tstTxt = Engine.GetGUIObjectByName("testTextbox").caption; + let tstTB = Engine.GetGUIObjectByName("testTextboxScrollable"); + for (let i=0; i<3; ++i) + tstTB.caption += '[font="sans-bold-12"]Scrollable [/font]' + tstTxt + "\n\n"; + + let tstML = Engine.GetGUIObjectByName("testInputMultiline"); + for (let i=0; i<24; ++i) + tstML.caption += "\n."; + tstML.caption += "\nGroovy, baby!"; } function getHotloadData() Index: binaries/data/mods/public/gui/pregame/mainmenu.xml =================================================================== --- binaries/data/mods/public/gui/pregame/mainmenu.xml +++ binaries/data/mods/public/gui/pregame/mainmenu.xml @@ -641,6 +641,31 @@ + + + + + +[font="sans-bold-14"]Textbox:[/font] +Consider yourself, at home! +Consider yourself, part of the furniture! +We've taken to you, so strong. +It's clear. We're. Going to get along! + + + + + + + + + + Single Line Input Box + Multiple Line Input Box + + + + Index: source/gui/CDropDown.cpp =================================================================== --- source/gui/CDropDown.cpp +++ source/gui/CDropDown.cpp @@ -86,6 +86,7 @@ Message.value == "dropdown_size" || Message.value == "dropdown_buffer" || Message.value == "scrollbar_style" || + Message.value == "scrollbar" || Message.value == "button_width") { SetupListRect(); @@ -119,7 +120,7 @@ { if (mouse.y >= rect.top + m_ItemsYPositions[i] && mouse.y < rect.top + m_ItemsYPositions[i+1] && - // mouse is not over scroll-bar + // Mouse is not over scrollbar (m_HideScrollBar || mouse.x < GetScrollBar(0).GetOuterRect().left || mouse.x > GetScrollBar(0).GetOuterRect().right)) @@ -165,8 +166,8 @@ break; } - // We can't inherent this routine from CList, because we need to include - // a mouse click to open the dropdown, also the coordinates are changed. + // We can't inherit this routine from CList, because we need to include + // a mouse click to open the dropdown. Also, the coordinates are changed. case GUIM_MOUSE_PRESS_LEFT: { bool enabled; @@ -389,6 +390,9 @@ void CDropDown::SetupListRect() { + if (!GetGUI()) + return; + float size, buffer; GUI::GetSetting(this, "dropdown_size", size); GUI::GetSetting(this, "dropdown_buffer", buffer); Index: source/gui/CGUI.h =================================================================== --- source/gui/CGUI.h +++ source/gui/CGUI.h @@ -637,7 +637,7 @@ // Styles std::map m_Styles; - // Scroll-bar styles + // Scrollbar styles std::map m_ScrollBarStyles; // Icons Index: source/gui/CGUI.cpp =================================================================== --- source/gui/CGUI.cpp +++ source/gui/CGUI.cpp @@ -1601,13 +1601,13 @@ else scrollbar.m_UseEdgeButtons = b; } - else if (attr_name == "width") + else if (attr_name == "breadth") { float f; if (!GUI::ParseString(attr_value.FromUTF8(), f)) LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); else - scrollbar.m_Width = f; + scrollbar.m_Breadth = f; } else if (attr_name == "minimum_bar_size") { Index: source/gui/CGUIScrollBarVertical.h =================================================================== --- source/gui/CGUIScrollBarVertical.h +++ source/gui/CGUIScrollBarVertical.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -16,22 +16,10 @@ */ /* -A GUI ScrollBar - ---Overview-- - - A GUI Scrollbar, this class doesn't present all functionality - to the scrollbar, it just controls the drawing and a wrapper - for interaction with it. - ---Usage-- - - Used in everywhere scrollbars are needed, like in a combobox for instance. - ---More info-- - - Check GUI.h - + A vertical GUI Scrollbar, this class doesn't present all functionality + to the scrollbar, it just controls the drawing, handles some events, + and provides a wrapper for interaction with itself. Actual tracking + of how far we've scrolled inside the owner is handled elsewhere. */ #ifndef INCLUDED_CGUISCROLLBARVERTICAL @@ -52,15 +40,29 @@ virtual ~CGUIScrollBarVertical(); public: + + virtual void Draw(); + /** - * Draw the scroll-bar + * Setup the scrollbar. Sets the size, length and position. + * An object owning scrollbars still has to call this (preferably + * in the object's own Setup function), it isn't called + * automatically. There are two variations covering several common + * uses. + * + * The first assumes that the content is inside the host and thus + * uses the host's dimensions. + * + * The second permits a CRect defining the dimensions of the + * scrollable content to be passed. Any object that uses this + * variant has to set a scroll range. */ - virtual void Draw(); + virtual void Setup(); + virtual void Setup(const CRect& content); /** - * If an object that contains a scrollbar has got messages, send - * them to the scroll-bar and it will see if the message regarded - * itself. + * If an object containing one (or more) scrollbars receives messages, + * pass the messages on to the scrollbar to be dealt with as appropriate. * * @see IGUIObject#HandleMessage() */ @@ -71,38 +73,25 @@ */ virtual void SetPosFromMousePos(const CPos& mouse); - /** - * @see IGUIScrollBar#HoveringButtonMinus - */ virtual bool HoveringButtonMinus(const CPos& mouse); - - /** - * @see IGUIScrollBar#HoveringButtonPlus - */ virtual bool HoveringButtonPlus(const CPos& mouse); - /** - * Set Right Aligned - * @param align Alignment - */ void SetRightAligned(const bool& align) { m_RightAligned = align; } /** * Get the rectangle of the actual BAR. - * @return Rectangle, CRect */ virtual CRect GetBarRect() const; /** * Get the rectangle of the outline of the scrollbar, every component of the - * scroll-bar should be inside this area. - * @return Rectangle, CRect + * scrollbar should be inside this area. */ virtual CRect GetOuterRect() const; protected: /** - * Should the scroll bar proceed to the left or to the right of the m_X value. + * Should the scrollbar be drawn on the left or on the right of the m_X value. * Notice, this has nothing to do with where the owner places it. */ bool m_RightAligned; Index: source/gui/CGUIScrollBarVertical.cpp =================================================================== --- source/gui/CGUIScrollBarVertical.cpp +++ source/gui/CGUIScrollBarVertical.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -16,14 +16,10 @@ */ #include "precompiled.h" - #include "CGUIScrollBarVertical.h" - #include "GUI.h" - #include "ps/CLogger.h" - CGUIScrollBarVertical::CGUIScrollBarVertical() { } @@ -32,6 +28,31 @@ { } +void CGUIScrollBarVertical::Setup() +{ + CRect host = m_pHostObject->GetCachedSize(); + CRect content = m_pHostObject->GetContentSize(); + + SetScrollRange(content.GetHeight()); + Setup(host); + + int length = host.bottom - host.top; + if (content.GetWidth() > host.GetWidth()) + length -= GetStyle()->m_Breadth; + SetLength(length); +} + +void CGUIScrollBarVertical::Setup(const CRect& content) +{ + SetScrollSpace(content.GetHeight()); + + SetX(m_RightAligned ? content.right : content.left); + SetY(content.top); + SetZ(m_pHostObject->GetBufferedZ()); + + SetLength(content.bottom - content.top); +} + void CGUIScrollBarVertical::SetPosFromMousePos(const CPos& mouse) { if (!GetStyle()) @@ -43,8 +64,7 @@ float emptyBackground = m_Length - m_BarSize; if (GetStyle()->m_UseEdgeButtons) - emptyBackground -= GetStyle()->m_Width * 2; - + emptyBackground -= GetStyle()->m_Breadth * 2; m_Pos = m_PosWhenPressed + GetMaxPos() * (mouse.y - m_BarPressedAtPos.y) / emptyBackground; } @@ -52,23 +72,23 @@ { if (!GetStyle()) { - LOGWARNING("Attempt to draw scrollbar without a style."); + LOGWARNING("Attempt to draw a vertical scrollbar without a style."); return; } - if (GetGUI() && IsVisible()) + if (GetGUI() && IsNeeded()) { CRect outline = GetOuterRect(); GetGUI()->DrawSprite( GetStyle()->m_SpriteBackVertical, 0, - m_Z+0.1f, + m_Z + 0.1f, CRect( outline.left, - outline.top + (GetStyle()->m_UseEdgeButtons ? GetStyle()->m_Width : 0), + outline.top + (GetStyle()->m_UseEdgeButtons ? GetStyle()->m_Breadth : 0), outline.right, - outline.bottom - (GetStyle()->m_UseEdgeButtons ? GetStyle()->m_Width : 0) + outline.bottom - (GetStyle()->m_UseEdgeButtons ? GetStyle()->m_Breadth : 0) ) ); @@ -100,22 +120,22 @@ GetGUI()->DrawSprite( *button_top, 0, - m_Z+0.2f, + m_Z + 0.2f, CRect( outline.left, outline.top, outline.right, - outline.top+GetStyle()->m_Width + outline.top + GetStyle()->m_Breadth ) ); GetGUI()->DrawSprite( *button_bottom, 0, - m_Z+0.2f, + m_Z + 0.2f, CRect( outline.left, - outline.bottom-GetStyle()->m_Width, + outline.bottom - GetStyle()->m_Breadth, outline.right, outline.bottom ) @@ -133,6 +153,20 @@ void CGUIScrollBarVertical::HandleMessage(SGUIMessage& Message) { + switch (Message.type) + { + case GUIM_MOUSE_WHEEL_UP: + ScrollMinus(); + break; + + case GUIM_MOUSE_WHEEL_DOWN: + ScrollPlus(); + break; + + default: + break; + } + IGUIScrollBar::HandleMessage(Message); } @@ -148,14 +182,14 @@ if (GetStyle()->m_UseEdgeButtons) { - from += GetStyle()->m_Width; - to -= GetStyle()->m_Width; + from += GetStyle()->m_Breadth; + to -= GetStyle()->m_Breadth; } ret.top = from + (to - from) * m_Pos / GetMaxPos(); ret.bottom = ret.top + m_BarSize; - ret.right = m_X + (m_RightAligned ? 0 : GetStyle()->m_Width); - ret.left = ret.right - GetStyle()->m_Width; + ret.right = m_X + (m_RightAligned ? 0 : GetStyle()->m_Breadth); + ret.left = ret.right - GetStyle()->m_Breadth; return ret; } @@ -168,8 +202,8 @@ ret.top = m_Y; ret.bottom = m_Y+m_Length; - ret.right = m_X + (m_RightAligned ? 0 : GetStyle()->m_Width); - ret.left = ret.right - GetStyle()->m_Width; + ret.right = m_X + (m_RightAligned ? 0 : GetStyle()->m_Breadth); + ret.left = ret.right - GetStyle()->m_Breadth; return ret; } @@ -179,12 +213,12 @@ if (!GetStyle()) return false; - float StartX = m_RightAligned ? m_X-GetStyle()->m_Width : m_X; + float StartX = m_RightAligned ? m_X-GetStyle()->m_Breadth : m_X; return mouse.x >= StartX && - mouse.x <= StartX + GetStyle()->m_Width && + mouse.x <= StartX + GetStyle()->m_Breadth && mouse.y >= m_Y && - mouse.y <= m_Y + GetStyle()->m_Width; + mouse.y <= m_Y + GetStyle()->m_Breadth; } bool CGUIScrollBarVertical::HoveringButtonPlus(const CPos& mouse) @@ -192,10 +226,10 @@ if (!GetStyle()) return false; - float StartX = m_RightAligned ? m_X-GetStyle()->m_Width : m_X; + float StartX = m_RightAligned ? m_X-GetStyle()->m_Breadth : m_X; return mouse.x > StartX && - mouse.x < StartX + GetStyle()->m_Width && - mouse.y > m_Y + m_Length - GetStyle()->m_Width && + mouse.x < StartX + GetStyle()->m_Breadth && + mouse.y > m_Y + m_Length - GetStyle()->m_Breadth && mouse.y < m_Y + m_Length; } Index: source/gui/CInput.cpp =================================================================== --- source/gui/CInput.cpp +++ source/gui/CInput.cpp @@ -66,7 +66,7 @@ CFG_GET_VAL("gui.cursorblinkrate", m_CursorBlinkRate); - // Add scroll-bar + // Add scrollbar CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(); bar->SetRightAligned(true); AddScrollBar(bar); @@ -795,17 +795,14 @@ bool scrollbar; GUI::GetSetting(this, "scrollbar", scrollbar); - // Update scroll-bar + // Update scrollbar // TODO Gee: (2004-09-01) Is this really updated each time it should? if (scrollbar && (Message.value == CStr("size") || Message.value == CStr("z") || Message.value == CStr("absolute"))) { - GetScrollBar(0).SetX(m_CachedActualSize.right); - GetScrollBar(0).SetY(m_CachedActualSize.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top); + GetScrollBar(0).Setup(); } // Update scrollbar @@ -859,7 +856,7 @@ // Check if we're selecting the scrollbar if (GetScrollBar(0).GetStyle() && multiline) { - if (GetMousePos().x > m_CachedActualSize.right - GetScrollBar(0).GetStyle()->m_Width) + if (GetMousePos().x > m_CachedActualSize.right - GetScrollBar(0).GetStyle()->m_Breadth) break; } @@ -1020,10 +1017,7 @@ case GUIM_LOAD: { - GetScrollBar(0).SetX(m_CachedActualSize.right); - GetScrollBar(0).SetY(m_CachedActualSize.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top); + GetScrollBar(0).Setup(); CStr scrollbar_style; GUI::GetSetting(this, "scrollbar_style", scrollbar_style); @@ -1082,12 +1076,7 @@ bool scrollbar; GUI::GetSetting(this, "scrollbar", scrollbar); if (scrollbar) - { - GetScrollBar(0).SetX(m_CachedActualSize.right); - GetScrollBar(0).SetY(m_CachedActualSize.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top); - } + GetScrollBar(0).Setup(); } void CInput::Draw() @@ -1844,13 +1833,14 @@ // add the final row (even if empty) m_CharacterPositions.insert(current_line, row); + // Update scrollbar if needed bool scrollbar; GUI::GetSetting(this, "scrollbar", scrollbar); - // Update scollbar if (scrollbar) { - GetScrollBar(0).SetScrollRange(m_CharacterPositions.size() * font.GetLineSpacing() + buffer_zone*2.f); - GetScrollBar(0).SetScrollSpace(m_CachedActualSize.GetHeight()); + float height = m_CharacterPositions.size() * font.GetLineSpacing() + buffer_zone * 2.f; + m_CachedContentSize = CRect(0.0f, 0.0f, GetTextAreaWidth(), height); + GetScrollBar(0).Setup(); } } @@ -2003,7 +1993,7 @@ GUI::GetSetting(this, "buffer_zone", buffer_zone); if (scrollbar && GetScrollBar(0).GetStyle()) - return m_CachedActualSize.GetWidth() - buffer_zone*2.f - GetScrollBar(0).GetStyle()->m_Width; + return m_CachedActualSize.GetWidth() - buffer_zone*2.f - GetScrollBar(0).GetStyle()->m_Breadth; else return m_CachedActualSize.GetWidth() - buffer_zone*2.f; } Index: source/gui/CList.h =================================================================== --- source/gui/CList.h +++ source/gui/CList.h @@ -26,7 +26,7 @@ * text-object for each element, which will be managed * by the IGUITextOwner structure. * - * A scroll-bar will appear when needed. This will be + * A scrollbar will appear when needed. This will be * achieved with the IGUIScrollBarOwner structure. */ class CList : public IGUIScrollBarOwner, public IGUITextOwner Index: source/gui/CList.cpp =================================================================== --- source/gui/CList.cpp +++ source/gui/CList.cpp @@ -57,7 +57,7 @@ GUI::SetSetting(this, "selected", -1); GUI::SetSetting(this, "hovered", -1); - // Add scroll-bar + // Add scrollbar CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(); bar->SetRightAligned(true); AddScrollBar(bar); @@ -97,9 +97,9 @@ GUI::GetSetting(this, "scrollbar", scrollbar); float width = GetListRect().GetWidth(); - // remove scrollbar if applicable + // Reduce width by the breadth of the scrollbar if applicable. if (scrollbar && GetScrollBar(0).GetStyle()) - width -= GetScrollBar(0).GetStyle()->m_Width; + width -= GetScrollBar(0).GetStyle()->m_Breadth; float buffer_zone = 0.f; GUI::GetSetting(this, "buffer_zone", buffer_zone); @@ -134,13 +134,7 @@ if (scrollbar) { GetScrollBar(0).SetScrollRange(m_ItemsYPositions.back()); - GetScrollBar(0).SetScrollSpace(GetListRect().GetHeight()); - - CRect rect = GetListRect(); - GetScrollBar(0).SetX(rect.right); - GetScrollBar(0).SetY(rect.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(rect.bottom - rect.top); + GetScrollBar(0).Setup(GetListRect()); } } @@ -167,19 +161,8 @@ ScriptEvent("selectionchange"); } - if (Message.value == "scrollbar") - SetupText(); - - // Update scrollbar - if (Message.value == "scrollbar_style") - { - CStr scrollbar_style; - GUI::GetSetting(this, Message.value, scrollbar_style); - - GetScrollBar(0).SetScrollBarStyle(scrollbar_style); - + if (Message.value == "scrollbar" || Message.value == "scrollbar_style") SetupText(); - } break; @@ -241,14 +224,6 @@ break; } - case GUIM_LOAD: - { - CStr scrollbar_style; - GUI::GetSetting(this, "scrollbar_style", scrollbar_style); - GetScrollBar(0).SetScrollBarStyle(scrollbar_style); - break; - } - default: break; } @@ -386,7 +361,7 @@ m_ItemsYPositions[i] - scroll > rect.GetHeight()) continue; - // Clipping area (we'll have to substract the scrollbar) + // Clipping area (we'll have to subtract the scrollbar) CRect cliparea = GetListRect(); if (scrollbar) @@ -536,7 +511,7 @@ mouse.y += scroll; // Mouse is over scrollbar - if (scrollbar && GetScrollBar(0).IsVisible() && + if (scrollbar && GetScrollBar(0).IsNeeded() && mouse.x >= GetScrollBar(0).GetOuterRect().left && mouse.x <= GetScrollBar(0).GetOuterRect().right) return -1; Index: source/gui/COList.h =================================================================== --- source/gui/COList.h +++ source/gui/COList.h @@ -38,7 +38,7 @@ * * The list can be sorted dynamically by JS code when a * heading is clicked. - * A scroll-bar will appear when needed. + * A scrollbar will appear when needed. */ class COList : public CList { Index: source/gui/COList.cpp =================================================================== --- source/gui/COList.cpp +++ source/gui/COList.cpp @@ -64,7 +64,7 @@ float width = GetListRect().GetWidth(); // remove scrollbar if applicable if (scrollbar && GetScrollBar(0).GetStyle()) - width -= GetScrollBar(0).GetStyle()->m_Width; + width -= GetScrollBar(0).GetStyle()->m_Breadth; m_TotalAvailableColumnWidth = width; @@ -111,14 +111,8 @@ if (scrollbar) { - CRect rect = GetListRect(); GetScrollBar(0).SetScrollRange(m_ItemsYPositions.back()); - GetScrollBar(0).SetScrollSpace(rect.GetHeight()); - - GetScrollBar(0).SetX(rect.right); - GetScrollBar(0).SetY(rect.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(rect.bottom - rect.top); + GetScrollBar(0).Setup(GetListRect()); } } Index: source/gui/CText.h =================================================================== --- source/gui/CText.h +++ source/gui/CText.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -59,11 +59,6 @@ * Draws the Text */ virtual void Draw(); - - /** - * Placement of text. Ignored when scrollbars are active. - */ - CPos m_TextPos; }; #endif // INCLUDED_CTEXT Index: source/gui/CText.cpp =================================================================== --- source/gui/CText.cpp +++ source/gui/CText.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -51,7 +51,7 @@ GUI::SetSetting(this, "scrollbar", false); GUI::SetSetting(this, "clip", true); - // Add scroll-bar + // Add scrollbar CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(); bar->SetRightAligned(true); AddScrollBar(bar); @@ -83,19 +83,20 @@ GUI::GetSetting(this, "scrollbar", scrollbar); float width = m_CachedActualSize.GetWidth(); - // remove scrollbar if applicable - if (scrollbar && GetScrollBar(0).GetStyle()) - width -= GetScrollBar(0).GetStyle()->m_Width; + // Reduce width by scrollbar breadth if applicable. + if (scrollbar && GetScrollBar(0).GetStyle()) + width -= GetScrollBar(0).GetStyle()->m_Breadth; float buffer_zone = 0.f; GUI::GetSetting(this, "buffer_zone", buffer_zone); *m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, width, buffer_zone, this); - if (!scrollbar) - CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]); + // Text generation returns an object with an incorrectly measured width - sometimes wider than its container(!) + m_GeneratedTexts[0]->m_Size.cx = std::min(width, m_GeneratedTexts[0]->m_Size.cx); + m_CachedContentSize = m_GeneratedTexts[0]->m_Size; - // Setup scrollbar + // Setup scrollbar, if applicable. if (scrollbar) { bool scroll_top = false, scroll_bottom = false; @@ -110,13 +111,7 @@ if (scroll_bottom && GetScrollBar(0).GetPos() > GetScrollBar(0).GetMaxPos() - 1.5f) bottom = true; - GetScrollBar(0).SetScrollRange(m_GeneratedTexts[0]->m_Size.cy); - GetScrollBar(0).SetScrollSpace(m_CachedActualSize.GetHeight()); - - GetScrollBar(0).SetX(m_CachedActualSize.right); - GetScrollBar(0).SetY(m_CachedActualSize.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top); + GetScrollBar(0).Setup(); if (bottom) GetScrollBar(0).SetPos(GetScrollBar(0).GetMaxPos()); @@ -128,55 +123,21 @@ void CText::HandleMessage(SGUIMessage& Message) { IGUIScrollBarOwner::HandleMessage(Message); - //IGUITextOwner::HandleMessage(Message); <== placed it after the switch instead! switch (Message.type) { case GUIM_SETTINGS_UPDATED: - if (Message.value == "scrollbar") - SetupText(); - - // Update scrollbar - if (Message.value == "scrollbar_style") - { - CStr scrollbar_style; - GUI::GetSetting(this, Message.value, scrollbar_style); - - GetScrollBar(0).SetScrollBarStyle(scrollbar_style); - + if (Message.value == "scrollbar" || Message.value == "scrollbar_style") SetupText(); - } - break; case GUIM_MOUSE_WHEEL_DOWN: - { - GetScrollBar(0).ScrollPlus(); - // Since the scroll was changed, let's simulate a mouse movement - // to check if scrollbar now is hovered - SGUIMessage msg(GUIM_MOUSE_MOTION); - HandleMessage(msg); - break; - } case GUIM_MOUSE_WHEEL_UP: { - GetScrollBar(0).ScrollMinus(); - // Since the scroll was changed, let's simulate a mouse movement - // to check if scrollbar now is hovered - SGUIMessage msg(GUIM_MOUSE_MOTION); - HandleMessage(msg); - break; - } - case GUIM_LOAD: - { - GetScrollBar(0).SetX(m_CachedActualSize.right); - GetScrollBar(0).SetY(m_CachedActualSize.top); - GetScrollBar(0).SetZ(GetBufferedZ()); - GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top); - - CStr scrollbar_style; - GUI::GetSetting(this, "scrollbar_style", scrollbar_style); - GetScrollBar(0).SetScrollBarStyle(scrollbar_style); + bool scrollbar; + GUI::GetSetting(this, "scrollbar", scrollbar); + if (!scrollbar) + m_pParent->HandleMessage(Message); break; } @@ -184,6 +145,7 @@ break; } + // Deliberately placed after the switch IGUITextOwner::HandleMessage(Message); } @@ -194,9 +156,7 @@ // First call draw on ScrollBarOwner bool scrollbar; GUI::GetSetting(this, "scrollbar", scrollbar); - if (scrollbar) - // Draw scrollbar IGUIScrollBarOwner::Draw(); if (!GetGUI()) @@ -243,7 +203,11 @@ if (scrollbar) DrawText(0, color, m_CachedActualSize.TopLeft() - CPos(0.f, scroll), bz+0.1f, cliparea); else - DrawText(0, color, m_TextPos, bz+0.1f, cliparea); + { + CPos textPos; + CalculateTextPosition(m_CachedActualSize, textPos, *m_GeneratedTexts[0]); + DrawText(0, color, textPos, bz + 0.1f, cliparea); + } } bool CText::MouseOverIcon() Index: source/gui/IGUIObject.h =================================================================== --- source/gui/IGUIObject.h +++ source/gui/IGUIObject.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -160,6 +160,9 @@ /// Get object name void SetName(const CStr& Name) { m_Name = Name; } + /// Get object size + const CRect& GetCachedSize() const { return m_CachedActualSize; } + // Get Presentable name. // Will change all internally set names to something like "" CStr GetPresentableName() const; @@ -338,15 +341,6 @@ */ void LoadStyle(const SGUIStyle& Style); - /** - * Returns not the Z value, but the actual buffered Z value, i.e. if it's - * defined relative, then it will check its parent's Z value and add - * the relativity. - * - * @return Actual Z value on the screen. - */ - virtual float GetBufferedZ() const; - void SetGUI(CGUI* const& pGUI); /** @@ -372,6 +366,15 @@ */ void SetFocus(); + /** + * Returns not the Z value, but the actual buffered Z value, i.e. if it's + * defined relative, then it will check its parent's Z value and add + * the relativity. + * + * @return Actual Z value on the screen. + */ + virtual float GetBufferedZ() const; + protected: /** * Check if object is focused. @@ -414,6 +417,12 @@ */ CRect m_CachedActualSize; + /** + * Like `m_CachedActualSize` above, except this stores a cached + * value of the combined size of all the children. + */ + CRect m_CachedContentSize; + /** * Send event to this GUI object (HandleMessage and ScriptEvent) * Index: source/gui/IGUIScrollBar.h =================================================================== --- source/gui/IGUIScrollBar.h +++ source/gui/IGUIScrollBar.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -40,9 +40,9 @@ #include "GUI.h" /** - * The GUI Scroll-bar style. Tells us how scroll-bars look and feel. + * The GUI Scrollbar style. Tells us how scrollbars look and feel. * - * A scroll-bar style can choose whether to support horizontal, vertical + * A scrollbar style can choose whether to support horizontal, vertical * or both. * * @see IGUIScrollBar @@ -55,9 +55,11 @@ //@{ /** - * Width of bar, also both sides of the edge buttons. + * Breadth of bar, from side to side. It is the width of a vertical bar + * and the height of a horizontal bar. It is also used as the dimensions + * of both sides of the edge buttons. */ - float m_Width; + float m_Breadth; /** * Scrollable with the wheel. @@ -84,7 +86,7 @@ float m_MinimumBarSize; /** - * Sometimes you would like your scroll bar to have a fixed maximum size + * Sometimes you would like your scrollbar to have a fixed maximum size * so that the texture does not get too stretched, you can set a maximum * in pixels. */ @@ -140,17 +142,17 @@ /** - * The GUI Scroll-bar, used everywhere there is a scroll-bar in the game. + * The GUI Scrollbar, used everywhere there is a scrollbar in the game. * - * To include a scroll-bar to an object, inherent the object from - * IGUIScrollBarOwner and call AddScrollBar() to add the scroll-bars. + * To include a scrollbar to an object, inherit the object from + * IGUIScrollBarOwner and call AddScrollBar() to add the scrollbars. * * It's also important that the scrollbar is located within the parent * object's mouse over area. Otherwise the input won't be sent to the - * scroll-bar. + * scrollbar. * - * The class does not provide all functionality to the scroll-bar, many - * things the parent of the scroll-bar, must provide. Like a combo-box. + * The class does not provide all functionality to the scrollbar, many + * things the parent of the scrollbar, must provide. Like a combo-box. */ class IGUIScrollBar { @@ -160,19 +162,26 @@ public: /** - * Draw the scroll-bar + * Draw the scrollbar */ virtual void Draw() = 0; /** * If an object that contains a scrollbar has got messages, send - * them to the scroll-bar and it will see if the message regarded + * them to the scrollbar and it will see if the message regarded * itself. * * @see IGUIObject#HandleMessage() */ virtual void HandleMessage(SGUIMessage& Message) = 0; + /** + * These are overridden by the *Vertical subclass + * and are not actually implemented within this class. + */ + virtual void Setup() = 0; + virtual void Setup(const CRect& content) = 0; + /** * Set m_Pos with g_mouse_x/y input, i.e. when draggin. */ @@ -210,9 +219,10 @@ float GetMaxPos() const { return std::max(1.f, m_ScrollRange - m_ScrollSpace); } /** - * Get the value of m_Pos that corresponds to the bottom of the scrollable region + * Gets whether a scrollbar is actually needed, based on whether the + * scroll range is large enough to warrant one. */ - float IsVisible() const { return GetMaxPos() != 1.f; } + bool IsNeeded() const { return GetMaxPos() != 1.f; } /** * Increase scroll one step @@ -235,7 +245,7 @@ virtual void ScrollMinusPlenty() { m_Pos -= 90.f; UpdatePosBoundaries(); } /** - * Set host object, must be done almost at creation of scroll bar. + * Set host object, must be done almost at creation of the scrollbar. * @param pOwner Pointer to host object. */ void SetHostObject(IGUIScrollBarOwner* pOwner) { m_pHostObject = pOwner; } @@ -253,10 +263,10 @@ void SetGUI(CGUI* pGUI) { m_pGUI = pGUI; } /** - * Set Width - * @param width Width + * Set the Breadth of the scrollbar + * @param breadth Breadth */ - void SetWidth(float width) { m_Width = width; } + void SetBreadth(float breadth) { m_Breadth = breadth; } /** * Set X Position @@ -277,7 +287,7 @@ void SetZ(float z) { m_Z = z; } /** - * Set Length of scroll bar + * Set the length of the scrollbar * @param length Length */ void SetLength(float length) { m_Length = length; } @@ -301,26 +311,26 @@ void SetBarPressed(bool b) { m_BarPressed = b; } /** - * Set Scroll bar style string - * @param style String with scroll bar style reference name + * Set the Scrollbar style + * @param style String consisting of the name of the scrollbar style */ void SetScrollBarStyle(const CStr& style) { m_ScrollBarStyle = style; } /** * Get style used by the scrollbar - * @return Scroll bar style struct. + * @return Scrollbar style struct. */ const SGUIScrollBarStyle* GetStyle() const; /** - * Get the rectangle of the actual BAR. not the whole scroll-bar. + * Get the rectangle of the actual BAR. not the whole scrollbar. * @return Rectangle, CRect */ virtual CRect GetBarRect() const = 0; /** * Get the rectangle of the outline of the scrollbar, every component of the - * scroll-bar should be inside this area. + * scrollbar should be inside this area. * @return Rectangle, CRect */ virtual CRect GetOuterRect() const = 0; @@ -344,9 +354,9 @@ //@{ /** - * Width of the scroll bar + * Breadth of the scrollbar */ - float m_Width; + float m_Breadth; /** * Absolute X Position @@ -384,12 +394,12 @@ float m_BarSize; /** - * Scroll bar style reference name + * Scrollbar style reference name */ CStr m_ScrollBarStyle; /** - * Pointer to scroll bar style used. + * Pointer to the scrollbar style used. */ SGUIScrollBarStyle *m_pStyle; @@ -435,7 +445,7 @@ bool m_ButtonMinusPressed, m_ButtonPlusPressed; /** - * Position of scroll bar, 0 means scrolled all the way to one side. + * Position of scrollbar, 0 means scrolled all the way to one side. * It is measured in pixels, it is up to the host to make it actually * apply in pixels. */ Index: source/gui/IGUIScrollBar.cpp =================================================================== --- source/gui/IGUIScrollBar.cpp +++ source/gui/IGUIScrollBar.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,7 +23,7 @@ IGUIScrollBar::IGUIScrollBar() : m_pStyle(NULL), m_pGUI(NULL), m_X(300.f), m_Y(300.f), m_ScrollRange(1.f), m_ScrollSpace(0.f), // MaxPos: not 0, due to division. - m_Length(200.f), m_Width(20.f), + m_Length(200.f), m_Breadth(20.f), m_BarSize(0.f), m_Pos(0.f), m_ButtonPlusPressed(false), m_ButtonMinusPressed(false), @@ -49,7 +49,7 @@ // Check for edge buttons if (GetStyle()->m_UseEdgeButtons) - length -= GetStyle()->m_Width * 2.f; + length -= GetStyle()->m_Breadth * 2.f; // Check min and max are valid if (min > length) @@ -170,7 +170,8 @@ case GUIM_MOUSE_WHEEL_UP: { - ScrollMinus(); + if (m_Pos <= 0) + m_pHostObject->m_pParent->HandleMessage(Message); // Since the scroll was changed, let's simulate a mouse movement // to check if scrollbar now is hovered SGUIMessage msg(GUIM_MOUSE_MOTION); @@ -180,7 +181,8 @@ case GUIM_MOUSE_WHEEL_DOWN: { - ScrollPlus(); + if (m_Pos >= GetMaxPos()) + m_pHostObject->m_pParent->HandleMessage(Message); // Since the scroll was changed, let's simulate a mouse movement // to check if scrollbar now is hovered SGUIMessage msg(GUIM_MOUSE_MOTION); @@ -188,6 +190,23 @@ break; } + case GUIM_SETTINGS_UPDATED: + if (Message.value == "scrollbar_style") + { + CStr scrollbar_style; + GUI::GetSetting(m_pHostObject, "scrollbar_style", scrollbar_style); + SetScrollBarStyle(scrollbar_style); + } + break; + + case GUIM_LOAD: + { + CStr scrollbar_style; + GUI::GetSetting(m_pHostObject, "scrollbar_style", scrollbar_style); + SetScrollBarStyle(scrollbar_style); + break; + } + default: break; } Index: source/gui/IGUIScrollBarOwner.h =================================================================== --- source/gui/IGUIScrollBarOwner.h +++ source/gui/IGUIScrollBarOwner.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -25,7 +25,7 @@ /** * Base-class this if you want an object to contain - * one, or several, scroll-bars. + * one, or several, scrollbars. * * @see IGUIObject * @see IGUIScrollBar @@ -56,12 +56,12 @@ virtual const SGUIScrollBarStyle* GetScrollBarStyle(const CStr& style) const; /** - * Add a scroll-bar + * Add a scrollbar */ virtual void AddScrollBar(IGUIScrollBar* scrollbar); /** - * Get Scroll Bar reference (it should be transparent it's actually + * Get scrollbar reference (it should be transparent it's actually * pointers). */ virtual IGUIScrollBar& GetScrollBar(const int& index) @@ -70,11 +70,19 @@ } /** - * Get the position of the scroll bar at @param index. + * Get the position of the scrollbar at @param index. * Equivalent to GetScrollbar(index).GetPos(). */ virtual float GetScrollBarPos(const int index) const; + /** + * Get the calculated size of the content + * + * If the size hasn't been calculated (by a subclass) then this will + * return a CRect that is still new + */ + const CRect& GetContentSize() const { return m_CachedContentSize; } + protected: /**