Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/gui/COList.cpp
/* Copyright (C) 2017 Wildfire Games. | /* Copyright (C) 2019 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, | ||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
#include "precompiled.h" | #include "precompiled.h" | ||||
#include "COList.h" | #include "COList.h" | ||||
#include "i18n/L10n.h" | #include "i18n/L10n.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "soundmanager/ISoundManager.h" | #include "soundmanager/ISoundManager.h" | ||||
const float SORT_SPRITE_DIM = 16.0f; | |||||
const CPos COLUMN_SHIFT = CPos(0, 4); | |||||
COList::COList() : CList() | COList::COList() : CList() | ||||
{ | { | ||||
AddSetting(GUIST_CGUISpriteInstance, "sprite_heading"); | AddSetting(GUIST_CGUISpriteInstance, "sprite_heading"); | ||||
AddSetting(GUIST_float, "heading_height"); | |||||
AddSetting(GUIST_bool, "sortable"); // The actual sorting is done in JS for more versatility | AddSetting(GUIST_bool, "sortable"); // The actual sorting is done in JS for more versatility | ||||
AddSetting(GUIST_CStr, "selected_column"); | AddSetting(GUIST_CStr, "selected_column"); | ||||
AddSetting(GUIST_int, "selected_column_order"); | AddSetting(GUIST_int, "selected_column_order"); | ||||
AddSetting(GUIST_CGUISpriteInstance, "sprite_asc"); // Show the order of sorting | AddSetting(GUIST_CGUISpriteInstance, "sprite_asc"); // Show the order of sorting | ||||
AddSetting(GUIST_CGUISpriteInstance, "sprite_desc"); | AddSetting(GUIST_CGUISpriteInstance, "sprite_desc"); | ||||
AddSetting(GUIST_CGUISpriteInstance, "sprite_not_sorted"); | AddSetting(GUIST_CGUISpriteInstance, "sprite_not_sorted"); | ||||
} | } | ||||
Show All 18 Lines | void COList::SetupText() | ||||
if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) | if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) | ||||
// Use the default if none is specified | // Use the default if none is specified | ||||
// TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. | // TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. | ||||
font = L"default"; | font = L"default"; | ||||
bool scrollbar; | bool scrollbar; | ||||
GUI<bool>::GetSetting(this, "scrollbar", scrollbar); | GUI<bool>::GetSetting(this, "scrollbar", scrollbar); | ||||
float width = GetListRect().GetWidth(); | m_TotalAvailableColumnWidth = GetListRect().GetWidth(); | ||||
// remove scrollbar if applicable | // remove scrollbar if applicable | ||||
if (scrollbar && GetScrollBar(0).GetStyle()) | if (scrollbar && GetScrollBar(0).GetStyle()) | ||||
width -= GetScrollBar(0).GetStyle()->m_Width; | m_TotalAvailableColumnWidth -= GetScrollBar(0).GetStyle()->m_Width; | ||||
m_TotalAvailableColumnWidth = width; | |||||
float buffer_zone = 0.f; | float buffer_zone = 0.f; | ||||
GUI<float>::GetSetting(this, "buffer_zone", buffer_zone); | GUI<float>::GetSetting(this, "buffer_zone", buffer_zone); | ||||
for (COListColumn column : m_Columns) | m_HeadingHeight = SORT_SPRITE_DIM; // At least the size of the sorting sprite | ||||
for (const COListColumn& column : m_Columns) | |||||
{ | { | ||||
float width = column.m_Width; | |||||
if (column.m_Width > 0 && column.m_Width < 1) | |||||
width *= m_TotalAvailableColumnWidth; | |||||
SGUIText* text = new SGUIText(); | SGUIText* text = new SGUIText(); | ||||
CGUIString gui_string; | CGUIString gui_string; | ||||
gui_string.SetValue(column.m_Heading); | gui_string.SetValue(column.m_Heading); | ||||
*text = GetGUI()->GenerateText(gui_string, font, width, buffer_zone, this); | *text = GetGUI()->GenerateText(gui_string, font, width, buffer_zone, this); | ||||
AddText(text); | AddText(text); | ||||
m_HeadingHeight = std::max(m_HeadingHeight, text->m_Size.cy + COLUMN_SHIFT.y); | |||||
} | } | ||||
// Generate texts | // Generate texts | ||||
float buffered_y = 0.f; | float buffered_y = 0.f; | ||||
for (size_t i = 0; i < pList->m_Items.size(); ++i) | for (size_t i = 0; i < pList->m_Items.size(); ++i) | ||||
{ | { | ||||
m_ItemsYPositions[i] = buffered_y; | m_ItemsYPositions[i] = buffered_y; | ||||
float shift = 0.0f; | float shift = 0.0f; | ||||
for (size_t c = 0; c < m_Columns.size(); ++c) | for (const COListColumn& column : m_Columns) | ||||
{ | { | ||||
float width = column.m_Width; | |||||
if (column.m_Width > 0 && column.m_Width < 1) | |||||
width *= m_TotalAvailableColumnWidth; | |||||
CGUIList* pList_c; | CGUIList* pList_c; | ||||
GUI<CGUIList>::GetSettingPointer(this, "list_" + m_Columns[c].m_Id, pList_c); | GUI<CGUIList>::GetSettingPointer(this, "list_" + column.m_Id, pList_c); | ||||
SGUIText* text = new SGUIText(); | SGUIText* text = new SGUIText(); | ||||
if (!pList_c->m_Items[i].GetOriginalString().empty()) | if (!pList_c->m_Items[i].GetOriginalString().empty()) | ||||
*text = GetGUI()->GenerateText(pList_c->m_Items[i], font, width, buffer_zone, this); | *text = GetGUI()->GenerateText(pList_c->m_Items[i], font, width, buffer_zone, this); | ||||
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" "); | ||||
Show All 17 Lines | if (scrollbar) | ||||
GetScrollBar(0).SetY(rect.top); | GetScrollBar(0).SetY(rect.top); | ||||
GetScrollBar(0).SetZ(GetBufferedZ()); | GetScrollBar(0).SetZ(GetBufferedZ()); | ||||
GetScrollBar(0).SetLength(rect.bottom - rect.top); | GetScrollBar(0).SetLength(rect.bottom - rect.top); | ||||
} | } | ||||
} | } | ||||
CRect COList::GetListRect() const | CRect COList::GetListRect() const | ||||
{ | { | ||||
float headingHeight; | return m_CachedActualSize + CRect(0, m_HeadingHeight, 0, 0); | ||||
GUI<float>::GetSetting(this, "heading_height", headingHeight); | |||||
return m_CachedActualSize + CRect(0, 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) | ||||
{ | { | ||||
// If somebody clicks on the column heading | // If somebody clicks on the column heading | ||||
case GUIM_MOUSE_PRESS_LEFT: | case GUIM_MOUSE_PRESS_LEFT: | ||||
{ | { | ||||
bool sortable; | bool sortable; | ||||
GUI<bool>::GetSetting(this, "sortable", sortable); | GUI<bool>::GetSetting(this, "sortable", sortable); | ||||
if (!sortable) | if (!sortable) | ||||
return; | return; | ||||
CPos mouse = GetMousePos(); | CPos mouse = GetMousePos(); | ||||
if (!m_CachedActualSize.PointInside(mouse)) | if (!m_CachedActualSize.PointInside(mouse)) | ||||
return; | return; | ||||
CStr selectedColumn; | CStr selectedColumn; | ||||
GUI<CStr>::GetSetting(this, "selected_column", selectedColumn); | GUI<CStr>::GetSetting(this, "selected_column", selectedColumn); | ||||
int selectedColumnOrder; | int selectedColumnOrder; | ||||
GUI<int>::GetSetting(this, "selected_column_order", selectedColumnOrder); | GUI<int>::GetSetting(this, "selected_column_order", selectedColumnOrder); | ||||
float headingHeight; | |||||
GUI<float>::GetSetting(this, "heading_height", headingHeight); | |||||
float xpos = 0; | float xpos = 0; | ||||
for (COListColumn column : m_Columns) | for (const COListColumn& column : m_Columns) | ||||
{ | { | ||||
bool hidden = false; | bool hidden = false; | ||||
GUI<bool>::GetSetting(this, "hidden_" + column.m_Id, hidden); | GUI<bool>::GetSetting(this, "hidden_" + column.m_Id, hidden); | ||||
if (hidden) | if (hidden) | ||||
continue; | continue; | ||||
float width = column.m_Width; | float width = column.m_Width; | ||||
// 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; | ||||
CPos leftTopCorner = m_CachedActualSize.TopLeft() + CPos(xpos, 0); | CPos leftTopCorner = m_CachedActualSize.TopLeft() + CPos(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 + headingHeight) | mouse.y < leftTopCorner.y + m_HeadingHeight) | ||||
{ | { | ||||
if (column.m_Id != selectedColumn) | if (column.m_Id != selectedColumn) | ||||
{ | { | ||||
selectedColumnOrder = 1; | selectedColumnOrder = 1; | ||||
selectedColumn = column.m_Id; | selectedColumn = column.m_Id; | ||||
} | } | ||||
else | else | ||||
selectedColumnOrder = -selectedColumnOrder; | selectedColumnOrder = -selectedColumnOrder; | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | if (rect_sel.top <= rect.bottom && | ||||
rect_sel.left = GetScrollBar(0).GetOuterRect().right; | rect_sel.left = GetScrollBar(0).GetOuterRect().right; | ||||
} | } | ||||
// Draw item selection | // Draw item selection | ||||
GetGUI()->DrawSprite(*sprite_selectarea, cell_id, bz+0.05f, rect_sel); | GetGUI()->DrawSprite(*sprite_selectarea, cell_id, bz+0.05f, rect_sel); | ||||
} | } | ||||
} | } | ||||
float headingHeight; | |||||
GUI<float>::GetSetting(this, "heading_height", headingHeight); | |||||
// Draw line above column header | // Draw line above column header | ||||
CGUISpriteInstance* sprite_heading = NULL; | CGUISpriteInstance* sprite_heading = NULL; | ||||
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_heading", sprite_heading); | GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_heading", sprite_heading); | ||||
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 + headingHeight); | m_CachedActualSize.top + m_HeadingHeight); | ||||
GetGUI()->DrawSprite(*sprite_heading, cell_id, bz, rect_head); | GetGUI()->DrawSprite(*sprite_heading, cell_id, bz, rect_head); | ||||
// Draw column headers | // Draw column headers | ||||
bool sortable; | bool sortable; | ||||
GUI<bool>::GetSetting(this, "sortable", sortable); | GUI<bool>::GetSetting(this, "sortable", sortable); | ||||
CStr selectedColumn; | CStr selectedColumn; | ||||
GUI<CStr>::GetSetting(this, "selected_column", selectedColumn); | GUI<CStr>::GetSetting(this, "selected_column", selectedColumn); | ||||
Show All 31 Lines | if (sortable) | ||||
if (selectedColumnOrder != -1) | if (selectedColumnOrder != -1) | ||||
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_asc", sprite); | GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_asc", sprite); | ||||
else | else | ||||
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_desc", sprite); | GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_desc", sprite); | ||||
} | } | ||||
else | else | ||||
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_not_sorted", sprite); | GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_not_sorted", sprite); | ||||
GetGUI()->DrawSprite(*sprite, cell_id, bz + 0.1f, CRect(leftTopCorner + CPos(width - 16, 0), leftTopCorner + CPos(width, 16))); | GetGUI()->DrawSprite(*sprite, cell_id, bz + 0.1f, CRect(leftTopCorner + CPos(width - SORT_SPRITE_DIM, 0), leftTopCorner + CPos(width, SORT_SPRITE_DIM))); | ||||
} | } | ||||
// Draw column header text | // Draw column header text | ||||
DrawText(col, color, leftTopCorner + CPos(0, 4), bz + 0.1f, rect_head); | DrawText(col, color, leftTopCorner + COLUMN_SHIFT, bz + 0.1f, rect_head); | ||||
xpos += width; | xpos += width; | ||||
} | } | ||||
// 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 < pList->m_Items.size(); ++i) | for (size_t i = 0; i < pList->m_Items.size(); ++i) | ||||
{ | { | ||||
if (m_ItemsYPositions[i+1] - scroll < 0 || | if (m_ItemsYPositions[i+1] - scroll < 0 || | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator