Changeset View
Changeset View
Standalone View
Standalone View
source/gui/ObjectTypes/COList.cpp
Show All 27 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(), | m_SpriteHeading(this, "sprite_heading"), | ||||
m_Sortable(), | m_Sortable(this, "sortable"), // The actual sorting is done in JS for more versatility | ||||
m_SelectedColumn(), | m_SelectedColumn(this, "selected_column"), | ||||
m_SelectedColumnOrder(), | m_SelectedColumnOrder(this, "selected_column_order"), | ||||
m_SpriteAsc(), | m_SpriteAsc(this, "sprite_asc"), // Show the order of sorting | ||||
m_SpriteDesc(), | m_SpriteDesc(this, "sprite_desc"), | ||||
m_SpriteNotSorted() | m_SpriteNotSorted(this, "sprite_not_sorted") | ||||
{ | { | ||||
RegisterSetting("sprite_heading", m_SpriteHeading); | |||||
RegisterSetting("sortable", m_Sortable); // The actual sorting is done in JS for more versatility | |||||
RegisterSetting("selected_column", m_SelectedColumn); | |||||
RegisterSetting("selected_column_order", m_SelectedColumnOrder); | |||||
RegisterSetting("sprite_asc", m_SpriteAsc); // Show the order of sorting | |||||
RegisterSetting("sprite_desc", m_SpriteDesc); | |||||
RegisterSetting("sprite_not_sorted", m_SpriteNotSorted); | |||||
} | } | ||||
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, | ||||
// but this is easier, and this function will never be called | // but this is easier, and this function will never be called | ||||
// continuously, or even often, so it'll probably be okay. | // continuously, or even often, so it'll probably be okay. | ||||
m_GeneratedTexts.clear(); | m_GeneratedTexts.clear(); | ||||
m_TotalAvailableColumnWidth = GetListRect().GetWidth(); | m_TotalAvailableColumnWidth = GetListRect().GetWidth(); | ||||
// remove scrollbar if applicable | // remove scrollbar if applicable | ||||
Show All 13 Lines | for (const COListColumn& column : m_Columns) | ||||
const CGUIText& text = AddText(gui_string, m_Font, width, m_BufferZone); | const CGUIText& text = AddText(gui_string, m_Font, width, m_BufferZone); | ||||
m_HeadingHeight = std::max(m_HeadingHeight, text.GetSize().Height + COLUMN_SHIFT.Y); | m_HeadingHeight = std::max(m_HeadingHeight, text.GetSize().Height + COLUMN_SHIFT.Y); | ||||
} | } | ||||
// Generate texts | // Generate texts | ||||
float buffered_y = 0.f; | float buffered_y = 0.f; | ||||
for (size_t i = 0; i < m_List.m_Items.size(); ++i) | for (size_t i = 0; i < m_List->m_Items.size(); ++i) | ||||
{ | { | ||||
m_ItemsYPositions[i] = buffered_y; | m_ItemsYPositions[i] = buffered_y; | ||||
float shift = 0.0f; | float shift = 0.0f; | ||||
for (const COListColumn& column : m_Columns) | for (const COListColumn& column : m_Columns) | ||||
{ | { | ||||
float width = column.m_Width; | float width = column.m_Width; | ||||
if (column.m_Width > 0 && column.m_Width < 1) | if (column.m_Width > 0 && column.m_Width < 1) | ||||
width *= m_TotalAvailableColumnWidth; | width *= m_TotalAvailableColumnWidth; | ||||
CGUIText* text; | CGUIText* text; | ||||
if (!column.m_List.m_Items[i].GetOriginalString().empty()) | if (!column.m_List->m_Items[i].GetOriginalString().empty()) | ||||
text = &AddText(column.m_List.m_Items[i], m_Font, width, m_BufferZone); | text = &AddText(column.m_List->m_Items[i], m_Font, width, m_BufferZone); | ||||
else | else | ||||
{ | { | ||||
// Minimum height of a space character of the current font size | // Minimum height of a space character of the current font size | ||||
CGUIString align_string; | CGUIString align_string; | ||||
align_string.SetValue(L" "); | align_string.SetValue(L" "); | ||||
text = &AddText(align_string, m_Font, width, m_BufferZone); | text = &AddText(align_string, m_Font, width, m_BufferZone); | ||||
} | } | ||||
shift = std::max(shift, text->GetSize().Height); | shift = std::max(shift, text->GetSize().Height); | ||||
} | } | ||||
buffered_y += shift; | buffered_y += shift; | ||||
} | } | ||||
m_ItemsYPositions[m_List.m_Items.size()] = buffered_y; | m_ItemsYPositions[m_List->m_Items.size()] = buffered_y; | ||||
if (m_ScrollBar) | if (m_ScrollBar) | ||||
{ | { | ||||
CRect rect = GetListRect(); | CRect rect = GetListRect(); | ||||
GetScrollBar(0).SetScrollRange(m_ItemsYPositions.back()); | GetScrollBar(0).SetScrollRange(m_ItemsYPositions.back()); | ||||
GetScrollBar(0).SetScrollSpace(rect.GetHeight()); | GetScrollBar(0).SetScrollSpace(rect.GetHeight()); | ||||
GetScrollBar(0).SetX(rect.right); | GetScrollBar(0).SetX(rect.right); | ||||
Show All 34 Lines | for (const COListColumn& column : m_Columns) | ||||
// Check if it's a decimal value, and if so, assume relative positioning. | // Check if it's a decimal value, and if so, assume relative positioning. | ||||
if (column.m_Width < 1 && column.m_Width > 0) | if (column.m_Width < 1 && column.m_Width > 0) | ||||
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 != m_SelectedColumn) | if (column.m_Id != static_cast<CStr>(m_SelectedColumn)) | ||||
{ | { | ||||
SetSetting<i32>("selected_column_order", -1, true); | m_SelectedColumnOrder.Set(-1, true); | ||||
CStr selected_column = column.m_Id; | CStr selected_column = column.m_Id; | ||||
SetSetting<CStr>("selected_column", selected_column, true); | m_SelectedColumn.Set(selected_column, true); | ||||
} | } | ||||
else | else | ||||
SetSetting<i32>("selected_column_order", -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; | ||||
Show All 17 Lines | bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile) | ||||
{ | { | ||||
CGUIString vlist; | CGUIString vlist; | ||||
vlist.SetValue(child.GetText().FromUTF8()); | vlist.SetValue(child.GetText().FromUTF8()); | ||||
AddItem(vlist, vlist); | AddItem(vlist, vlist); | ||||
return true; | return true; | ||||
} | } | ||||
else if (child.GetNodeName() == elmt_column) | else if (child.GetNodeName() == elmt_column) | ||||
{ | { | ||||
COListColumn column; | CStr id; | ||||
XERO_ITER_ATTR(child, attr) | |||||
{ | |||||
if (attr.Name == attr_id) | |||||
id = attr.Value; | |||||
} | |||||
COListColumn column(this, id); | |||||
for (XMBAttribute attr : child.GetAttributes()) | for (XMBAttribute attr : child.GetAttributes()) | ||||
{ | { | ||||
CStr attr_name(pFile->GetAttributeString(attr.Name)); | CStr attr_name(pFile->GetAttributeString(attr.Name)); | ||||
CStr attr_value(attr.Value); | CStr attr_value(attr.Value); | ||||
if (attr_name == "color") | if (attr_name == "color") | ||||
{ | { | ||||
if (!CGUI::ParseString<CGUIColor>(&m_pGUI, attr_value.FromUTF8(), column.m_TextColor)) | if (!CGUI::ParseString<CGUIColor>(&m_pGUI, attr_value.FromUTF8(), column.m_TextColor)) | ||||
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); | LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); | ||||
} | } | ||||
else if (attr_name == "id") | |||||
{ | |||||
column.m_Id = attr_value; | |||||
} | |||||
else if (attr_name == "hidden") | else if (attr_name == "hidden") | ||||
{ | { | ||||
bool hidden = false; | bool hidden = false; | ||||
if (!CGUI::ParseString<bool>(&m_pGUI, attr_value.FromUTF8(), hidden)) | if (!CGUI::ParseString<bool>(&m_pGUI, attr_value.FromUTF8(), hidden)) | ||||
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); | LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); | ||||
else | else | ||||
column.m_Hidden = hidden; | column.m_Hidden.Set(hidden, false); | ||||
} | } | ||||
else if (attr_name == "width") | else if (attr_name == "width") | ||||
{ | { | ||||
float width; | float width; | ||||
if (!CGUI::ParseString<float>(&m_pGUI, attr_value.FromUTF8(), width)) | if (!CGUI::ParseString<float>(&m_pGUI, attr_value.FromUTF8(), width)) | ||||
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); | LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); | ||||
else | else | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile) | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
void COList::AdditionalChildrenHandled() | void COList::AdditionalChildrenHandled() | ||||
{ | { | ||||
SetupText(); | SetupText(); | ||||
// Do this after the last push_back call to avoid iterator invalidation | |||||
for (COListColumn& column : m_Columns) | |||||
{ | |||||
RegisterSetting("list_" + column.m_Id, column.m_List); | |||||
RegisterSetting("hidden_" + column.m_Id, column.m_Hidden); | |||||
} | |||||
} | } | ||||
void COList::DrawList(const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& sprite_selected, const CGUIColor& textcolor) | void COList::DrawList(const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& sprite_selected, const CGUIColor& textcolor) | ||||
{ | { | ||||
const float bz = GetBufferedZ(); | const float bz = GetBufferedZ(); | ||||
if (m_ScrollBar) | if (m_ScrollBar) | ||||
IGUIScrollBarOwner::Draw(); | IGUIScrollBarOwner::Draw(); | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | if (column.m_Width < 1 && column.m_Width > 0) | ||||
width *= m_TotalAvailableColumnWidth; | width *= m_TotalAvailableColumnWidth; | ||||
CVector2D leftTopCorner = m_CachedActualSize.TopLeft() + CVector2D(xpos, 0); | CVector2D leftTopCorner = m_CachedActualSize.TopLeft() + CVector2D(xpos, 0); | ||||
// Draw sort arrows in colum header | // Draw sort arrows in colum header | ||||
if (m_Sortable) | if (m_Sortable) | ||||
{ | { | ||||
const CGUISpriteInstance* pSprite; | const CGUISpriteInstance* pSprite; | ||||
if (m_SelectedColumn == column.m_Id) | if (m_SelectedColumn.Get() == column.m_Id) | ||||
{ | { | ||||
if (m_SelectedColumnOrder == 0) | if (m_SelectedColumnOrder == 0) | ||||
LOGERROR("selected_column_order must not be 0"); | LOGERROR("selected_column_order must not be 0"); | ||||
if (m_SelectedColumnOrder != -1) | if (m_SelectedColumnOrder != -1) | ||||
pSprite = &m_SpriteAsc; | pSprite = &m_SpriteAsc.Get(); | ||||
else | else | ||||
pSprite = &m_SpriteDesc; | pSprite = &m_SpriteDesc.Get(); | ||||
} | } | ||||
else | else | ||||
pSprite = &m_SpriteNotSorted; | pSprite = &m_SpriteNotSorted.Get(); | ||||
m_pGUI.DrawSprite(*pSprite, bz + 0.1f, CRect(leftTopCorner + CVector2D(width - SORT_SPRITE_DIM, 0), leftTopCorner + CVector2D(width, SORT_SPRITE_DIM))); | m_pGUI.DrawSprite(*pSprite, bz + 0.1f, CRect(leftTopCorner + CVector2D(width - SORT_SPRITE_DIM, 0), leftTopCorner + CVector2D(width, SORT_SPRITE_DIM))); | ||||
} | } | ||||
// Draw column header text | // Draw column header text | ||||
DrawText(col, textcolor, leftTopCorner + COLUMN_SHIFT, bz + 0.1f, rect_head); | DrawText(col, textcolor, leftTopCorner + COLUMN_SHIFT, bz + 0.1f, rect_head); | ||||
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) | ||||
Show All 40 Lines |
Wildfire Games · Phabricator