Ticket #3391: t3391_fix_sortable_list_column_header_v2.patch

File t3391_fix_sortable_list_column_header_v2.patch, 7.2 KB (added by elexis, 9 years ago)

Added comments. Those 4 pixels were added because the column header text was drawn 4 pixels below the start of the list header. But that doesn't mean that we need to extend the area where clicks are registered, which is defined by m_HeadingHeight(30.f), so removing those 4 pixels there is correct.

  • source/gui/COList.cpp

     
    133133CRect COList::GetListRect() const
    134134{
    135135    return m_CachedActualSize + CRect(0, m_HeadingHeight, 0, 0);
    136136}
    137137
    138138void COList::HandleMessage(SGUIMessage& Message)
    139139{
    140140    CList::HandleMessage(Message);
    141141
    142142    switch (Message.type)
    143143    {
    144144    // If somebody clicks on the column heading
    145145    case GUIM_MOUSE_PRESS_LEFT:
    146146    {
    147147        bool sortable;
    148148        GUI<bool>::GetSetting(this, "sortable", sortable);
    149149        if (!sortable)
    150150            return;
    151151
    152152        CPos mouse = GetMousePos();
    153153        if (!m_CachedActualSize.PointInside(mouse))
    154154            return;
    155155
    156156        float xpos = 0;
    157157        for (size_t def = 0; def < m_ObjectsDefs.size(); ++def)
    158158        {
    159159            float width = m_ObjectsDefs[def].m_Width;
    160160            // Check if it's a decimal value, and if so, assume relative positioning.
    161161            if (m_ObjectsDefs[def].m_Width < 1 && m_ObjectsDefs[def].m_Width > 0)
    162162                width *= m_TotalAvalibleColumnWidth;
    163             CPos leftTopCorner = m_CachedActualSize.TopLeft() + CPos(xpos, 4);
     163            CPos leftTopCorner = m_CachedActualSize.TopLeft() + CPos(xpos, 0);
    164164            if (mouse.x >= leftTopCorner.x &&
    165165                mouse.x < leftTopCorner.x + width &&
    166166                mouse.y < leftTopCorner.y + m_HeadingHeight)
    167167            {
    168168                if (def != m_SelectedDef)
    169169                {
    170170                    m_SelectedColumnOrder = 1;
    171171                    m_SelectedDef = def;
    172172                }
    173173                else
    174174                    m_SelectedColumnOrder = -m_SelectedColumnOrder;
    175175                GUI<CStr>::SetSetting(this, "selected_column", m_ObjectsDefs[def].m_Id.substr(5));
    176176                GUI<int>::SetSetting(this, "selected_column_order", m_SelectedColumnOrder);
    177177                GUI<int>::SetSetting(this, "selected_def", def);
    178178                ScriptEvent("selectioncolumnchange");
    179179
    180180                CStrW soundPath;
    181181                if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty())
    182182                    g_SoundManager->PlayAsUI(soundPath.c_str(), false);
    183183
    184184                return;
    185185            }
    186186            xpos += width;
    187187        }
    188188        return;
    189189    }
    190190    default:
    191191        return;
    192192    }
    193193}
     
    294294    float bz = GetBufferedZ();
    295295
    296296    // First call draw on ScrollBarOwner
    297297    bool scrollbar;
    298298    GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
    299299
    300300    if (scrollbar)
    301301        IGUIScrollBarOwner::Draw();
    302302
    303303    if (!GetGUI())
    304304        return;
    305305
    306306    CRect rect = GetListRect();
    307307
    308308    CGUISpriteInstance* sprite = NULL;
    309309    CGUISpriteInstance* sprite_selectarea = NULL;
    310310    int cell_id;
    311311    GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite, sprite);
    312312    GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite_selected, sprite_selectarea);
    313313    GUI<int>::GetSetting(this, "cell_id", cell_id);
    314314
    315315    CGUIList* pList;
    316316    GUI<CGUIList>::GetSettingPointer(this, "list_name", pList);
    317317
    318318    GetGUI()->DrawSprite(*sprite, cell_id, bz, rect);
    319319
    320320    float scroll = 0.f;
    321321    if (scrollbar)
    322322        scroll = GetScrollBar(0).GetPos();
    323323
     324    // Draw item selection
    324325    if (selected != -1)
    325326    {
    326327        ENSURE(selected >= 0 && selected+1 < (int)m_ItemsYPositions.size());
    327328
    328329        // Get rectangle of selection:
    329330        CRect rect_sel(rect.left, rect.top + m_ItemsYPositions[selected] - scroll,
    330331                       rect.right, rect.top + m_ItemsYPositions[selected+1] - scroll);
    331332
    332333        if (rect_sel.top <= rect.bottom &&
    333334            rect_sel.bottom >= rect.top)
    334335        {
    335336            if (rect_sel.bottom > rect.bottom)
    336337                rect_sel.bottom = rect.bottom;
    337338            if (rect_sel.top < rect.top)
    338339                rect_sel.top = rect.top;
    339340
    340341            if (scrollbar)
    341342            {
    342343                // Remove any overlapping area of the scrollbar.
    343344                if (rect_sel.right > GetScrollBar(0).GetOuterRect().left &&
    344345                    rect_sel.right <= GetScrollBar(0).GetOuterRect().right)
    345346                    rect_sel.right = GetScrollBar(0).GetOuterRect().left;
    346347
    347348                if (rect_sel.left >= GetScrollBar(0).GetOuterRect().left &&
    348349                    rect_sel.left < GetScrollBar(0).GetOuterRect().right)
    349350                    rect_sel.left = GetScrollBar(0).GetOuterRect().right;
    350351            }
    351352
     353            // Draw item selection
    352354            GetGUI()->DrawSprite(*sprite_selectarea, cell_id, bz+0.05f, rect_sel);
    353355        }
    354356    }
    355357
    356358    CColor color;
    357359    GUI<CColor>::GetSetting(this, _textcolor, color);
    358360
     361    // Draw line above column header
    359362    CGUISpriteInstance* sprite_heading = NULL;
    360363    GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_heading", sprite_heading);
    361364    CRect rect_head(m_CachedActualSize.left, m_CachedActualSize.top, m_CachedActualSize.right,
    362365                                    m_CachedActualSize.top + m_HeadingHeight);
    363366    GetGUI()->DrawSprite(*sprite_heading, cell_id, bz, rect_head);
    364367
    365368    CGUISpriteInstance* sprite_order;
    366369    CGUISpriteInstance* sprite_not_sorted;
    367370    if (m_SelectedColumnOrder != -1)
    368371        GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_asc", sprite_order);
    369372    else
    370373        GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_desc", sprite_order);
    371374    GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_not_sorted", sprite_not_sorted);
    372375
     376    // Draw column headers
    373377    float xpos = 0;
    374378    for (size_t def = 0; def < m_ObjectsDefs.size(); ++def)
    375379    {
    376380        // Check if it's a decimal value, and if so, assume relative positioning.
    377381        float width = m_ObjectsDefs[def].m_Width;
    378382        if (m_ObjectsDefs[def].m_Width < 1 && m_ObjectsDefs[def].m_Width > 0)
    379383            width *= m_TotalAvalibleColumnWidth;
    380384
    381385        CPos leftTopCorner = m_CachedActualSize.TopLeft() + CPos(xpos, 0);
     386
    382387        CGUISpriteInstance* sprite;
    383388        // If the list sorted by current column
    384389        if (m_SelectedDef == def)
    385390            sprite = sprite_order;
    386391        else
    387392            sprite = sprite_not_sorted;
     393
     394        // Draw sort arrows in colum header
    388395        GetGUI()->DrawSprite(*sprite, cell_id, bz + 0.1f, CRect(leftTopCorner + CPos(width - 16, 0), leftTopCorner + CPos(width, 16)));
    389396
     397        // Draw column header text
    390398        DrawText(def, color, leftTopCorner + CPos(0, 4), bz + 0.1f, rect_head);
    391399        xpos += width;
    392400    }
    393401
     402    // Draw list items for each column
    394403    const size_t objectsCount = m_ObjectsDefs.size();
    395404    for (size_t i = 0; i < pList->m_Items.size(); ++i)
    396405    {
    397406        if (m_ItemsYPositions[i+1] - scroll < 0 ||
    398407            m_ItemsYPositions[i] - scroll > rect.GetHeight())
    399408            continue;
    400409
    401410        const float rowHeight = m_ItemsYPositions[i+1] - m_ItemsYPositions[i];
    402411
    403412        // Clipping area (we'll have to substract the scrollbar)
    404413        CRect cliparea = GetListRect();
    405414
    406415        if (scrollbar)
    407416        {
    408417            if (cliparea.right > GetScrollBar(0).GetOuterRect().left &&
    409418                cliparea.right <= GetScrollBar(0).GetOuterRect().right)
    410419                cliparea.right = GetScrollBar(0).GetOuterRect().left;
    411420
    412421            if (cliparea.left >= GetScrollBar(0).GetOuterRect().left &&
    413422                cliparea.left < GetScrollBar(0).GetOuterRect().right)
    414423                cliparea.left = GetScrollBar(0).GetOuterRect().right;
    415424        }
    416425
     426        // Draw all items for that column
    417427        xpos = 0;
    418428        for (size_t def = 0; def < objectsCount; ++def)
    419429        {
    420430            // Determine text position and width
    421431            const CPos textPos = rect.TopLeft() + CPos(xpos, -scroll + m_ItemsYPositions[i]);
    422432
    423433            float width = m_ObjectsDefs[def].m_Width;;
    424434            // Check if it's a decimal value, and if so, assume relative positioning.
    425435            if (m_ObjectsDefs[def].m_Width < 1 && m_ObjectsDefs[def].m_Width > 0)
    426436                width *= m_TotalAvalibleColumnWidth;
    427437
    428438            // Clip text to the column (to prevent drawing text into the neighboring column)
    429439            CRect cliparea2 = cliparea;
    430440            cliparea2.right = std::min(cliparea2.right, textPos.x + width);
    431441            cliparea2.bottom = std::min(cliparea2.bottom, textPos.y + rowHeight);
    432442
     443            // Draw list item
    433444            DrawText(objectsCount * (i+/*Heading*/1) + def, m_ObjectsDefs[def].m_TextColor, textPos, bz+0.1f, cliparea2);
    434445            xpos += width;
    435446        }
    436447    }
    437448}