Ticket #3415: t3415_fix_lists_invisible_scrollbar_v1.patch

File t3415_fix_lists_invisible_scrollbar_v1.patch, 13.6 KB (added by elexis, 9 years ago)

Fixes the bug (48 lines of context to make reviewing easier).

  • source/gui/CDropDown.cpp

     
    6868void CDropDown::HandleMessage(SGUIMessage& Message)
    6969{
    7070    // Important
    7171
    7272    switch (Message.type)
    7373    {
    7474    case GUIM_SETTINGS_UPDATED:
    7575    {
    7676        // Update cached list rect
    7777        if (Message.value == "size" ||
    7878            Message.value == "absolute" ||
    7979            Message.value == "dropdown_size" ||
    8080            Message.value == "dropdown_buffer" ||
    8181            Message.value == "scrollbar_style" ||
    8282            Message.value == "button_width")
    8383        {
    8484            SetupListRect();
    8585        }
    8686
    8787        break;
    8888    }
    8989
    9090    case GUIM_MOUSE_MOTION:
    9191    {
    9292        if (!m_Open)
    9393            break;
    9494
    9595        CPos mouse = GetMousePos();
    9696
    9797        if (!GetListRect().PointInside(mouse))
    9898            break;
    9999
    100100        bool scrollbar;
    101101        CGUIList* pList;
    102102        GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
    103103        GUI<CGUIList>::GetSettingPointer(this, "list", pList);
    104104        float scroll = 0.f;
    105105        if (scrollbar)
    106106            scroll = GetScrollBar(0).GetPos();
    107107
    108108        CRect rect = GetListRect();
    109109        mouse.y += scroll;
    110110        int set = -1;
    111111        for (int i = 0; i < (int)pList->m_Items.size(); ++i)
    112112        {
    113113            if (mouse.y >= rect.top + m_ItemsYPositions[i] &&
    114114                mouse.y < rect.top + m_ItemsYPositions[i+1] &&
    115115                // mouse is not over scroll-bar
    116                 !(mouse.x >= GetScrollBar(0).GetOuterRect().left &&
    117                 mouse.x <= GetScrollBar(0).GetOuterRect().right))
     116                (m_HideScrollBar ||
     117                    mouse.x < GetScrollBar(0).GetOuterRect().left ||
     118                    mouse.x > GetScrollBar(0).GetOuterRect().right))
    118119            {
    119120                set = i;
    120121            }
    121122        }
    122123
    123124        if (set != -1)
    124125        {
    125126            m_ElementHighlight = set;
    126127            //UpdateAutoScroll();
    127128        }
    128129
    129130        break;
    130131    }
    131132
    132133    case GUIM_MOUSE_ENTER:
    133134    {
    134135        bool enabled;
    135136        GUI<bool>::GetSetting(this, "enabled", enabled);
    136137        if (!enabled)
    137138            break;
    138139
    139140        CStrW soundPath;
    140141        if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_enter", soundPath) == PSRETURN_OK && !soundPath.empty())
    141142            g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    142143        break;
    143144    }
    144145
    145146    case GUIM_MOUSE_LEAVE:
    146147    {
    147148        GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
    148149
    149150        bool enabled;
    150151        GUI<bool>::GetSetting(this, "enabled", enabled);
    151152        if (!enabled)
    152153            break;
    153154
    154155        CStrW soundPath;
    155156        if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_leave", soundPath) == PSRETURN_OK && !soundPath.empty())
    156157            g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    157158        break;
    158159    }
    159160
    160161    // We can't inherent this routine from CList, because we need to include
    161162    // a mouse click to open the dropdown, also the coordinates are changed.
    162163    case GUIM_MOUSE_PRESS_LEFT:
    163164    {
    164165        bool enabled;
    165166        GUI<bool>::GetSetting(this, "enabled", enabled);
    166167        if (!enabled)
    167168        {
    168169            CStrW soundPath;
    169170            if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_disabled", soundPath) == PSRETURN_OK && !soundPath.empty())
    170171                g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    171172            break;
    172173        }
    173174
    174175        if (!m_Open)
    175176        {
    176177            CGUIList* pList;
    177178            GUI<CGUIList>::GetSettingPointer(this, "list", pList);
    178179            if (pList->m_Items.empty())
    179180                return;
    180181
    181182            m_Open = true;
    182183            GetScrollBar(0).SetZ(GetBufferedZ());
    183184            GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
    184185
    185186            // Start at the position of the selected item, if possible.
    186187            GetScrollBar(0).SetPos(m_ItemsYPositions.empty() ? 0 : m_ItemsYPositions[m_ElementHighlight] - 60);
    187188
    188189            CStrW soundPath;
    189190            if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_opened", soundPath) == PSRETURN_OK && !soundPath.empty())
    190191                g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    191192
    192193            return; // overshadow
    193194        }
    194195        else
    195196        {
    196197            CPos mouse = GetMousePos();
    197198
    198199            // If the regular area is pressed, then abort, and close.
    199200            if (m_CachedActualSize.PointInside(mouse))
    200201            {
    201202                m_Open = false;
    202203                GetScrollBar(0).SetZ(GetBufferedZ());
    203204
    204205                CStrW soundPath;
    205206                if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_closed", soundPath) == PSRETURN_OK && !soundPath.empty())
    206207                    g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    207208
    208209                return; // overshadow
    209210            }
    210211
    211             if (!(mouse.x >= GetScrollBar(0).GetOuterRect().left &&
    212                 mouse.x <= GetScrollBar(0).GetOuterRect().right) &&
    213                 mouse.y >= GetListRect().top)
     212            if (m_HideScrollBar ||
     213                mouse.x < GetScrollBar(0).GetOuterRect().left ||
     214                mouse.x > GetScrollBar(0).GetOuterRect().right ||
     215                mouse.y < GetListRect().top)
    214216            {
    215217                m_Open = false;
    216218                GetScrollBar(0).SetZ(GetBufferedZ());
    217219            }
    218220        }
    219221        break;
    220222    }
    221223
    222224    case GUIM_MOUSE_WHEEL_DOWN:
    223225    {
    224226        bool enabled;
    225227        GUI<bool>::GetSetting(this, "enabled", enabled);
    226228
    227229        // Don't switch elements by scrolling when open, causes a confusing interaction between this and the scrollbar.
    228230        if (m_Open || !enabled)
    229231            break;
    230232
    231233        GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
    232234        if (m_ElementHighlight + 1 >= (int)m_ItemsYPositions.size() - 1)
    233235            break;
    234236
    235237        ++m_ElementHighlight;
    236238        GUI<int>::SetSetting(this, "selected", m_ElementHighlight);
    237239        break;
    238240    }
    239241
    240242    case GUIM_MOUSE_WHEEL_UP:
    241243    {
    242244        bool enabled;
    243245        GUI<bool>::GetSetting(this, "enabled", enabled);
    244246
    245247        // Don't switch elements by scrolling when open, causes a confusing interaction between this and the scrollbar.
    246248        if (m_Open || !enabled)
    247249            break;
    248250
    249251        GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
    250252        if (m_ElementHighlight - 1 < 0)
    251253            break;
    252254
    253255        m_ElementHighlight--;
    254256        GUI<int>::SetSetting(this, "selected", m_ElementHighlight);
    255257        break;
    256258    }
    257259
    258260    case GUIM_LOST_FOCUS:
    259261    {
    260262        if (m_Open)
    261263        {
  • source/gui/CGUIScrollBarVertical.cpp

     
    99 * 0 A.D. is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1111 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1212 * GNU General Public License for more details.
    1313 *
    1414 * You should have received a copy of the GNU General Public License
    1515 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    1616 */
    1717
    1818#include "precompiled.h"
    1919
    2020#include "CGUIScrollBarVertical.h"
    2121
    2222#include "GUI.h"
    2323
    2424#include "ps/CLogger.h"
    2525
    2626
    2727CGUIScrollBarVertical::CGUIScrollBarVertical()
    2828{
    2929}
    3030
    3131CGUIScrollBarVertical::~CGUIScrollBarVertical()
    3232{
    3333}
    3434
    3535void CGUIScrollBarVertical::SetPosFromMousePos(const CPos& mouse)
    3636{
    3737    if (!GetStyle())
    3838        return;
    3939
    4040    /**
    4141     * Calculate the position for the top of the item being scrolled
    4242     */
    4343    float emptyBackground = m_Length - m_BarSize;
    4444    if (GetStyle()->m_UseEdgeButtons)
    4545        emptyBackground -= GetStyle()->m_Width * 2;
    4646    m_Pos = m_PosWhenPressed + GetMaxPos() * (mouse.y - m_BarPressedAtPos.y) / emptyBackground;
    4747}
    4848
    4949void CGUIScrollBarVertical::Draw()
    5050{
    5151    if (!GetStyle())
    5252    {
    5353        LOGWARNING("Attempt to draw scrollbar without a style.");
    5454        return;
    5555    }
    5656
    57     if (GetGUI() && GetMaxPos() != 1)
     57    if (GetGUI() && IsVisible())
    5858    {
    5959        CRect outline = GetOuterRect();
    6060
    6161        // Draw background
    6262        GetGUI()->DrawSprite(GetStyle()->m_SpriteBackVertical,
    6363                             0,
    6464                             m_Z+0.1f,
    6565                             CRect(outline.left,
    6666                                   outline.top+(GetStyle()->m_UseEdgeButtons?GetStyle()->m_Width:0),
    6767                                   outline.right,
    6868                                   outline.bottom-(GetStyle()->m_UseEdgeButtons?GetStyle()->m_Width:0))
    6969                             );
    7070
    7171        if (GetStyle()->m_UseEdgeButtons)
    7272        {
    7373            // Get Appropriate sprites
    7474            const CGUISpriteInstance* button_top;
    7575            const CGUISpriteInstance* button_bottom;
    7676
    7777            // figure out what sprite to use for top button
    7878            if (m_ButtonMinusHovered)
    7979            {
    8080                if (m_ButtonMinusPressed)
    8181                    button_top = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonTopPressed, GetStyle()->m_SpriteButtonTop);
    8282                else
    8383                    button_top = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonTopOver, GetStyle()->m_SpriteButtonTop);
    8484            }
    8585            else
    8686                button_top = &GetStyle()->m_SpriteButtonTop;
    8787
    8888            // figure out what sprite to use for bottom button
    8989            if (m_ButtonPlusHovered)
    9090            {
    9191                if (m_ButtonPlusPressed)
    9292                    button_bottom = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonBottomPressed, GetStyle()->m_SpriteButtonBottom);
    9393                else
    9494                    button_bottom = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonBottomOver, GetStyle()->m_SpriteButtonBottom);
    9595            }
    9696            else
    9797                button_bottom = &GetStyle()->m_SpriteButtonBottom;
    9898
    9999            // Draw top button
    100100            GetGUI()->DrawSprite(*button_top,
    101101                                 0,
    102102                                 m_Z+0.2f,
    103103                                 CRect(outline.left,
    104104                                       outline.top,
    105105                                       outline.right,
  • source/gui/CList.cpp

     
    155155            ScriptEvent("selectionchange");
    156156        }
    157157
    158158        if (Message.value == "scrollbar")
    159159            SetupText();
    160160
    161161        // Update scrollbar
    162162        if (Message.value == "scrollbar_style")
    163163        {
    164164            CStr scrollbar_style;
    165165            GUI<CStr>::GetSetting(this, Message.value, scrollbar_style);
    166166
    167167            GetScrollBar(0).SetScrollBarStyle(scrollbar_style);
    168168
    169169            SetupText();
    170170        }
    171171
    172172        break;
    173173
    174174    case GUIM_MOUSE_PRESS_LEFT:
    175175    {
    176176        bool enabled;
    177177        GUI<bool>::GetSetting(this, "enabled", enabled);
    178178        if (!enabled)
    179179        {
    180180            CStrW soundPath;
    181181            if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_disabled", soundPath) == PSRETURN_OK && !soundPath.empty())
    182182                g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    183183            break;
    184184        }
    185185
    186186        bool scrollbar;
    187187        CGUIList* pList;
    188188        GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
    189189        GUI<CGUIList>::GetSettingPointer(this, "list", pList);
    190190        float scroll = 0.f;
    191191        if (scrollbar)
    192192            scroll = GetScrollBar(0).GetPos();
    193193
    194194        CRect rect = GetListRect();
    195195        CPos mouse = GetMousePos();
    196196        mouse.y += scroll;
    197197        int set = -1;
    198198        for (int i = 0; i < (int)pList->m_Items.size(); ++i)
    199199        {
    200200            if (mouse.y >= rect.top + m_ItemsYPositions[i] &&
    201201                mouse.y < rect.top + m_ItemsYPositions[i+1] &&
    202202                // mouse is not over scroll-bar
    203                 !(mouse.x >= GetScrollBar(0).GetOuterRect().left &&
    204                 mouse.x <= GetScrollBar(0).GetOuterRect().right))
     203                (!scrollbar || !GetScrollBar(0).IsVisible() ||
     204                    mouse.x < GetScrollBar(0).GetOuterRect().left ||
     205                    mouse.x > GetScrollBar(0).GetOuterRect().right))
    205206            {
    206207                set = i;
    207208            }
    208209        }
    209210
    210211        if (set != -1)
    211212        {
    212213            GUI<int>::SetSetting(this, "selected", set);
    213214            UpdateAutoScroll();
    214215
    215216            CStrW soundPath;
    216217            if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty())
    217218                g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    218219        }
    219220        break;
    220221    }
    221222
    222223    case GUIM_LOAD:
    223224    {
    224225        CStr scrollbar_style;
    225226        GUI<CStr>::GetSetting(this, "scrollbar_style", scrollbar_style);
    226227        GetScrollBar(0).SetScrollBarStyle(scrollbar_style);
    227228        break;
    228229    }
    229230
    230231    default:
    231232        break;
    232233    }
    233234
    234235    IGUITextOwner::HandleMessage(Message);
    235236}
    236237
    237238InReaction CList::ManuallyHandleEvent(const SDL_Event_* ev)
    238239{
    239240    InReaction result = IN_PASS;
    240241
    241242    if (ev->ev.type == SDL_KEYDOWN)
    242243    {
    243244        int szChar = ev->ev.key.keysym.sym;
    244245
    245246        switch (szChar)
    246247        {
    247248        case SDLK_HOME:
    248249            SelectFirstElement();
    249250            UpdateAutoScroll();
    250251            result = IN_HANDLED;
    251252            break;
    252253
  • source/gui/IGUIScrollBar.h

     
    165165    virtual void Draw() = 0;
    166166
    167167    /**
    168168     * If an object that contains a scrollbar has got messages, send
    169169     * them to the scroll-bar and it will see if the message regarded
    170170     * itself.
    171171     *
    172172     * @see IGUIObject#HandleMessage()
    173173     */
    174174    virtual void HandleMessage(SGUIMessage& Message) = 0;
    175175
    176176    /**
    177177     * Set m_Pos with g_mouse_x/y input, i.e. when draggin.
    178178     */
    179179    virtual void SetPosFromMousePos(const CPos& mouse) = 0;
    180180
    181181    /**
    182182     * Hovering the scroll minus button
    183183     *
    184184     * @param mouse current mouse position
    185185     * @return True if mouse positions are hovering the button
    186186     */
    187187    virtual bool HoveringButtonMinus(const CPos& UNUSED(mouse)) { return false; }
    188188
    189189    /**
    190190     * Hovering the scroll plus button
    191191     *
    192192     * @param mouse current mouse position
    193193     * @return True if mouse positions are hovering the button
    194194     */
    195195    virtual bool HoveringButtonPlus(const CPos& UNUSED(mouse)) { return false; }
    196196
    197197    /**
    198198     * Get scroll-position
    199199     */
    200200    float GetPos() const { return m_Pos; }
    201201
    202202    /**
    203203     * Set scroll-position by hand
    204204     */
    205205    virtual void SetPos(float f) { m_Pos = f; UpdatePosBoundaries(); }
    206206
    207207    /**
    208208     * Get the value of m_Pos that corresponds to the bottom of the scrollable region
    209209     */
    210210    float GetMaxPos() const { return std::max(1.f, m_ScrollRange - m_ScrollSpace); }
    211211
    212212    /**
     213     * Get the value of m_Pos that corresponds to the bottom of the scrollable region
     214     */
     215    float IsVisible() const { return GetMaxPos() != 1.f; }
     216
     217    /**
    213218     * Increase scroll one step
    214219     */
    215220    virtual void ScrollPlus() { m_Pos += 30.f; UpdatePosBoundaries(); }
    216221
    217222    /**
    218223     * Decrease scroll one step
    219224     */
    220225    virtual void ScrollMinus() { m_Pos -= 30.f; UpdatePosBoundaries(); }
    221226
    222227    /**
    223228     * Increase scroll three steps
    224229     */
    225230    virtual void ScrollPlusPlenty() { m_Pos += 90.f; UpdatePosBoundaries(); }
    226231
    227232    /**
    228233     * Decrease scroll three steps
    229234     */
    230235    virtual void ScrollMinusPlenty() { m_Pos -= 90.f; UpdatePosBoundaries(); }
    231236
    232237    /**
    233238     * Set host object, must be done almost at creation of scroll bar.
    234239     * @param pOwner Pointer to host object.
    235240     */
    236241    void SetHostObject(IGUIScrollBarOwner* pOwner) { m_pHostObject = pOwner; }
    237242
    238243    /**
    239244     * Get GUI pointer
    240245     * @return CGUI pointer
    241246     */
    242247    CGUI* GetGUI() const;
    243248
    244249    /**
    245250     * Set GUI pointer
    246251     * @param pGUI pointer to CGUI object.
    247252     */
    248253    void SetGUI(CGUI* pGUI) { m_pGUI = pGUI; }
    249254
    250255    /**
    251256     * Set Width
    252257     * @param width Width
    253258     */
    254259    void SetWidth(float width) { m_Width = width; }
    255260
    256261    /**
    257262     * Set X Position
    258263     * @param x Position in this axis
    259264     */
    260265    void SetX(float x) { m_X = x; }