diff --git a/Client/core/CChat.h b/Client/core/CChat.h index e967127075..9269bcaf9b 100644 --- a/Client/core/CChat.h +++ b/Client/core/CChat.h @@ -13,6 +13,7 @@ #include "CGUI.h" #include +#include <../Shared/sdk/CColor.h> class CChatLineSection; @@ -22,39 +23,6 @@ class CChatLineSection; #define CHAT_BUFFER 1024 // Chatbox buffer size #define CHAT_INPUT_HISTORY_LENGTH 128 // Chatbox input history length -class CColor -{ -public: - CColor() { R = G = B = A = 255; } - CColor(unsigned char _R, unsigned char _G, unsigned char _B, unsigned char _A = 255) - { - R = _R; - G = _G; - B = _B; - A = _A; - } - CColor(const CColor& other) { *this = other; } - CColor(unsigned long ulColor) { *this = ulColor; } - CColor& operator=(const CColor& color) - { - R = color.R; - G = color.G; - B = color.B; - A = color.A; - return *this; - } - CColor& operator=(unsigned long ulColor) - { - R = (ulColor >> 16) & 0xFF; - G = (ulColor >> 8) & 0xFF; - B = (ulColor)&0xFF; - return *this; - } - bool operator==(const CColor& other) const { return R == other.R && G == other.G && B == other.B && A == other.A; } - - unsigned char R, G, B, A; -}; - class CChatLineSection { public: diff --git a/Client/gui/CGUIGridLayout_Impl.cpp b/Client/gui/CGUIGridLayout_Impl.cpp index dbc4d3de3d..3e75a3354e 100644 --- a/Client/gui/CGUIGridLayout_Impl.cpp +++ b/Client/gui/CGUIGridLayout_Impl.cpp @@ -399,6 +399,134 @@ const bool CGUIGridLayout_Impl::SetRowHeight(const int row, const float height) return true; } +const bool CGUIGridLayout_Impl::SetCellFullSize(const int column, const int row, const bool fullSize) +{ + auto* cell = GetCell(column, row); + + if (cell == nullptr) + return false; + + cell->forceFullSize = fullSize; + RepositionGridCell(*cell, true); + return true; +} + +const bool CGUIGridLayout_Impl::SetDefaultCellFullSize(const bool fullSize, const bool updateExisting) +{ + m_defaultFullSize = fullSize; + + if (updateExisting) + { + for (auto& cell : m_cells) + { + cell.second->forceFullSize = fullSize; + } + + RepositionGridCells(true); + } + + return true; +} + +const bool CGUIGridLayout_Impl::GetCellFullSize(const int column, const int row) const +{ + auto* cell = GetCell(column, row); + + if (cell == nullptr) + return false; + + return cell->forceFullSize; +} + +const bool CGUIGridLayout_Impl::SetCellPadding(const int column, const int row, const CVector2D& padding) +{ + auto* cell = GetCell(column, row); + + if (cell == nullptr) + return false; + + cell->padding = padding; + RepositionGridCell(*cell, true); + return true; +} + +const bool CGUIGridLayout_Impl::SetDefaultCellPadding(const CVector2D& padding, const bool updateExisting) +{ + m_defaultPadding = padding; + + for (auto& cell : m_cells) + { + cell.second->padding = padding; + } + + RepositionGridCells(true); + return true; +} + +const CVector2D& CGUIGridLayout_Impl::GetCellPadding(const int column, const int row) const +{ + auto* cell = GetCell(column, row); + + if (cell == nullptr) + return m_defaultPadding; + + return cell->padding; +} + +const bool CGUIGridLayout_Impl::SetCellTexture(const int column, const int row, CGUITexture* texture, const bool alt) +{ + auto* cell = GetCell(column, row); + + if (cell == nullptr) + return false; + + cell->container->LoadFromTexture(texture); + return true; +} + +const bool CGUIGridLayout_Impl::SetCellColor(const int column, const int row, const CColor& color, const bool alt) +{ + auto* cell = GetCell(column, row); + + if (cell == nullptr) + return false; + + auto* texture = m_pManager->CreateTexture(); + unsigned long argb = COLOR_ARGB(color.A, color.R, color.G, color.B); + + texture->LoadFromMemory(&argb, 1, 1); + cell->container->LoadFromTexture(texture); + + return true; +} + +const bool CGUIGridLayout_Impl::SetDefaultCellTexture(CGUITexture* texture, const bool alt, const bool updateExisting) +{ + if (alt) + m_cellTextureAlt = texture; + else + m_cellTexture = texture; + + if (updateExisting) + { + for (auto& cell : m_cells) + { + cell.second->container->LoadFromTexture(texture); + } + } + + return true; +} + +const bool CGUIGridLayout_Impl::SetDefaultCellColor(const CColor& color, const bool alt, const bool updateExisting) +{ + auto* texture = m_pManager->CreateTexture(); + unsigned long argb = COLOR_ARGB(color.A, color.R, color.G, color.B); + + texture->LoadFromMemory(&argb, 1, 1); + return SetDefaultCellTexture(texture, alt, updateExisting); +} + void CGUIGridLayout_Impl::CreateGridCells() { auto* parent = reinterpret_cast(this); @@ -418,6 +546,8 @@ void CGUIGridLayout_Impl::CreateGridCells() auto* cellItem = new SGridCellItem(); cellItem->container = m_pManager->CreateStaticImage(parent); cellItem->alignment = m_defaultAlignment; + cellItem->forceFullSize = m_defaultFullSize; + cellItem->padding = m_defaultPadding; // Assign the cell container texture, alternative between m_cellTexture and m_cellTextureAlt cellItem->container->LoadFromTexture((i + j) % 2 == 0 ? m_cellTexture : m_cellTextureAlt); @@ -431,19 +561,28 @@ void CGUIGridLayout_Impl::CreateGridCells() // Size the cell container in the grid cellItem->container->SetSize(CalculateCellSize(*cellItem, offsets), true); + // Create a test label for the cell + auto* label = m_pManager->CreateLabel(cellItem->container, std::to_string(m_nextId).c_str()); + cellItem->id = m_nextId; + cellItem->element = label; + cellItem->column = i + 1; + cellItem->row = j + 1; - auto* label = m_pManager->CreateLabel(cellItem->container, std::to_string(m_nextId).c_str()); - label->AutoSize(); + label->SetFrameEnabled(true); + label->SetHorizontalAlign(CGUI_ALIGN_HORIZONTALCENTER); + label->SetVerticalAlign(CGUI_ALIGN_VERTICALCENTER); + + // For testing purposes. Use CGUIGridLayout::SetCellFullSize in proper implementation + if (cellItem->forceFullSize) + label->SetSize(CVector2D(1.0f - (cellItem->padding.fX * 2.0f), 1.0f - (cellItem->padding.fY * 2.0f)), true); + else + label->SetSize(CVector2D(0.2f, 0.2f), true); CVector2D offset = GetAlignmentOffset(*cellItem, label->GetSize(true)); label->SetPosition(offset, true); label->ForceRedraw(); - cellItem->element = label; - cellItem->column = i + 1; - cellItem->row = j + 1; - m_cells.emplace(m_nextId, cellItem); m_grid[i][j] = m_nextId; @@ -491,10 +630,9 @@ const CVector2D CGUIGridLayout_Impl::CalculateCellPosition(const SGridCellItem& if (cell.element != nullptr) cell.element->SetText(std::to_string(std::max(0, cell.column - widths)).c_str()); - return CVector2D(offsets.first + (std::max(0, cell.column - CountColumnWidths(cell.column) - 1) * - ((1.0f - AccumulateOffset(m_columnWidths)) / (m_columns - widths))), - offsets.second + (std::max(0, cell.row - CountRowHeights(cell.row) - 1) * - ((1.0f - AccumulateOffset(m_rowHeights)) / (m_rows - heights)))); + return CVector2D( + offsets.first + (std::max(0, cell.column - CountColumnWidths(cell.column) - 1) * ((1.0f - AccumulateOffset(m_columnWidths)) / (m_columns - widths))), + offsets.second + (std::max(0, cell.row - CountRowHeights(cell.row) - 1) * ((1.0f - AccumulateOffset(m_rowHeights)) / (m_rows - heights)))); } const CVector2D CGUIGridLayout_Impl::CalculateCellSize(const SGridCellItem& cell, const std::pair& offsets) const @@ -565,6 +703,11 @@ void CGUIGridLayout_Impl::RepositionGridCells(const bool itemOnly) const if (cellItem->element != nullptr) { + if (cellItem->forceFullSize) + { + cellItem->element->SetSize(CVector2D(1.0f - (cellItem->padding.fX * 2.0f), 1.0f - (cellItem->padding.fY * 2.0f)), true); + } + CVector2D position = GetAlignmentOffset(*cellItem, cellItem->element->GetSize(true)); cellItem->element->SetPosition(position, true); cellItem->element->ForceRedraw(); @@ -592,6 +735,11 @@ void CGUIGridLayout_Impl::RepositionGridCell(const SGridCellItem& cell, const bo if (cell.element != nullptr) { + if (cell.forceFullSize) + { + cell.element->SetSize(CVector2D(1.0f - (cell.padding.fX * 2.0f), 1.0f - (cell.padding.fY * 2.0f)), true); + } + CVector2D position = GetAlignmentOffset(cell, cell.element->GetSize(true)); cell.element->SetPosition(position, true); cell.element->ForceRedraw(); @@ -627,37 +775,42 @@ const CVector2D CGUIGridLayout_Impl::GetAlignmentOffset(const SGridCellItem& cel { CVector2D offset; - switch (cell.alignment) + if (!cell.forceFullSize) { - case eGridLayoutItemAlignment::TOP_LEFT: - offset = CVector2D(0.0f, 0.0f); - break; - case eGridLayoutItemAlignment::TOP_CENTER: - offset = CVector2D((1.0f - size.fX) / 2.0f, 0.0f); - break; - case eGridLayoutItemAlignment::TOP_RIGHT: - offset = CVector2D(1.0f - size.fX, 0.0f); - break; - case eGridLayoutItemAlignment::MIDDLE_LEFT: - offset = CVector2D(0.0f, (1.0f - size.fY) / 2.0f); - break; - case eGridLayoutItemAlignment::MIDDLE_CENTER: - offset = CVector2D((1.0f - size.fX) / 2.0f, (1.0f - size.fY) / 2.0f); - break; - case eGridLayoutItemAlignment::MIDDLE_RIGHT: - offset = CVector2D(1.0f - size.fX, (1.0f - size.fY) / 2.0f); - break; - case eGridLayoutItemAlignment::BOTTOM_LEFT: - offset = CVector2D(0.0f, 1.0f - size.fY); - break; - case eGridLayoutItemAlignment::BOTTOM_CENTER: - offset = CVector2D((1.0f - size.fX) / 2.0f, 1.0f - size.fY); - break; - case eGridLayoutItemAlignment::BOTTOM_RIGHT: - offset = CVector2D(1.0f - size.fX, 1.0f - size.fY); - break; + switch (cell.alignment) + { + case eGridLayoutItemAlignment::TOP_LEFT: + offset += CVector2D(0.0f, 0.0f); + break; + case eGridLayoutItemAlignment::TOP_CENTER: + offset += CVector2D(0.5f - (size.fX / 2.0f), 0.0f); + break; + case eGridLayoutItemAlignment::TOP_RIGHT: + offset += CVector2D(1.0f - size.fX, 0.0f); + break; + case eGridLayoutItemAlignment::MIDDLE_LEFT: + offset += CVector2D(0.0f, 0.5f - (size.fY / 2.0f)); + break; + case eGridLayoutItemAlignment::MIDDLE_CENTER: + offset += CVector2D(0.5f - (size.fX / 2.0f), 0.5f - (size.fY / 2.0f)); + break; + case eGridLayoutItemAlignment::MIDDLE_RIGHT: + offset += CVector2D(1.0f - size.fX, 0.5f - (size.fY / 2.0f)); + break; + case eGridLayoutItemAlignment::BOTTOM_LEFT: + offset += CVector2D(0.0f, 1.0f - size.fY); + break; + case eGridLayoutItemAlignment::BOTTOM_CENTER: + offset += CVector2D(0.5f - (size.fX / 2.0f), 1.0f - size.fY); + break; + case eGridLayoutItemAlignment::BOTTOM_RIGHT: + offset += CVector2D(1.0f - size.fX, 1.0f - size.fY); + break; + } } + offset = CVector2D(std::min(offset.fX, 1.0f - size.fX - cell.padding.fX), std::min(offset.fY, 1.0f - size.fY - cell.padding.fY)); + offset = CVector2D(std::max(offset.fX, cell.padding.fX), std::max(offset.fY, cell.padding.fY)); return offset; } diff --git a/Client/gui/CGUIGridLayout_Impl.h b/Client/gui/CGUIGridLayout_Impl.h index d2a699d480..2f63fe13ff 100644 --- a/Client/gui/CGUIGridLayout_Impl.h +++ b/Client/gui/CGUIGridLayout_Impl.h @@ -61,6 +61,24 @@ class CGUIGridLayout_Impl : public CGUIGridLayout, public CGUIElement_Impl const bool SetColumnWidth(const int column, const float width); const bool SetRowHeight(const int row, const float height); + const bool SetCellFullSize(const int column, const int row, const bool fullSize); + const bool SetDefaultCellFullSize(const bool fullSize, const bool updateExisting = false); + + const bool GetCellFullSize(const int column, const int row) const; + const bool GetDefaultCellFullSize() const { return m_defaultFullSize; } + + const bool SetCellPadding(const int column, const int row, const CVector2D& padding); + const bool SetDefaultCellPadding(const CVector2D& padding, const bool updateExisting); + + const CVector2D& GetCellPadding(const int column, const int row) const; + const CVector2D& GetDefaultCellPadding() const { return m_defaultPadding; } + + const bool SetCellTexture(const int column, const int row, CGUITexture* texture, const bool alt = false); + const bool SetCellColor(const int column, const int row, const CColor& color, const bool alt = false); + + const bool SetDefaultCellTexture(CGUITexture* texture, const bool alt = false, const bool updateExisting = false); + const bool SetDefaultCellColor(const CColor& color, const bool alt = false, const bool updateExisting = false); + #include "CGUIElement_Inc.h" private: @@ -86,6 +104,9 @@ class CGUIGridLayout_Impl : public CGUIGridLayout, public CGUIElement_Impl eGridLayoutItemAlignment m_defaultAlignment = eGridLayoutItemAlignment::MIDDLE_CENTER; + bool m_defaultFullSize = false; + CVector2D m_defaultPadding = CVector2D(0.1f, 0.1f); + void CreateGridCells(); void CleanupGridCells(); diff --git a/Client/sdk/gui/CGUIGridLayout.h b/Client/sdk/gui/CGUIGridLayout.h index af0f5d1cd6..796e321e74 100644 --- a/Client/sdk/gui/CGUIGridLayout.h +++ b/Client/sdk/gui/CGUIGridLayout.h @@ -13,10 +13,13 @@ #include "CGUIElement.h" #include "CGUIGridLayout.h" +#include <../Shared/sdk/CVector2D.h> +#include <../Shared/sdk/CColor.h> #include class CGUIStaticImage; +class CGUITexture; enum class eGridLayoutItemAlignment { @@ -39,6 +42,8 @@ struct SGridCellItem eGridLayoutItemAlignment alignment; int column; int row; + bool forceFullSize; + CVector2D padding; }; class CGUIGridLayout : public CGUIElement @@ -86,4 +91,22 @@ class CGUIGridLayout : public CGUIElement virtual const bool SetColumnWidth(const int column, const float width) = 0; virtual const bool SetRowHeight(const int row, const float height) = 0; + + virtual const bool SetCellFullSize(const int column, const int row, const bool fullSize) = 0; + virtual const bool SetDefaultCellFullSize(const bool fullSize, const bool updateExisting = false) = 0; + + virtual const bool GetCellFullSize(const int column, const int row) const = 0; + virtual const bool GetDefaultCellFullSize() const = 0; + + virtual const bool SetCellPadding(const int column, const int row, const CVector2D& padding) = 0; + virtual const bool SetDefaultCellPadding(const CVector2D& padding, const bool updateExisting) = 0; + + virtual const CVector2D& GetCellPadding(const int column, const int row) const = 0; + virtual const CVector2D& GetDefaultCellPadding() const = 0; + + virtual const bool SetCellTexture(const int column, const int row, CGUITexture* texture, const bool alt = false) = 0; + virtual const bool SetCellColor(const int column, const int row, const CColor& color, const bool alt = false) = 0; + + virtual const bool SetDefaultCellTexture(CGUITexture* texture, const bool alt = false, const bool updateExisting = false) = 0; + virtual const bool SetDefaultCellColor(const CColor& color, const bool alt = false, const bool updateExisting = false) = 0; }; diff --git a/Shared/sdk/CColor.h b/Shared/sdk/CColor.h new file mode 100644 index 0000000000..92f506926d --- /dev/null +++ b/Shared/sdk/CColor.h @@ -0,0 +1,42 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto: San Andreas + * LICENSE: See LICENSE in the top level directory + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ +#pragma once + +class CColor +{ +public: + CColor() { R = G = B = A = 255; } + CColor(unsigned char _R, unsigned char _G, unsigned char _B, unsigned char _A = 255) + { + R = _R; + G = _G; + B = _B; + A = _A; + } + CColor(const CColor& other) { *this = other; } + CColor(unsigned long ulColor) { *this = ulColor; } + CColor& operator=(const CColor& color) + { + R = color.R; + G = color.G; + B = color.B; + A = color.A; + return *this; + } + CColor& operator=(unsigned long ulColor) + { + R = (ulColor >> 16) & 0xFF; + G = (ulColor >> 8) & 0xFF; + B = (ulColor)&0xFF; + return *this; + } + bool operator==(const CColor& other) const { return R == other.R && G == other.G && B == other.B && A == other.A; } + + unsigned char R, G, B, A; +};