Changeset View
Changeset View
Standalone View
Standalone View
source/gui/ObjectTypes/COList.cpp
/* Copyright (C) 2021 Wildfire Games. | /* Copyright (C) 2022 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 18 Lines | |||||
const float SORT_SPRITE_DIM = 16.0f; | const float SORT_SPRITE_DIM = 16.0f; | ||||
const CVector2D COLUMN_SHIFT = CVector2D(0, 4); | const CVector2D COLUMN_SHIFT = CVector2D(0, 4); | ||||
const CStr COList::EventNameSelectionColumnChange = "SelectionColumnChange"; | const CStr COList::EventNameSelectionColumnChange = "SelectionColumnChange"; | ||||
COList::COList(CGUI& pGUI) | COList::COList(CGUI& pGUI) | ||||
: CList(pGUI), | : CList(pGUI), | ||||
m_SpriteHeading(this, "sprite_heading"), | m_SpriteHeading(this, "sprite_heading"), | ||||
m_Sortable(this, "sortable"), // The actual sorting is done in JS for more versatility | m_Sortable(this, "sortable"), // The actual sorting is done in JS for more versatility | ||||
m_SelectedColumn(this, "selected_column"), | m_SelectedColumn(this, "selected_column"), | ||||
m_SelectedColumnOrder(this, "selected_column_order"), | m_SelectedColumnOrder(this, "selected_column_order"), | ||||
m_SpriteAsc(this, "sprite_asc"), // Show the order of sorting | m_SpriteAsc(this, "sprite_asc"), // Show the order of sorting | ||||
m_SpriteDesc(this, "sprite_desc"), | m_SpriteDesc(this, "sprite_desc"), | ||||
m_SpriteNotSorted(this, "sprite_not_sorted") | m_SpriteNotSorted(this, "sprite_not_sorted") | ||||
{ | { | ||||
} | } | ||||
void COList::SetupText() | void COList::SetupText() | ||||
{ | { | ||||
m_ItemsYPositions.resize(m_List->m_Items.size() + 1); | m_ItemsYPositions.resize(m_List->m_Items.size() + 1); | ||||
// Delete all generated texts. Some could probably be saved, | // Delete all generated texts. Some could probably be saved, | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | CRect COList::GetListRect() const | ||||
return m_CachedActualSize + CRect(0, m_HeadingHeight, 0, 0); | return m_CachedActualSize + CRect(0, m_HeadingHeight, 0, 0); | ||||
} | } | ||||
void COList::HandleMessage(SGUIMessage& Message) | void COList::HandleMessage(SGUIMessage& Message) | ||||
{ | { | ||||
CList::HandleMessage(Message); | CList::HandleMessage(Message); | ||||
switch (Message.type) | switch (Message.type) | ||||
{ | { | ||||
case GUIM_SETTINGS_UPDATED: | |||||
{ | |||||
if (Message.value.find("heading_") == 0) | |||||
SetupText(); | |||||
break; | |||||
} | |||||
Silier: You need to move the check under correct type | |||||
Done Inline ActionsI can't compile with this, seems like ::algorithm is the issue. "must be a class or namespace name". Ended up using a different method (don't know if it's any good though). Grapjas: I can't compile with this, seems like ::algorithm is the issue. "must be a class or namespace… | |||||
// If somebody clicks on the column heading | // If somebody clicks on the column heading | ||||
case GUIM_MOUSE_PRESS_LEFT: | case GUIM_MOUSE_PRESS_LEFT: | ||||
{ | { | ||||
if (!m_Sortable) | if (!m_Sortable) | ||||
return; | return; | ||||
const CVector2D& mouse = m_pGUI.GetMousePos(); | const CVector2D& mouse = m_pGUI.GetMousePos(); | ||||
if (!m_CachedActualSize.PointInside(mouse)) | if (!m_CachedActualSize.PointInside(mouse)) | ||||
Show All 11 Lines | for (const COListColumn& column : m_Columns) | ||||
width *= m_TotalAvailableColumnWidth; | width *= m_TotalAvailableColumnWidth; | ||||
CVector2D leftTopCorner = m_CachedActualSize.TopLeft() + CVector2D(xpos, 0); | CVector2D leftTopCorner = m_CachedActualSize.TopLeft() + CVector2D(xpos, 0); | ||||
if (mouse.X >= leftTopCorner.X && | if (mouse.X >= leftTopCorner.X && | ||||
mouse.X < leftTopCorner.X + width && | mouse.X < leftTopCorner.X + width && | ||||
mouse.Y < leftTopCorner.Y + m_HeadingHeight) | mouse.Y < leftTopCorner.Y + m_HeadingHeight) | ||||
{ | { | ||||
if (column.m_Id != static_cast<CStr>(m_SelectedColumn)) | if (column.m_Id != static_cast<CStr>(m_SelectedColumn)) | ||||
{ | { | ||||
m_SelectedColumnOrder.Set(-1, true); | (column.m_Id == "rating") ? m_SelectedColumnOrder.Set(-1, true) : m_SelectedColumnOrder.Set(1, true); | ||||
CStr selected_column = column.m_Id; | CStr selected_column = column.m_Id; | ||||
m_SelectedColumn.Set(selected_column, true); | m_SelectedColumn.Set(selected_column, true); | ||||
} | } | ||||
else | else | ||||
m_SelectedColumnOrder.Set(-m_SelectedColumnOrder, true); | m_SelectedColumnOrder.Set(-m_SelectedColumnOrder, true); | ||||
ScriptEvent(EventNameSelectionColumnChange); | ScriptEvent(EventNameSelectionColumnChange); | ||||
PlaySound(m_SoundSelected); | PlaySound(m_SoundSelected); | ||||
return; | return; | ||||
} | } | ||||
xpos += width; | xpos += width; | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
default: | default: | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
bool COList::HandleAdditionalChildren(const XMBData& xmb, const XMBElement& child) | bool COList::HandleAdditionalChildren(const XMBData& xmb, const XMBElement& child) | ||||
{ | { | ||||
#define ELMT(x) int elmt_##x = xmb.GetElementID(#x) | #define ELMT(x) int elmt_##x = xmb.GetElementID(#x) | ||||
#define ATTR(x) int attr_##x = xmb.GetAttributeID(#x) | #define ATTR(x) int attr_##x = xmb.GetAttributeID(#x) | ||||
ELMT(item); | ELMT(item); | ||||
ELMT(column); | ELMT(column); | ||||
ELMT(translatableAttribute); | ELMT(translatableAttribute); | ||||
ATTR(id); | ATTR(id); | ||||
ATTR(context); | ATTR(context); | ||||
if (child.GetNodeName() == elmt_item) | if (child.GetNodeName() == elmt_item) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | for (XMBAttribute attr : child.GetAttributes()) | ||||
// Check if it's a relative value, and save as decimal if so. | // Check if it's a relative value, and save as decimal if so. | ||||
if (attr_value.find("%") != std::string::npos) | if (attr_value.find("%") != std::string::npos) | ||||
width = width / 100.f; | width = width / 100.f; | ||||
column.m_Width = width; | column.m_Width = width; | ||||
} | } | ||||
} | } | ||||
else if (attr_name == "heading") | else if (attr_name == "heading") | ||||
{ | { | ||||
column.m_Heading = attr_value.FromUTF8(); | column.m_Heading.Set(attr_value.FromUTF8(), false); | ||||
} | } | ||||
} | } | ||||
for (XMBElement grandchild : child.GetChildNodes()) | for (XMBElement grandchild : child.GetChildNodes()) | ||||
{ | { | ||||
if (grandchild.GetNodeName() != elmt_translatableAttribute) | if (grandchild.GetNodeName() != elmt_translatableAttribute) | ||||
continue; | continue; | ||||
CStr attributeName(grandchild.GetAttributes().GetNamedItem(attr_id)); | CStr attributeName(grandchild.GetAttributes().GetNamedItem(attr_id)); | ||||
// only the heading is translatable for list column | // only the heading is translatable for list column | ||||
if (attributeName.empty() || attributeName != "heading") | if (attributeName.empty() || attributeName != "heading") | ||||
{ | { | ||||
LOGERROR("GUI: translatable attribute in olist column that isn't a heading. (object: %s)", this->GetPresentableName().c_str()); | LOGERROR("GUI: translatable attribute in olist column that isn't a heading. (object: %s)", this->GetPresentableName().c_str()); | ||||
continue; | continue; | ||||
} | } | ||||
CStr value(grandchild.GetText()); | CStr value(grandchild.GetText()); | ||||
if (value.empty()) | if (value.empty()) | ||||
continue; | continue; | ||||
CStr context(grandchild.GetAttributes().GetNamedItem(attr_context)); // Read the context if any. | CStr context(grandchild.GetAttributes().GetNamedItem(attr_context)); // Read the context if any. | ||||
if (!context.empty()) | if (!context.empty()) | ||||
{ | { | ||||
CStr translatedValue(g_L10n.TranslateWithContext(context, value)); | CStr translatedValue(g_L10n.TranslateWithContext(context, value)); | ||||
column.m_Heading = translatedValue.FromUTF8(); | column.m_Heading.Set(translatedValue.FromUTF8(), false); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
CStr translatedValue(g_L10n.Translate(value)); | CStr translatedValue(g_L10n.Translate(value)); | ||||
column.m_Heading = translatedValue.FromUTF8(); | column.m_Heading.Set(translatedValue.FromUTF8(), false); | ||||
} | } | ||||
} | } | ||||
m_Columns.emplace_back(std::move(column)); | m_Columns.emplace_back(std::move(column)); | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
void COList::AdditionalChildrenHandled() | void COList::AdditionalChildrenHandled() | ||||
{ | { | ||||
SetupText(); | SetupText(); | ||||
} | } | ||||
void COList::DrawList(CCanvas2D& canvas, const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& spriteOverlay, | void COList::DrawList(CCanvas2D& canvas, const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& spriteOverlay, | ||||
const CGUISpriteInstance& spriteSelectArea, const CGUISpriteInstance& spriteSelectAreaOverlay, const CGUIColor& textColor) | const CGUISpriteInstance& spriteSelectArea, const CGUISpriteInstance& spriteSelectAreaOverlay, const CGUIColor& textColor) | ||||
{ | { | ||||
CRect rect = GetListRect(); | CRect rect = GetListRect(); | ||||
m_pGUI.DrawSprite(sprite, canvas, rect); | m_pGUI.DrawSprite(sprite, canvas, rect); | ||||
float scroll = 0.f; | float scroll = 0.f; | ||||
if (m_ScrollBar) | if (m_ScrollBar) | ||||
scroll = GetScrollBar(0).GetPos(); | scroll = GetScrollBar(0).GetPos(); | ||||
bool drawSelected = false; | bool drawSelected = false; | ||||
CRect rectSel; | CRect rectSel; | ||||
// Draw item selection | // Draw item selection | ||||
if (selected != -1) | if (selected != -1) | ||||
{ | { | ||||
ENSURE(selected >= 0 && selected+1 < (int)m_ItemsYPositions.size()); | ENSURE(selected >= 0 && selected + 1 < (int)m_ItemsYPositions.size()); | ||||
// Get rectangle of selection: | // Get rectangle of selection: | ||||
rectSel = CRect( | rectSel = CRect( | ||||
rect.left, rect.top + m_ItemsYPositions[selected] - scroll, | rect.left, rect.top + m_ItemsYPositions[selected] - scroll, | ||||
rect.right, rect.top + m_ItemsYPositions[selected+1] - scroll); | rect.right, rect.top + m_ItemsYPositions[selected + 1] - scroll); | ||||
if (rectSel.top <= rect.bottom && | if (rectSel.top <= rect.bottom && | ||||
rectSel.bottom >= rect.top) | rectSel.bottom >= rect.top) | ||||
{ | { | ||||
if (rectSel.bottom > rect.bottom) | if (rectSel.bottom > rect.bottom) | ||||
rectSel.bottom = rect.bottom; | rectSel.bottom = rect.bottom; | ||||
if (rectSel.top < rect.top) | if (rectSel.top < rect.top) | ||||
rectSel.top = rect.top; | rectSel.top = rect.top; | ||||
Show All 13 Lines | if (rectSel.top <= rect.bottom && | ||||
// Draw item selection | // Draw item selection | ||||
m_pGUI.DrawSprite(spriteSelectArea, canvas, rectSel); | m_pGUI.DrawSprite(spriteSelectArea, canvas, rectSel); | ||||
drawSelected = true; | drawSelected = true; | ||||
} | } | ||||
} | } | ||||
// Draw line above column header | // Draw line above column header | ||||
CRect rect_head(m_CachedActualSize.left, m_CachedActualSize.top, m_CachedActualSize.right, | CRect rect_head(m_CachedActualSize.left, m_CachedActualSize.top, m_CachedActualSize.right, | ||||
m_CachedActualSize.top + m_HeadingHeight); | m_CachedActualSize.top + m_HeadingHeight); | ||||
m_pGUI.DrawSprite(m_SpriteHeading, canvas, rect_head); | m_pGUI.DrawSprite(m_SpriteHeading, canvas, rect_head); | ||||
// Draw column headers | // Draw column headers | ||||
float xpos = 0; | float xpos = 0; | ||||
size_t col = 0; | size_t col = 0; | ||||
for (const COListColumn& column : m_Columns) | for (const COListColumn& column : m_Columns) | ||||
{ | { | ||||
if (column.m_Hidden) | if (column.m_Hidden) | ||||
Show All 34 Lines | for (const COListColumn& column : m_Columns) | ||||
xpos += width; | xpos += width; | ||||
++col; | ++col; | ||||
} | } | ||||
// Draw list items for each column | // Draw list items for each column | ||||
const size_t objectsCount = m_Columns.size(); | const size_t objectsCount = m_Columns.size(); | ||||
for (size_t i = 0; i < m_List->m_Items.size(); ++i) | for (size_t i = 0; i < m_List->m_Items.size(); ++i) | ||||
{ | { | ||||
if (m_ItemsYPositions[i+1] - scroll < 0 || | if (m_ItemsYPositions[i + 1] - scroll < 0 || | ||||
m_ItemsYPositions[i] - scroll > rect.GetHeight()) | m_ItemsYPositions[i] - scroll > rect.GetHeight()) | ||||
continue; | continue; | ||||
const float rowHeight = m_ItemsYPositions[i+1] - m_ItemsYPositions[i]; | const float rowHeight = m_ItemsYPositions[i + 1] - m_ItemsYPositions[i]; | ||||
// Clipping area (we'll have to substract the scrollbar) | // Clipping area (we'll have to substract the scrollbar) | ||||
CRect cliparea = GetListRect(); | CRect cliparea = GetListRect(); | ||||
if (m_ScrollBar) | if (m_ScrollBar) | ||||
{ | { | ||||
if (cliparea.right > GetScrollBar(0).GetOuterRect().left && | if (cliparea.right > GetScrollBar(0).GetOuterRect().left && | ||||
cliparea.right <= GetScrollBar(0).GetOuterRect().right) | cliparea.right <= GetScrollBar(0).GetOuterRect().right) | ||||
Show All 34 Lines | void COList::DrawList(CCanvas2D& canvas, const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& spriteOverlay, | ||||
// Draw scrollbars on top of the content | // Draw scrollbars on top of the content | ||||
if (m_ScrollBar) | if (m_ScrollBar) | ||||
IGUIScrollBarOwner::Draw(canvas); | IGUIScrollBarOwner::Draw(canvas); | ||||
// Draw the overlays last | // Draw the overlays last | ||||
m_pGUI.DrawSprite(spriteOverlay, canvas, rect); | m_pGUI.DrawSprite(spriteOverlay, canvas, rect); | ||||
if (drawSelected) | if (drawSelected) | ||||
m_pGUI.DrawSprite(spriteSelectAreaOverlay, canvas, rectSel); | m_pGUI.DrawSprite(spriteSelectAreaOverlay, canvas, rectSel); | ||||
} | } | ||||
No newline at end of file |
Wildfire Games · Phabricator
You need to move the check under correct type