Draw blank squares for empty blocks in the grid.
Import vectorwrapper, it's just too convenient. It's only used in one place for now but I will probably use it more from now on.
This commit is contained in:
parent
88be1a1247
commit
0d287a60f1
8 changed files with 127 additions and 20 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
|||
[submodule "subprojects/cxxopts"]
|
||||
path = subprojects/cxxopts
|
||||
url = https://github.com/jarro2783/cxxopts.git
|
||||
[submodule "subprojects/vectorwrapper"]
|
||||
path = subprojects/vectorwrapper
|
||||
url = http://alarmpi.no-ip.org/gitan/King_DuckZ/vectorwrapper.git
|
||||
|
|
|
@ -50,4 +50,7 @@ cxxopts_incl = include_directories('subprojects/cxxopts/include', '.')
|
|||
memcard_proj = subproject('memcard')
|
||||
memcard_dep = memcard_proj.get_variable('memcard_dep')
|
||||
|
||||
vectorwrapper_proj = subproject('vectorwrapper')
|
||||
vectorwrapper_dep = vectorwrapper_proj.get_variable('vectorwrapper_dep')
|
||||
|
||||
subdir('src')
|
||||
|
|
|
@ -100,10 +100,11 @@ void MemoservWin::open_file_from_dialog() {
|
|||
|
||||
m_memcards.push_back(mc::psx::make_memory_card(file.toStdString()));
|
||||
auto& mc = m_memcards.back();
|
||||
auto grid = std::make_unique<widget::BlockGrid>(this, 3, g_icon_fps);
|
||||
auto grid = std::make_unique<widget::BlockGrid>(this, 5, 3, g_icon_fps);
|
||||
grid->set_icon_size(g_icon_size);
|
||||
for (const auto& block : mc) {
|
||||
for (std::size_t n = 0; block.has_magic() and n < block.block_count(); ++n) {
|
||||
grid->emplace_back(make_qt_animation(block, g_icon_size, g_icon_size, g_icon_fps));
|
||||
grid->push_back(make_qt_animation(block, g_icon_size, g_icon_size));
|
||||
}
|
||||
}
|
||||
m_main_lay->addWidget(grid.release(), 1, m_grid_count);
|
||||
|
|
|
@ -38,6 +38,11 @@ executable(app_name,
|
|||
'make_qt_animation.cpp',
|
||||
'animated_pixmap.cpp',
|
||||
include_directories: inc,
|
||||
dependencies: [qt5_dep, fslib_dep, memcard_dep],
|
||||
dependencies: [
|
||||
qt5_dep,
|
||||
fslib_dep,
|
||||
memcard_dep,
|
||||
vectorwrapper_dep
|
||||
],
|
||||
install: true,
|
||||
)
|
||||
|
|
45
src/qt/vec.hpp
Normal file
45
src/qt/vec.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* Copyright 2020, Michele Santullo
|
||||
* This file is part of memoserv.
|
||||
*
|
||||
* Memoserv is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Memoserv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Memoserv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vectorwrapper/vectorwrapper.hpp>
|
||||
#include <QPoint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace duck::detail {
|
||||
struct VecSimpleXYPoint { int x, y; };
|
||||
} //namespace duck::detail
|
||||
|
||||
namespace vwr {
|
||||
template <>
|
||||
struct VectorWrapperInfo<QPoint> {
|
||||
enum { dimensions = 2 };
|
||||
typedef int scalar_type;
|
||||
typedef QPoint vector_type;
|
||||
|
||||
static_assert(sizeof(duck::detail::VecSimpleXYPoint) == sizeof(QPoint), "Unexpected QPoint size, maybe you will have to provide get_at()");
|
||||
enum {
|
||||
offset_x = offsetof(duck::detail::VecSimpleXYPoint, x),
|
||||
offset_y = offsetof(duck::detail::VecSimpleXYPoint, y)
|
||||
};
|
||||
};
|
||||
} //namespace vwr
|
||||
|
||||
namespace duck {
|
||||
typedef vwr::Vec<QPoint> qtint2;
|
||||
} //namespace duck
|
|
@ -16,18 +16,36 @@
|
|||
*/
|
||||
|
||||
#include "block_grid.hpp"
|
||||
#include "vec.hpp"
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace duck::widget {
|
||||
namespace {
|
||||
const constexpr int g_icon_spacing = 3;
|
||||
|
||||
[[gnu::const]]
|
||||
qtint2 scalar_to_point (int scalar, int max) {
|
||||
return {
|
||||
scalar % max,
|
||||
scalar / max
|
||||
};
|
||||
}
|
||||
|
||||
[[gnu::const]]
|
||||
qtint2 to_qtint2 (const QSize& sz) {
|
||||
return {sz.width(), sz.height()};
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
BlockGrid::BlockGrid (QWidget* parent, unsigned int columns, float fps) :
|
||||
BlockGrid::BlockGrid (QWidget* parent, unsigned int rows, unsigned int columns, float fps) :
|
||||
QWidget(parent),
|
||||
m_anim_timer(new QTimer(this)),
|
||||
m_icon_size(-1, -1),
|
||||
m_rows(rows),
|
||||
m_columns(columns)
|
||||
{
|
||||
fps = std::max(fps, 1.0f);
|
||||
|
@ -43,9 +61,9 @@ QSize BlockGrid::minimumSizeHint() const {
|
|||
|
||||
QSize BlockGrid::sizeHint() const {
|
||||
if (m_columns) {
|
||||
const auto w = icon_width() * m_columns + g_icon_spacing * (1 + m_columns);
|
||||
const unsigned int rows = size() / m_columns;
|
||||
const auto h = icon_height() * rows + g_icon_spacing * (rows + 1);
|
||||
const auto w = icon_size().width() * m_columns + g_icon_spacing * (1 + m_columns);
|
||||
const unsigned int rows = (m_rows ? m_rows : size() / m_columns);
|
||||
const auto h = icon_size().height() * rows + g_icon_spacing * (rows + 1);
|
||||
|
||||
return {static_cast<int>(w), static_cast<int>(h)};
|
||||
}
|
||||
|
@ -54,12 +72,23 @@ QSize BlockGrid::sizeHint() const {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int BlockGrid::icon_width() const {
|
||||
return m_icons.empty() ? static_cast<unsigned int>(g_icon_spacing) : m_icons.front().size().width();
|
||||
void BlockGrid::set_icon_size (const QSize& sz) {
|
||||
if (sz != m_icon_size) {
|
||||
m_icon_size = sz;
|
||||
m_empty_icon.reset();
|
||||
if (m_icon_size.isValid()) {
|
||||
m_empty_icon = std::make_unique<QPixmap>(m_icon_size);
|
||||
m_empty_icon->fill(QColor(115, 115, 115, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int BlockGrid::icon_height() const {
|
||||
return m_icons.empty() ? static_cast<unsigned int>(g_icon_spacing) : m_icons.front().size().height();
|
||||
void BlockGrid::set_icon_size (int sz) {
|
||||
set_icon_size(QSize{sz, sz});
|
||||
}
|
||||
|
||||
QSize BlockGrid::icon_size() const {
|
||||
return m_icon_size.isValid() ? m_icon_size : QSize(g_icon_spacing, g_icon_spacing);
|
||||
}
|
||||
|
||||
void BlockGrid::push_back (AnimatedPixmap&& anim) {
|
||||
|
@ -70,6 +99,17 @@ std::size_t BlockGrid::size() const {
|
|||
return m_icons.size();
|
||||
}
|
||||
|
||||
unsigned int BlockGrid::rows() const {
|
||||
if (m_rows) {
|
||||
return m_rows;
|
||||
}
|
||||
else {
|
||||
const auto widget_h = static_cast<unsigned int>(std::max(this->height(), g_icon_spacing));
|
||||
const auto ico_spacing_uns = static_cast<unsigned int>(g_icon_spacing);
|
||||
return (widget_h - ico_spacing_uns) / (icon_size().height() + ico_spacing_uns);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int BlockGrid::columns() const {
|
||||
if (m_columns) {
|
||||
return m_columns;
|
||||
|
@ -78,26 +118,29 @@ unsigned int BlockGrid::columns() const {
|
|||
const auto widget_w = static_cast<unsigned int>(std::max(this->width(), g_icon_spacing));
|
||||
const auto ico_spacing_uns = static_cast<unsigned int>(g_icon_spacing);
|
||||
|
||||
return (widget_w - ico_spacing_uns) / (icon_width() + ico_spacing_uns);
|
||||
return (widget_w - ico_spacing_uns) / (icon_size().width() + ico_spacing_uns);
|
||||
}
|
||||
}
|
||||
|
||||
void BlockGrid::paintEvent (QPaintEvent* event) {
|
||||
QPainter painter(this);
|
||||
const int max_col = static_cast<int>(this->columns());
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int count = 0;
|
||||
|
||||
for (auto& ico : m_icons) {
|
||||
x = g_icon_spacing + (count % max_col) * (g_icon_spacing + ico.size().width());
|
||||
y = g_icon_spacing + (count / max_col) * (g_icon_spacing + ico.size().height());
|
||||
auto point = g_icon_spacing + scalar_to_point(count, max_col) * (g_icon_spacing + to_qtint2(ico.size()));
|
||||
if (ico.frame_count()) {
|
||||
painter.drawPixmap(x, y, ico.current_frame());
|
||||
painter.drawPixmap(point.x(), point.y(), ico.current_frame());
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
const int total_squares = static_cast<int>(rows() * columns());
|
||||
for (int z = count; z < total_squares && m_empty_icon; ++z) {
|
||||
auto point = g_icon_spacing + scalar_to_point(z, max_col) * (g_icon_spacing + to_qtint2(icon_size()));
|
||||
painter.drawPixmap(point.x(), point.y(), *m_empty_icon);
|
||||
}
|
||||
}
|
||||
|
||||
void BlockGrid::advance_frame() {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "../animated_pixmap.hpp"
|
||||
#include <QWidget>
|
||||
#include <QPixmap>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
@ -28,14 +29,15 @@ namespace duck::widget {
|
|||
class BlockGrid : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BlockGrid (QWidget* parent=nullptr, unsigned int columns=0, float fps=24.0f);
|
||||
explicit BlockGrid (QWidget* parent=nullptr, unsigned int rows=0, unsigned int columns=0, float fps=24.0f);
|
||||
~BlockGrid() noexcept;
|
||||
|
||||
QSize minimumSizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
unsigned int icon_width() const;
|
||||
unsigned int icon_height() const;
|
||||
void set_icon_size (const QSize& sz);
|
||||
void set_icon_size (int sz);
|
||||
QSize icon_size() const;
|
||||
|
||||
void push_back (AnimatedPixmap&& anim);
|
||||
std::size_t size() const;
|
||||
|
@ -47,10 +49,14 @@ private slots:
|
|||
void advance_frame();
|
||||
|
||||
private:
|
||||
unsigned int rows() const;
|
||||
unsigned int columns() const;
|
||||
|
||||
std::vector<AnimatedPixmap> m_icons;
|
||||
QTimer* m_anim_timer;
|
||||
std::unique_ptr<QPixmap> m_empty_icon;
|
||||
QSize m_icon_size;
|
||||
unsigned int m_rows;
|
||||
unsigned int m_columns;
|
||||
};
|
||||
} //namespace duck::widget
|
||||
|
|
1
subprojects/vectorwrapper
Submodule
1
subprojects/vectorwrapper
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 0a90a289a2c354c88130dbf04a4c15c696e0a9de
|
Loading…
Add table
Reference in a new issue