Drag and drop work in progress implementation
This commit is contained in:
parent
7af7ce540d
commit
6b835cd1d9
11 changed files with 370 additions and 33 deletions
|
@ -1,7 +1,7 @@
|
||||||
project('memoserv', 'cpp',
|
project('memoserv', 'cpp',
|
||||||
version: '0.1.0',
|
version: '0.1.0',
|
||||||
meson_version: '>=0.63.0',
|
meson_version: '>=0.63.0',
|
||||||
default_options: ['debug=true', 'cpp_std=c++17', 'b_ndebug=if-release']
|
default_options: ['debug=true', 'cpp_std=c++20', 'b_ndebug=if-release']
|
||||||
)
|
)
|
||||||
|
|
||||||
is_debug_build = 0
|
is_debug_build = 0
|
||||||
|
|
|
@ -135,8 +135,7 @@ void MemoservWin::load_memory_cards (const QStringList& paths) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t n = 0; block.has_magic() and n < block.block_count(); ++n) {
|
for (std::size_t n = 0; block.has_magic() and n < block.block_count(); ++n) {
|
||||||
grid->push_back(make_qt_animation(block, g_icon_size, g_icon_size));
|
//grid->push_back(make_qt_animation(block, g_icon_size, g_icon_size));
|
||||||
m_lower_grid->push_back(make_qt_animation(block, g_icon_size, g_icon_size));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_main_lay->addWidget(grid.release(), 1, m_grid_count);
|
m_main_lay->addWidget(grid.release(), 1, m_grid_count);
|
||||||
|
|
|
@ -39,6 +39,7 @@ executable(app_name,
|
||||||
'make_qt_animation.cpp',
|
'make_qt_animation.cpp',
|
||||||
'animated_pixmap.cpp',
|
'animated_pixmap.cpp',
|
||||||
'savegame_db.cpp',
|
'savegame_db.cpp',
|
||||||
|
'savegame_model.cpp',
|
||||||
include_directories: inc,
|
include_directories: inc,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
qt6_dep,
|
qt6_dep,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "savegame_db.hpp"
|
#include "savegame_db.hpp"
|
||||||
#include "memcard/block.hpp"
|
#include "memcard/alignment.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
@ -24,21 +24,24 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
namespace duck {
|
namespace duck {
|
||||||
|
namespace {
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
BlockEntry::BlockEntry (
|
BlockEntry::BlockEntry (
|
||||||
std::vector<mc::psx::BasicBlock<false>>&& blocks,
|
std::unique_ptr<uint8_t[]>&& data,
|
||||||
std::unique_ptr<uint8_t[]>&& data
|
std::size_t count
|
||||||
) :
|
) :
|
||||||
blocks(std::move(blocks)),
|
data(std::move(data)),
|
||||||
data(std::move(data))
|
block_count(count)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view BlockEntry::identifier() const {
|
std::string_view BlockEntry::identifier() const {
|
||||||
return blocks.front().identifier();
|
return make_block<true>(0).identifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BlockEntry::title() const {
|
std::string BlockEntry::title() const {
|
||||||
return blocks.front().title();
|
return make_block<true>(0).title();
|
||||||
}
|
}
|
||||||
|
|
||||||
SavegameDb::SavegameDb() = default;
|
SavegameDb::SavegameDb() = default;
|
||||||
|
@ -52,31 +55,52 @@ unsigned int SavegameDb::add (const std::vector<mc::psx::BasicBlock<Const> >& bl
|
||||||
|
|
||||||
const auto block_count = blocks.size();
|
const auto block_count = blocks.size();
|
||||||
assert(block_count == blocks.front().block_count());
|
assert(block_count == blocks.front().block_count());
|
||||||
auto mem = std::make_unique<uint8_t[]>(frame_size + block_size * block_count);
|
|
||||||
|
|
||||||
uint8_t* dest = std::copy(blocks.front().toc().cbegin(), blocks.front().toc().cend(), mem.get());
|
static_assert(
|
||||||
assert(std::distance(mem.get(), dest) == frame_size);
|
frame_size % mc::psx::Block::DataAlignment == 0,
|
||||||
mc::psx::Frame toc(mem.get(), 0);
|
"Unexpected alignment, alignment in this class will be wrong if you ignore this error"
|
||||||
|
);
|
||||||
|
|
||||||
|
auto mem = mc::psx::make_unique_for_block_aligned(frame_size + block_size * block_count);
|
||||||
|
|
||||||
|
std::uint8_t* const ptr = mc::psx::to_block_aligned(mem.get());
|
||||||
|
uint8_t* dest = std::copy(blocks.front().toc().cbegin(), blocks.front().toc().cend(), ptr);
|
||||||
|
assert(mc::psx::is_block_aligned(dest));
|
||||||
|
assert(std::distance(ptr, dest) == frame_size);
|
||||||
|
mc::psx::Frame toc(ptr, 0);
|
||||||
|
|
||||||
std::vector<mc::psx::BasicBlock<false>> new_blocks;
|
|
||||||
new_blocks.reserve(block_count);
|
|
||||||
std::size_t index = 0;
|
|
||||||
for (const auto& block : blocks) {
|
for (const auto& block : blocks) {
|
||||||
assert(block_count == block.block_count() or block.block_count() == 0);
|
assert(block_count == block.block_count() or block.block_count() == 0);
|
||||||
uint8_t* const curr_block_ptr = dest;
|
uint8_t* const curr_block_ptr = dest;
|
||||||
dest = std::copy(block.data(), block.data() + block_size, dest);
|
dest = std::copy(block.data(), block.data() + block_size, dest);
|
||||||
new_blocks.emplace_back(curr_block_ptr, toc, index++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t new_id = m_next_id++;
|
const std::size_t new_id = m_next_id++;
|
||||||
m_saves.emplace(
|
m_saves.emplace(
|
||||||
std::piecewise_construct,
|
std::piecewise_construct,
|
||||||
std::forward_as_tuple(new_id),
|
std::forward_as_tuple(new_id),
|
||||||
std::forward_as_tuple(std::move(new_blocks), std::move(mem))
|
std::forward_as_tuple(std::move(mem), block_count)
|
||||||
);
|
);
|
||||||
|
m_block_count += block_count;
|
||||||
return static_cast<unsigned int>(m_saves.size() - 1u);
|
return static_cast<unsigned int>(m_saves.size() - 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t SavegameDb::savegame_count() const {
|
||||||
|
return m_saves.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t SavegameDb::block_count() const {
|
||||||
|
return m_block_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SavegameDb::begin() -> iterator {
|
||||||
|
return {m_saves.begin()};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SavegameDb::end() -> iterator {
|
||||||
|
return {m_saves.end()};
|
||||||
|
}
|
||||||
|
|
||||||
template unsigned int SavegameDb::add<true> (const std::vector<mc::psx::BasicBlock<true> >&);
|
template unsigned int SavegameDb::add<true> (const std::vector<mc::psx::BasicBlock<true> >&);
|
||||||
template unsigned int SavegameDb::add<false> (const std::vector<mc::psx::BasicBlock<false> >&);
|
template unsigned int SavegameDb::add<false> (const std::vector<mc::psx::BasicBlock<false> >&);
|
||||||
} //namespace duck
|
} //namespace duck
|
||||||
|
|
|
@ -17,41 +17,135 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "memcard/alignment.hpp"
|
||||||
|
#include "memcard/block.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
namespace mc::psx {
|
#include <iterator>
|
||||||
template <bool C> class BasicBlock;
|
#include <cassert>
|
||||||
} //namespace mc::psx
|
#include <ciso646>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace duck {
|
namespace duck {
|
||||||
struct BlockEntry {
|
struct BlockEntry {
|
||||||
BlockEntry (
|
BlockEntry (
|
||||||
std::vector<mc::psx::BasicBlock<false> >&& blocks,
|
std::unique_ptr<uint8_t[]>&& data,
|
||||||
std::unique_ptr<uint8_t[]>&& data
|
std::size_t count
|
||||||
);
|
);
|
||||||
|
|
||||||
|
template <bool C>
|
||||||
|
mc::psx::BasicBlock<C> make_block (std::size_t index) const;
|
||||||
std::string_view identifier() const;
|
std::string_view identifier() const;
|
||||||
std::string title() const;
|
std::string title() const;
|
||||||
|
std::uint8_t* data_ptr() const;
|
||||||
|
|
||||||
std::vector<mc::psx::BasicBlock<false> > blocks;
|
std::unique_ptr<std::uint8_t[]> data;
|
||||||
std::unique_ptr<uint8_t[]> data;
|
std::size_t block_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SavegameDb {
|
class SavegameDb {
|
||||||
|
typedef std::map<unsigned int, BlockEntry> SavegameMap;
|
||||||
public:
|
public:
|
||||||
|
template <typename It>
|
||||||
|
class BlockIterator {
|
||||||
|
It m_it;
|
||||||
|
std::size_t m_pos_in_it {0};
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename std::iterator_traits<It>::difference_type difference_type;
|
||||||
|
typedef mc::psx::BasicBlock<std::is_const<SavegameMap::mapped_type>::value> value_type;
|
||||||
|
typedef std::add_pointer<value_type>::type pointer;
|
||||||
|
typedef value_type reference;
|
||||||
|
typedef mc::psx::ConstBlock const_reference;
|
||||||
|
typedef typename std::iterator_traits<It>::iterator_category iterator_category;
|
||||||
|
|
||||||
|
BlockIterator() = default;
|
||||||
|
BlockIterator(const BlockIterator&) = default;
|
||||||
|
BlockIterator(BlockIterator&&) = default;
|
||||||
|
BlockIterator (It&& it) : m_it(std::move(it)) {}
|
||||||
|
BlockIterator (const It& it) : m_it(it) {}
|
||||||
|
|
||||||
|
bool operator!=(const BlockIterator& other) const
|
||||||
|
{return m_it!=other.m_it or m_pos_in_it!=other.m_pos_in_it;}
|
||||||
|
bool operator==(const BlockIterator& other) const
|
||||||
|
{return m_it==other.m_it and m_pos_in_it==other.m_pos_in_it;}
|
||||||
|
|
||||||
|
BlockIterator& operator++();
|
||||||
|
BlockIterator operator++(int);
|
||||||
|
reference operator*();
|
||||||
|
const_reference operator*() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BlockIterator<SavegameMap::iterator> iterator;
|
||||||
|
typedef BlockIterator<SavegameMap::const_iterator> const_iterator;
|
||||||
|
|
||||||
SavegameDb();
|
SavegameDb();
|
||||||
~SavegameDb() noexcept;
|
~SavegameDb() noexcept;
|
||||||
|
|
||||||
template <bool Const>
|
template <bool Const>
|
||||||
unsigned int add (const std::vector<mc::psx::BasicBlock<Const> >& blocks);
|
unsigned int add (const std::vector<mc::psx::BasicBlock<Const> >& blocks);
|
||||||
|
std::size_t savegame_count() const;
|
||||||
|
std::size_t block_count() const;
|
||||||
|
|
||||||
|
std::size_t size() const { return block_count(); }
|
||||||
|
iterator begin();
|
||||||
|
iterator end();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<unsigned int, BlockEntry> m_saves;
|
SavegameMap m_saves;
|
||||||
std::size_t m_next_id{0};
|
std::size_t m_next_id{0};
|
||||||
|
std::size_t m_block_count{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <bool C>
|
||||||
|
mc::psx::BasicBlock<C> BlockEntry::make_block (std::size_t index) const {
|
||||||
|
using mc::psx::to_block_aligned;
|
||||||
|
using mc::psx::Frame;
|
||||||
|
using FrameType = typename mc::psx::BasicBlock<C>::FrameType;
|
||||||
|
|
||||||
|
assert(this->block_count > 0);
|
||||||
|
assert(this->block_count > index);
|
||||||
|
|
||||||
|
constexpr std::size_t frame_index = 0;
|
||||||
|
return {
|
||||||
|
to_block_aligned(this->data.get(), index, Frame::Size),
|
||||||
|
FrameType{to_block_aligned(this->data.get()), frame_index},
|
||||||
|
index
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
SavegameDb::BlockIterator<It>& SavegameDb::BlockIterator<It>::operator++() {
|
||||||
|
const BlockEntry& entry = m_it->second;
|
||||||
|
++m_pos_in_it;
|
||||||
|
if (m_pos_in_it >= entry.block_count) {
|
||||||
|
++m_it;
|
||||||
|
m_pos_in_it = 0;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
SavegameDb::BlockIterator<It> SavegameDb::BlockIterator<It>::operator++(int) {
|
||||||
|
auto retval = *this;
|
||||||
|
this->operator++();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
auto SavegameDb::BlockIterator<It>::operator*() -> reference {
|
||||||
|
BlockEntry& entry = m_it->second;
|
||||||
|
return entry.make_block<value_type::IsConst>(m_pos_in_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename It>
|
||||||
|
auto SavegameDb::BlockIterator<It>::operator*() const -> const_reference {
|
||||||
|
BlockEntry& entry = m_it->second;
|
||||||
|
return entry.make_block<value_type::IsConst>(m_pos_in_it);
|
||||||
|
}
|
||||||
} //namespace duck
|
} //namespace duck
|
||||||
|
|
105
src/qt/savegame_model.cpp
Normal file
105
src/qt/savegame_model.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/* Copyright 2020-2025, 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "savegame_model.hpp"
|
||||||
|
#include "savegame_db.hpp"
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <ciso646>
|
||||||
|
|
||||||
|
namespace duck {
|
||||||
|
SavegameModel::SavegameModel() = default;
|
||||||
|
SavegameModel::~SavegameModel() noexcept = default;
|
||||||
|
|
||||||
|
MemoryCardSavegameModel::MemoryCardSavegameModel (mc::psx::MemoryCard* memcard) :
|
||||||
|
m_mc(memcard)
|
||||||
|
{
|
||||||
|
assert(m_mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavegameModel::iterator MemoryCardSavegameModel::begin() {
|
||||||
|
return {m_mc->begin()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SavegameModel::iterator MemoryCardSavegameModel::end() {
|
||||||
|
return {m_mc->end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t MemoryCardSavegameModel::block_count() const {
|
||||||
|
return m_mc->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryCardSavegameModel::has_toc() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::Block MemoryCardSavegameModel::toc() {
|
||||||
|
return m_mc->toc_block();
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::ConstBlock MemoryCardSavegameModel::toc() const {
|
||||||
|
return m_mc->toc_block();
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::Block MemoryCardSavegameModel::block (std::size_t index) {
|
||||||
|
return (*m_mc)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::ConstBlock MemoryCardSavegameModel::block (std::size_t index) const {
|
||||||
|
return (*m_mc)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
DbSavegameModel::DbSavegameModel (SavegameDb* db) :
|
||||||
|
m_db(db)
|
||||||
|
{
|
||||||
|
assert(m_db);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavegameModel::iterator DbSavegameModel::begin() {
|
||||||
|
return {m_db->begin()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SavegameModel::iterator DbSavegameModel::end() {
|
||||||
|
return {m_db->end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t DbSavegameModel::block_count() const {
|
||||||
|
return m_db->block_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DbSavegameModel::has_toc() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::Block DbSavegameModel::toc() {
|
||||||
|
throw std::runtime_error("TOC not available in SavegameDb");
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::ConstBlock DbSavegameModel::toc() const {
|
||||||
|
throw std::runtime_error("TOC not available in SavegameDb");
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::Block DbSavegameModel::block (std::size_t index) {
|
||||||
|
auto it = begin();
|
||||||
|
std::advance(it, index);
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
mc::psx::ConstBlock DbSavegameModel::block (std::size_t index) const {
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace duck
|
89
src/qt/savegame_model.hpp
Normal file
89
src/qt/savegame_model.hpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/* Copyright 2020-2025, 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 "memcard/memorycard.hpp"
|
||||||
|
#include "any_iterator.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace mc::psx {
|
||||||
|
template <bool> class BasicBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace duck {
|
||||||
|
class SavegameDb;
|
||||||
|
|
||||||
|
class SavegameModel {
|
||||||
|
public:
|
||||||
|
typedef liph::any_forward_iterator<
|
||||||
|
mc::psx::BasicBlock<false>,
|
||||||
|
mc::psx::BasicBlock<false>
|
||||||
|
> iterator;
|
||||||
|
|
||||||
|
SavegameModel();
|
||||||
|
virtual ~SavegameModel() noexcept;
|
||||||
|
|
||||||
|
std::size_t size() const { return this->block_count(); }
|
||||||
|
|
||||||
|
virtual iterator begin() = 0;
|
||||||
|
virtual iterator end() = 0;
|
||||||
|
virtual std::size_t block_count() const = 0;
|
||||||
|
virtual bool has_toc() const = 0;
|
||||||
|
virtual mc::psx::Block toc() = 0;
|
||||||
|
virtual mc::psx::ConstBlock toc() const = 0;
|
||||||
|
virtual mc::psx::Block block (std::size_t index) = 0;
|
||||||
|
virtual mc::psx::ConstBlock block (std::size_t index) const = 0;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemoryCardSavegameModel : public SavegameModel {
|
||||||
|
public:
|
||||||
|
explicit MemoryCardSavegameModel (mc::psx::MemoryCard* memcard);
|
||||||
|
virtual ~MemoryCardSavegameModel() noexcept = default;
|
||||||
|
|
||||||
|
SavegameModel::iterator begin() override;
|
||||||
|
SavegameModel::iterator end() override;
|
||||||
|
std::size_t block_count() const override;
|
||||||
|
bool has_toc() const override;
|
||||||
|
mc::psx::Block toc() override;
|
||||||
|
mc::psx::ConstBlock toc() const override;
|
||||||
|
mc::psx::Block block (std::size_t index) override;
|
||||||
|
mc::psx::ConstBlock block (std::size_t index) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mc::psx::MemoryCard* m_mc;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DbSavegameModel : public SavegameModel {
|
||||||
|
public:
|
||||||
|
explicit DbSavegameModel (SavegameDb* db);
|
||||||
|
virtual ~DbSavegameModel() noexcept = default;
|
||||||
|
|
||||||
|
SavegameModel::iterator begin() override;
|
||||||
|
SavegameModel::iterator end() override;
|
||||||
|
std::size_t block_count() const override;
|
||||||
|
bool has_toc() const override;
|
||||||
|
mc::psx::Block toc() override;
|
||||||
|
mc::psx::ConstBlock toc() const override;
|
||||||
|
mc::psx::Block block (std::size_t index) override;
|
||||||
|
mc::psx::ConstBlock block (std::size_t index) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SavegameDb* m_db;
|
||||||
|
};
|
||||||
|
} //namespace duck
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "block_grid.hpp"
|
#include "block_grid.hpp"
|
||||||
#include "vec.hpp"
|
#include "vec.hpp"
|
||||||
|
#include "savegame_model.hpp"
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
@ -97,8 +98,8 @@ QSize BlockGrid::icon_size() const {
|
||||||
return m_icon_size.isValid() ? m_icon_size : QSize(g_icon_spacing, g_icon_spacing);
|
return m_icon_size.isValid() ? m_icon_size : QSize(g_icon_spacing, g_icon_spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockGrid::push_back (AnimatedPixmap&& anim) {
|
void BlockGrid::set_savegames (std::unique_ptr<duck::SavegameModel>&& savegames) {
|
||||||
m_icons.push_back(std::move(anim));
|
m_savegames = std::move(savegames);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t BlockGrid::size() const {
|
std::size_t BlockGrid::size() const {
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
|
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
|
||||||
|
namespace duck {
|
||||||
|
class SavegameModel;
|
||||||
|
} //namespace duck
|
||||||
|
|
||||||
namespace duck::widget {
|
namespace duck::widget {
|
||||||
class BlockGrid : public QWidget {
|
class BlockGrid : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -41,7 +45,7 @@ public:
|
||||||
void set_icon_size (int sz);
|
void set_icon_size (int sz);
|
||||||
QSize icon_size() const;
|
QSize icon_size() const;
|
||||||
|
|
||||||
void push_back (AnimatedPixmap&& anim);
|
void set_savegames (std::unique_ptr<duck::SavegameModel>&& savegames);
|
||||||
std::size_t size() const;
|
std::size_t size() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -65,6 +69,7 @@ private:
|
||||||
QSize m_icon_size;
|
QSize m_icon_size;
|
||||||
QTimer* m_anim_timer;
|
QTimer* m_anim_timer;
|
||||||
std::unique_ptr<QPixmap> m_empty_icon;
|
std::unique_ptr<QPixmap> m_empty_icon;
|
||||||
|
std::unique_ptr<duck::SavegameModel> m_savegames;
|
||||||
unsigned int m_rows;
|
unsigned int m_rows;
|
||||||
unsigned int m_columns;
|
unsigned int m_columns;
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,10 +117,29 @@ void BlockDragAndDrop::mouse_move_event (const QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockDragAndDrop::drag_enter_event(QDragEnterEvent* event) {
|
void BlockDragAndDrop::drag_enter_event(QDragEnterEvent* event) {
|
||||||
if (not m_dragging and event->mimeData()->hasFormat(g_drag_mime))
|
const QMimeData* const mime = event->mimeData();
|
||||||
|
if (not m_dragging and mime->hasFormat(g_drag_mime))
|
||||||
event->acceptProposedAction();
|
event->acceptProposedAction();
|
||||||
|
else if (mime->hasUrls())
|
||||||
|
event->acceptProposedAction();
|
||||||
|
else {
|
||||||
|
std::cout << "drag_enter rejected:";
|
||||||
|
for (const auto& str : mime->formats()) {
|
||||||
|
std::cout << ' ' << str.toStdString();
|
||||||
|
}
|
||||||
|
std::cout << '\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockDragAndDrop::drop_event(QDropEvent* event) {
|
void BlockDragAndDrop::drop_event(QDropEvent* event) {
|
||||||
|
if (event->mimeData()->hasUrls()) {
|
||||||
|
for (const auto& url : event->mimeData()->urls()) {
|
||||||
|
if (url.isLocalFile())
|
||||||
|
std::cout << "would accept " << url.toLocalFile().toStdString();
|
||||||
|
else
|
||||||
|
std::cout << "rejecting " << url.toString().toStdString();
|
||||||
|
std::cout << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} //namespace duck::widget::detail
|
} //namespace duck::widget::detail
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
project('memcard', 'cpp', 'c', default_options:['debug=true', 'cpp_std=c++17', 'b_ndebug=if-release'])
|
project('memcard', 'cpp', 'c', default_options:['debug=true', 'cpp_std=c++20', 'b_ndebug=if-release'])
|
||||||
add_project_link_arguments(['-lstdc++fs'], language: 'cpp')
|
add_project_link_arguments(['-lstdc++fs'], language: 'cpp')
|
||||||
|
|
||||||
private_incl = include_directories('src')
|
private_incl = include_directories('src')
|
||||||
|
|
Loading…
Add table
Reference in a new issue