1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 20:35:07 +00:00
serenity/Userland/Games/2048/BoardView.cpp
Brian Gianforcaro 1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00

200 lines
4.7 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "BoardView.h"
#include <LibGUI/Painter.h>
#include <LibGfx/Font.h>
#include <LibGfx/FontDatabase.h>
#include <LibGfx/Palette.h>
BoardView::BoardView(const Game::Board* board)
: m_board(board)
{
}
BoardView::~BoardView()
{
}
void BoardView::set_board(const Game::Board* board)
{
if (m_board == board)
return;
if (!board) {
m_board = nullptr;
return;
}
bool must_resize = !m_board || m_board->size() != board->size();
m_board = board;
if (must_resize)
resize();
update();
}
void BoardView::pick_font()
{
String best_font_name;
int best_font_size = -1;
auto& font_database = Gfx::FontDatabase::the();
font_database.for_each_font([&](const Gfx::Font& font) {
if (font.family() != "Liza" || font.weight() != 700)
return;
auto size = font.glyph_height();
if (size * 2 <= m_cell_size && size > best_font_size) {
best_font_name = font.qualified_name();
best_font_size = size;
}
});
auto font = font_database.get_by_name(best_font_name);
set_font(font);
}
size_t BoardView::rows() const
{
if (!m_board)
return 0;
return m_board->size();
}
size_t BoardView::columns() const
{
if (!m_board)
return 0;
if (m_board->is_empty())
return 0;
return (*m_board)[0].size();
}
void BoardView::resize_event(GUI::ResizeEvent&)
{
resize();
}
void BoardView::resize()
{
constexpr float padding_ratio = 7;
m_padding = min(
width() / (columns() * (padding_ratio + 1) + 1),
height() / (rows() * (padding_ratio + 1) + 1));
m_cell_size = m_padding * padding_ratio;
pick_font();
}
void BoardView::keydown_event(GUI::KeyEvent& event)
{
if (!on_move)
return;
switch (event.key()) {
case KeyCode::Key_A:
case KeyCode::Key_Left:
on_move(Game::Direction::Left);
break;
case KeyCode::Key_D:
case KeyCode::Key_Right:
on_move(Game::Direction::Right);
break;
case KeyCode::Key_W:
case KeyCode::Key_Up:
on_move(Game::Direction::Up);
break;
case KeyCode::Key_S:
case KeyCode::Key_Down:
on_move(Game::Direction::Down);
break;
default:
return;
}
}
Gfx::Color BoardView::background_color_for_cell(u32 value)
{
switch (value) {
case 0:
return Color::from_rgb(0xcdc1b4);
case 2:
return Color::from_rgb(0xeee4da);
case 4:
return Color::from_rgb(0xede0c8);
case 8:
return Color::from_rgb(0xf2b179);
case 16:
return Color::from_rgb(0xf59563);
case 32:
return Color::from_rgb(0xf67c5f);
case 64:
return Color::from_rgb(0xf65e3b);
case 128:
return Color::from_rgb(0xedcf72);
case 256:
return Color::from_rgb(0xedcc61);
case 512:
return Color::from_rgb(0xedc850);
case 1024:
return Color::from_rgb(0xedc53f);
case 2048:
return Color::from_rgb(0xedc22e);
default:
VERIFY(value > 2048);
return Color::from_rgb(0x3c3a32);
}
}
Gfx::Color BoardView::text_color_for_cell(u32 value)
{
if (value <= 4)
return Color::from_rgb(0x776e65);
return Color::from_rgb(0xf9f6f2);
}
void BoardView::paint_event(GUI::PaintEvent& event)
{
Frame::paint_event(event);
Color background_color = Color::from_rgb(0xbbada0);
GUI::Painter painter(*this);
painter.add_clip_rect(event.rect());
painter.add_clip_rect(frame_inner_rect());
painter.translate(frame_thickness(), frame_thickness());
if (!m_board) {
painter.fill_rect(rect(), background_color);
return;
}
auto& board = *m_board;
Gfx::IntRect field_rect {
0,
0,
static_cast<int>(m_padding + (m_cell_size + m_padding) * columns()),
static_cast<int>(m_padding + (m_cell_size + m_padding) * rows())
};
field_rect.center_within(rect());
painter.fill_rect(field_rect, background_color);
for (size_t column = 0; column < columns(); ++column) {
for (size_t row = 0; row < rows(); ++row) {
auto rect = Gfx::IntRect {
field_rect.x() + m_padding + (m_cell_size + m_padding) * column,
field_rect.y() + m_padding + (m_cell_size + m_padding) * row,
m_cell_size,
m_cell_size,
};
auto entry = board[row][column];
painter.fill_rect(rect, background_color_for_cell(entry));
if (entry > 0)
painter.draw_text(rect, String::number(entry), font(), Gfx::TextAlignment::Center, text_color_for_cell(entry));
}
}
}