205 lines
8.0 KiB
C++
205 lines
8.0 KiB
C++
#include "Drawer.h"
|
|
|
|
static const char* tileImageNames[TILE_IMAGES_N] = {
|
|
// clang-format off
|
|
"Pin1", "Pin2", "Pin3", "Pin4", "Pin5", "Pin6", "Pin7", "Pin8", "Pin9",
|
|
"Sou1", "Sou2", "Sou3", "Sou4", "Sou5", "Sou6", "Sou7", "Sou8", "Sou9",
|
|
"Man1", "Man2", "Man3", "Man4", "Man5", "Man6", "Man7", "Man8", "Man9",
|
|
"Chun", "Haku", "Hatsu",
|
|
"Nan", "Pei", "Shaa", "Ton",
|
|
"Flower1", "Flower2", "Flower3", "Flower4",
|
|
"Season1", "Season2", "Season3", "Season4"
|
|
// clang-format on
|
|
};
|
|
|
|
static const wxColor lGreen{0x07, 0x55, 0x2b};
|
|
static const wxColor dGreen{0x01, 0x2d, 0x16};
|
|
|
|
Drawer::Drawer() : marked{-1, -1, -1} {
|
|
for (int i = 0; i < TILE_IMAGES_N; i++) {
|
|
bool succeed = tileImages[i].LoadFile(
|
|
_("./resources/tiles/") + _(tileImageNames[i]) + _(".png"),
|
|
wxBITMAP_TYPE_PNG);
|
|
if (!succeed)
|
|
wxLogDebug(_("failed to load tile ./resources/tiles/") +
|
|
_(tileImageNames[i]) + _(".png with index") +
|
|
wxString::Format("%i", i));
|
|
}
|
|
}
|
|
|
|
void Drawer::drawTable(wxDC& dc) {
|
|
dc.DrawBitmap(bgBitmap, 0, 0, false);
|
|
if (boardBitmap.IsOk()) {
|
|
wxLogDebug("Drawing board");
|
|
dc.DrawBitmap(boardBitmap, tablePixelRect.GetPosition(), true);
|
|
}
|
|
}
|
|
|
|
void Drawer::composeBG() {
|
|
bgBitmap = wxBitmap(resolution);
|
|
|
|
wxLogDebug(
|
|
wxString::Format("Rebuild bg %i %i", resolution.x, resolution.y));
|
|
|
|
wxMemoryDC dc;
|
|
dc.SelectObject(bgBitmap);
|
|
|
|
dc.GradientFillConcentric(wxRect(wxPoint(0, 0), resolution), lGreen,
|
|
dGreen);
|
|
}
|
|
|
|
void Drawer::composeBoard(const TLVec& layout, const Dimensions& gridSize) {
|
|
boardBitmap = wxBitmap(tablePixelRect.GetSize());
|
|
|
|
wxLogDebug(_("Rebuild board"));
|
|
|
|
wxMemoryDC dc;
|
|
dc.SelectObject(boardBitmap);
|
|
|
|
for (int z = 0; z < gridSize.z; z++)
|
|
for (int x = 0; x < gridSize.x; x++)
|
|
for (int y = 0; y < gridSize.y; y++) {
|
|
CardT c = layout[z][x][y];
|
|
if (c >= 0)
|
|
drawTile(dc, c, fromGrid(x, y), z);
|
|
}
|
|
|
|
dc.SelectObject(wxNullBitmap);
|
|
|
|
wxMask* mask = new wxMask(boardBitmap, wxColor(0x00, 0x00, 0x00));
|
|
boardBitmap.SetMask(mask);
|
|
}
|
|
|
|
void Drawer::drawTile(wxDC& dc, int8_t index, const wxPoint& position,
|
|
uint8_t zIndex) const {
|
|
wxBrush _bgColor = dc.GetBrush();
|
|
|
|
wxBrush front = wxColor(0xff, 0xff, 0xff);
|
|
wxBrush back = wxColor(0xc8, 0xc8, 0xc8);
|
|
|
|
if (position == fromGrid({marked.x, marked.y}) && marked.z == zIndex) {
|
|
front = wxColor(0xc8, 0xff, 0xc8);
|
|
back = wxColor(0xbe, 0xdc, 0xbe);
|
|
}
|
|
|
|
dc.SetBrush(back);
|
|
|
|
dc.DrawRoundedRectangle(position.x + (tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE) -
|
|
(tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE) * zIndex,
|
|
position.y + (tilePixelSize.GetHeight() / TILE_WIDTH * TILE_PADDING_SCALE) -
|
|
(tilePixelSize.GetHeight() / TILE_WIDTH * TILE_PADDING_SCALE) * zIndex,
|
|
tilePixelSize.GetWidth() * 2,
|
|
tilePixelSize.GetHeight() * 2, (tilePixelSize.GetHeight() / TILE_HEIGHT * TILE_PADDING_SCALE));
|
|
|
|
dc.SetBrush(front);
|
|
|
|
dc.DrawRoundedRectangle(
|
|
position.x - (tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE) * zIndex,
|
|
position.y - (tilePixelSize.GetHeight() / TILE_WIDTH * TILE_PADDING_SCALE) * zIndex,
|
|
tilePixelSize.GetWidth() * 2, tilePixelSize.GetHeight() * 2, (tilePixelSize.GetHeight() / TILE_HEIGHT * TILE_PADDING_SCALE));
|
|
|
|
dc.SetBrush(_bgColor);
|
|
|
|
if (tileImages[index].IsOk()) {
|
|
wxPoint pos;
|
|
pos.x = position.x + (tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE) - (tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE) * zIndex;
|
|
pos.y = position.y + (tilePixelSize.GetHeight() / TILE_HEIGHT * TILE_PADDING_SCALE) - (tilePixelSize.GetHeight() / TILE_WIDTH * TILE_PADDING_SCALE) * zIndex;
|
|
|
|
if (tileImages[index].GetWidth() != tilePixelSize.x * 2 - tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE * 2)
|
|
dc.DrawBitmap(tileImages[index].Scale(tilePixelSize.x * 2 - tilePixelSize.GetWidth() / TILE_WIDTH * TILE_PADDING_SCALE * 2,
|
|
tilePixelSize.y * 2 - tilePixelSize.GetHeight() / TILE_HEIGHT * TILE_PADDING_SCALE * 2),
|
|
pos);
|
|
else
|
|
dc.DrawBitmap(tileImages[index], pos);
|
|
}
|
|
}
|
|
|
|
void Drawer::resizeBg(const wxSize& resolution) {
|
|
if (this->resolution != resolution) {
|
|
this->resolution = resolution;
|
|
composeBG();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resizes tile and whole board bitmap size to the resolution, set in this
|
|
* instance
|
|
*/
|
|
bool Drawer::resizeBoard(const TLVec& layout, const Dimensions& gridSize, bool force) {
|
|
bool res = false;
|
|
|
|
const int gridPoint = mmin(
|
|
resolution.x / (gridSize.x * TILE_WIDTH + gridSize.z * TILE_PADDING_SCALE),
|
|
resolution.y * TILE_WIDTH /
|
|
(gridSize.y * TILE_HEIGHT * TILE_WIDTH + TILE_HEIGHT * gridSize.z * TILE_PADDING_SCALE));
|
|
|
|
wxLogDebug(wxString::Format("Resize board: %i", gridPoint));
|
|
|
|
if (gridPoint != prevGridPoint || force) {
|
|
tilePixelSize.Set(gridPoint * TILE_WIDTH, gridPoint * TILE_HEIGHT);
|
|
|
|
boardPadding.x = (tilePixelSize.x / TILE_WIDTH * TILE_PADDING_SCALE) * (gridSize.z - 1); // Смещение, создаваемое самыми левыми картами на верхних позициях (их может и не быть, но проверять это дорого)
|
|
boardPadding.y = (tilePixelSize.y / TILE_WIDTH * TILE_PADDING_SCALE) * (gridSize.z - 1); // Смещение, создаваемое самыми верхними (в плоскости xy) картами на верхних позициях (их может и не быть, но проверять это дорого)
|
|
|
|
tablePixelRect.SetSize(
|
|
wxSize((tilePixelSize.x * gridSize.x) + // Размер только плоских карт
|
|
boardPadding.x + // см. выше
|
|
(tilePixelSize.x / TILE_WIDTH * TILE_PADDING_SCALE), // Смещение, даваемое подложками самых правых
|
|
(tilePixelSize.y * gridSize.y) + // Размер только плоских карт
|
|
boardPadding.y + // см. выше
|
|
(tilePixelSize.y / TILE_WIDTH * TILE_PADDING_SCALE) // Смещение, даваемое подложками самых нижних (в плоскости xy)
|
|
)
|
|
);
|
|
}
|
|
|
|
tablePixelRect.SetPosition({(resolution.x - tablePixelRect.width) / 2,
|
|
(resolution.y - tablePixelRect.height) / 2});
|
|
|
|
if (gridPoint != prevGridPoint || force) {
|
|
composeBoard(layout, gridSize);
|
|
res = true;
|
|
}
|
|
|
|
prevGridPoint = gridPoint;
|
|
|
|
return res;
|
|
}
|
|
|
|
wxPoint Drawer::toGrid(wxPoint point) const {
|
|
wxPoint out(-1, -1);
|
|
|
|
point.x -= boardPadding.x;
|
|
point.y -= boardPadding.y;
|
|
|
|
if (point.x >= tablePixelRect.x &&
|
|
point.x <= tablePixelRect.x + tablePixelRect.width &&
|
|
point.y >= tablePixelRect.y &&
|
|
point.y <= tablePixelRect.y + tablePixelRect.height) {
|
|
out.x = (point.x - tablePixelRect.x) / tilePixelSize.x;
|
|
out.y = (point.y - tablePixelRect.y) / tilePixelSize.y;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
wxPoint Drawer::fromGrid(int x, int y) const {
|
|
return {x * tilePixelSize.x + boardPadding.x, y * tilePixelSize.y + boardPadding.y};
|
|
}
|
|
|
|
wxPoint Drawer::fromGrid(const wxPoint& point) const {
|
|
return fromGrid(point.x, point.y);
|
|
}
|
|
|
|
wxSize Drawer::composeMinSize(const Dimensions& gridSize) {
|
|
wxSize ms;
|
|
|
|
ms.SetWidth(TILE_WIDTH * gridSize.x + gridSize.z * TILE_PADDING_SCALE);
|
|
ms.SetHeight(TILE_HEIGHT * gridSize.y + gridSize.z * TILE_PADDING_SCALE * TILE_HEIGHT / TILE_WIDTH);
|
|
|
|
ms += {1, 1};
|
|
|
|
wxLogDebug(wxString::Format("MinSize %i %i", ms.x, ms.y));
|
|
|
|
return ms;
|
|
}
|