[nostalgia] Add PaletteEditor
This commit is contained in:
@@ -2,16 +2,14 @@
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QItemDelegate>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QTableWidget>
|
||||
#include <QToolBar>
|
||||
#include <algorithm>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <ox/std/memory.hpp>
|
||||
|
||||
#include "util.hpp"
|
||||
#include "paletteeditor.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
@@ -24,359 +22,294 @@ enum class PaletteEditorCommandId {
|
||||
};
|
||||
|
||||
|
||||
class ColorChannelValidator: public QValidator {
|
||||
|
||||
public:
|
||||
explicit ColorChannelValidator(QLineEdit *parent);
|
||||
|
||||
QValidator::State validate(QString &input, int&) const override;
|
||||
|
||||
class AddColorCommand: public studio::UndoCommand {
|
||||
private:
|
||||
[[nodiscard]] static QString convert(const QString &input);
|
||||
|
||||
};
|
||||
|
||||
ColorChannelValidator::ColorChannelValidator(QLineEdit *parent): QValidator(parent) {
|
||||
connect(parent, &QLineEdit::editingFinished, [parent] {
|
||||
parent->setText(convert(parent->text()));
|
||||
});
|
||||
}
|
||||
|
||||
QString ColorChannelValidator::convert(const QString &input) {
|
||||
int num = 0;
|
||||
if (input[0] == '_') {
|
||||
num = input.mid(1).toInt() >> 3;
|
||||
}
|
||||
return QString::number(num);
|
||||
}
|
||||
|
||||
QValidator::State ColorChannelValidator::validate(QString &input, int&) const {
|
||||
if (input.size() == 0) {
|
||||
return QValidator::State::Intermediate;
|
||||
}
|
||||
const auto convert = input[0] == '_';
|
||||
const auto max = convert ? 255 : 31;
|
||||
const auto numTxt = convert ? input.mid(1) : input;
|
||||
bool isNumber = false;
|
||||
const auto num = numTxt.toInt(&isNumber);
|
||||
if (isNumber && num >= 0 && num <= max) {
|
||||
return QValidator::State::Acceptable;
|
||||
} else if (numTxt == "") {
|
||||
return QValidator::State::Intermediate;
|
||||
} else {
|
||||
return QValidator::State::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AddColorCommand: public QUndoCommand {
|
||||
private:
|
||||
PaletteEditor *m_editor = nullptr;
|
||||
PaletteEditorImGui *m_editor = nullptr;
|
||||
Color16 m_color = 0;
|
||||
int m_idx = -1;
|
||||
|
||||
public:
|
||||
AddColorCommand(PaletteEditor *editor, Color16 color, int idx) {
|
||||
AddColorCommand(PaletteEditorImGui *editor, Color16 color, int idx) noexcept {
|
||||
m_editor = editor;
|
||||
m_color = color;
|
||||
m_idx = idx;
|
||||
}
|
||||
|
||||
~AddColorCommand() override = default;
|
||||
~AddColorCommand() noexcept override = default;
|
||||
|
||||
[[nodiscard]] int id() const override {
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override {
|
||||
return static_cast<int>(PaletteEditorCommandId::AddColor);
|
||||
}
|
||||
|
||||
void redo() override {
|
||||
void redo() noexcept override {
|
||||
m_editor->addColor(m_idx, m_color);
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
void undo() noexcept override {
|
||||
m_editor->rmColor(m_idx);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class RemoveColorCommand: public QUndoCommand {
|
||||
class RemoveColorCommand: public studio::UndoCommand {
|
||||
private:
|
||||
PaletteEditor *m_editor = nullptr;
|
||||
PaletteEditorImGui *m_editor = nullptr;
|
||||
Color16 m_color = 0;
|
||||
int m_idx = -1;
|
||||
|
||||
public:
|
||||
RemoveColorCommand(PaletteEditor *editor, Color16 color, int idx) {
|
||||
RemoveColorCommand(PaletteEditorImGui *editor, Color16 color, int idx) noexcept {
|
||||
m_editor = editor;
|
||||
m_color = color;
|
||||
m_idx = idx;
|
||||
}
|
||||
|
||||
~RemoveColorCommand() override = default;
|
||||
~RemoveColorCommand() noexcept override = default;
|
||||
|
||||
[[nodiscard]] int id() const override {
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override {
|
||||
return static_cast<int>(PaletteEditorCommandId::RemoveColor);
|
||||
}
|
||||
|
||||
void redo() override {
|
||||
void redo() noexcept override {
|
||||
m_editor->rmColor(m_idx);
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
void undo() noexcept override {
|
||||
m_editor->addColor(m_idx, m_color);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class UpdateColorCommand: public QUndoCommand {
|
||||
class UpdateColorCommand: public studio::UndoCommand {
|
||||
private:
|
||||
PaletteEditor *m_editor = nullptr;
|
||||
PaletteEditorImGui *m_editor = nullptr;
|
||||
Color16 m_oldColor = 0;
|
||||
Color16 m_newColor = 0;
|
||||
int m_idx = -1;
|
||||
|
||||
public:
|
||||
UpdateColorCommand(PaletteEditor *editor, int idx, Color16 oldColor, Color16 newColor) {
|
||||
UpdateColorCommand(PaletteEditorImGui *editor, int idx, Color16 oldColor, Color16 newColor) noexcept {
|
||||
m_editor = editor;
|
||||
m_idx = idx;
|
||||
m_oldColor = oldColor;
|
||||
m_newColor = newColor;
|
||||
setObsolete(m_oldColor == m_newColor);
|
||||
//setObsolete(m_oldColor == m_newColor);
|
||||
}
|
||||
|
||||
~UpdateColorCommand() override = default;
|
||||
~UpdateColorCommand() noexcept override = default;
|
||||
|
||||
[[nodiscard]] int id() const override {
|
||||
bool mergeWith(const UndoCommand *cmd) noexcept final {
|
||||
if (cmd->commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColor)) {
|
||||
return false;
|
||||
}
|
||||
auto ucCmd = static_cast<const UpdateColorCommand*>(cmd);
|
||||
if (m_idx != ucCmd->m_idx) {
|
||||
return false;
|
||||
}
|
||||
m_newColor = ucCmd->m_newColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
int commandId() const noexcept final {
|
||||
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
|
||||
}
|
||||
|
||||
void redo() override {
|
||||
void redo() noexcept final {
|
||||
m_editor->updateColor(m_idx, m_newColor);
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
void undo() noexcept final {
|
||||
m_editor->updateColor(m_idx, m_oldColor);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class MoveColorCommand: public QUndoCommand {
|
||||
class MoveColorCommand: public studio::UndoCommand {
|
||||
private:
|
||||
PaletteEditor *m_editor = nullptr;
|
||||
int m_idx = -1;
|
||||
PaletteEditorImGui *m_editor = nullptr;
|
||||
std::size_t m_idx = 0;
|
||||
int m_offset = 0;
|
||||
|
||||
public:
|
||||
MoveColorCommand(PaletteEditor *editor, int idx, int offset) {
|
||||
MoveColorCommand(PaletteEditorImGui *editor, std::size_t idx, int offset) noexcept {
|
||||
m_editor = editor;
|
||||
m_idx = idx;
|
||||
m_offset = offset;
|
||||
}
|
||||
|
||||
~MoveColorCommand() override = default;
|
||||
~MoveColorCommand() noexcept override = default;
|
||||
|
||||
[[nodiscard]] int id() const override {
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override {
|
||||
return static_cast<int>(PaletteEditorCommandId::MoveColor);
|
||||
}
|
||||
|
||||
void redo() override {
|
||||
void redo() noexcept override {
|
||||
m_editor->moveColor(m_idx, m_offset);
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_editor->moveColor(m_idx + m_offset, -m_offset);
|
||||
void undo() noexcept override {
|
||||
m_editor->moveColor(static_cast<int>(m_idx) + m_offset, -m_offset);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
QWidget *PaletteEditorColorTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex &idx) const {
|
||||
auto le = new QLineEdit(parent);
|
||||
if (idx.column()) {
|
||||
auto validator = new ColorChannelValidator(le);
|
||||
le->setValidator(validator);
|
||||
ox::Result<PaletteEditorImGui*> PaletteEditorImGui::make(Context *ctx, const ox::String &path) noexcept {
|
||||
auto out = ox::UniquePtr<PaletteEditorImGui>(new PaletteEditorImGui);
|
||||
out->m_ctx = ctx;
|
||||
out->m_itemPath = path;
|
||||
const auto lastSlash = std::find(out->m_itemPath.rbegin(), out->m_itemPath.rend(), '/').offset();
|
||||
out->m_itemName = out->m_itemPath.substr(lastSlash + 1);
|
||||
oxRequire(pal, core::readObj<Palette>(out->m_ctx, out->m_itemPath));
|
||||
out->m_pal = *pal.get();
|
||||
out->undoStack()->changeTriggered.connect(out.get(), &PaletteEditorImGui::markUnsavedChanges);
|
||||
return out.release();
|
||||
}
|
||||
|
||||
const ox::String &PaletteEditorImGui::itemName() const {
|
||||
return m_itemName;
|
||||
}
|
||||
|
||||
studio::UndoStack *PaletteEditorImGui::undoStack() noexcept {
|
||||
return &m_undoStack;
|
||||
}
|
||||
|
||||
void PaletteEditorImGui::draw(core::Context*) noexcept {
|
||||
static constexpr auto flags = ImGuiTableFlags_RowBg;
|
||||
const auto paneSize = ImGui::GetContentRegionAvail();
|
||||
ImGui::BeginChild("PaletteEditor");
|
||||
{
|
||||
ImGui::BeginChild("Colors", ImVec2(paneSize.x - 200, paneSize.y), false);
|
||||
{
|
||||
const auto colorsSz = ImGui::GetContentRegionAvail();
|
||||
static constexpr auto toolbarHeight = 40;
|
||||
ImGui::BeginChild("Toolbar", ImVec2(colorsSz.x, toolbarHeight), true);
|
||||
{
|
||||
const auto sz = ImVec2(70, 24);
|
||||
if (ImGui::Button("Add", sz)) {
|
||||
m_undoStack.push(new AddColorCommand(this, 0, m_pal.colors.size()));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size());
|
||||
{
|
||||
if (ImGui::Button("Remove", sz)) {
|
||||
m_undoStack.push(new RemoveColorCommand(this, m_pal.colors[static_cast<std::size_t>(m_selectedRow)], m_selectedRow));
|
||||
m_selectedRow = ox::min(m_pal.colors.size() - 1, m_selectedRow);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(m_selectedRow <= 0);
|
||||
{
|
||||
if (ImGui::Button("Move Up", sz)) {
|
||||
m_undoStack.push(new MoveColorCommand(this, m_selectedRow, -1));
|
||||
--m_selectedRow;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size() - 1);
|
||||
{
|
||||
if (ImGui::Button("Move Down", sz)) {
|
||||
m_undoStack.push(new MoveColorCommand(this, m_selectedRow, 1));
|
||||
++m_selectedRow;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::BeginTable("Colors", 5, flags, ImVec2(colorsSz.x, colorsSz.y - (toolbarHeight + 5)));
|
||||
{
|
||||
ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25);
|
||||
ImGui::TableSetupColumn("Red", ImGuiTableColumnFlags_WidthFixed, 50);
|
||||
ImGui::TableSetupColumn("Green", ImGuiTableColumnFlags_WidthFixed, 50);
|
||||
ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 50);
|
||||
ImGui::TableSetupColumn("Color Preview", ImGuiTableColumnFlags_NoHide);
|
||||
ImGui::TableHeadersRow();
|
||||
for (auto i = 0u; const auto c : m_pal.colors) {
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
ImGui::TableNextRow();
|
||||
// Color No.
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", i);
|
||||
// Red
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", red16(c));
|
||||
// Green
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", green16(c));
|
||||
// Blue
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", blue16(c));
|
||||
// ColorPreview
|
||||
ImGui::TableNextColumn();
|
||||
const auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1));
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
|
||||
if (ImGui::Selectable("##ColorRow", i == m_selectedRow, ImGuiSelectableFlags_SpanAllColumns)) {
|
||||
m_selectedRow = i;
|
||||
}
|
||||
ImGui::PopID();
|
||||
++i;
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
if (m_selectedRow < m_pal.colors.size()) {
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginChild("ColorEditor", ImVec2(200, paneSize.y), true);
|
||||
{
|
||||
const auto c = m_pal.colors[m_selectedRow];
|
||||
int r = red16(c);
|
||||
int g = green16(c);
|
||||
int b = blue16(c);
|
||||
int a = alpha16(c);
|
||||
ImGui::InputInt("Red", &r, 1, 5);
|
||||
ImGui::InputInt("Green", &g, 1, 5);
|
||||
ImGui::InputInt("Blue", &b, 1, 5);
|
||||
const auto newColor = color16(r, g, b, a);
|
||||
if (c != newColor) {
|
||||
m_undoStack.push(new UpdateColorCommand(this, m_selectedRow, c, newColor));
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
return le;
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void PaletteEditorColorTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &idx) const {
|
||||
if (idx.column() != 3) {
|
||||
QStyledItemDelegate::paint(painter, opt, idx);
|
||||
} else {
|
||||
auto color = idx.model()->data(idx, Qt::DisplayRole).toString();
|
||||
painter->fillRect(opt.rect, QColor(color));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static QTableWidgetItem *mkCell(const QString& v, bool editable = true) {
|
||||
auto c = new QTableWidgetItem;
|
||||
c->setText(v);
|
||||
c->setFont(QFont("monospace"));
|
||||
c->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
if (!editable) {
|
||||
c->setFlags(c->flags() & ~Qt::ItemIsEditable);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static QTableWidgetItem *mkCell(uint8_t v) {
|
||||
return mkCell(QString("%1").arg(v), true);
|
||||
}
|
||||
|
||||
|
||||
PaletteEditor::PaletteEditor(QString path, const studio::Context *ctx, QWidget *parent): studio::Editor(parent) {
|
||||
m_ctx = ctx;
|
||||
m_itemPath = path;
|
||||
|
||||
auto canvasLyt = new QVBoxLayout(this);
|
||||
auto tb = new QToolBar(tr("Tile Sheet Options"));
|
||||
m_addBtn = new QPushButton(tr("Add"), tb);
|
||||
m_rmBtn = new QPushButton(tr("Remove"), tb);
|
||||
m_moveUpBtn = new QPushButton(tr("Move Up"), tb);
|
||||
m_moveDownBtn = new QPushButton(tr("Move Down"), tb);
|
||||
m_rmBtn->setEnabled(false);
|
||||
m_moveUpBtn->setEnabled(false);
|
||||
m_moveDownBtn->setEnabled(false);
|
||||
tb->addWidget(m_addBtn);
|
||||
tb->addWidget(m_rmBtn);
|
||||
tb->addWidget(m_moveUpBtn);
|
||||
tb->addWidget(m_moveDownBtn);
|
||||
canvasLyt->setMenuBar(tb);
|
||||
|
||||
m_table = new QTableWidget(this);
|
||||
m_table->setItemDelegate(&m_colorTableDelegate);
|
||||
m_table->setColumnCount(4);
|
||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_table->setHorizontalHeaderLabels(QStringList() << tr("Red") << tr("Green") << tr("Blue") << tr("Color Preview"));
|
||||
m_table->horizontalHeader()->setStretchLastSection(true);
|
||||
m_table->verticalHeader()->hide();
|
||||
canvasLyt->addWidget(m_table);
|
||||
connect(m_table, &QTableWidget::itemSelectionChanged, this, &PaletteEditor::colorSelected);
|
||||
connect(m_addBtn, &QPushButton::clicked, this, &PaletteEditor::addColorClicked);
|
||||
connect(m_rmBtn, &QPushButton::clicked, this, &PaletteEditor::rmColorClicked);
|
||||
connect(m_moveUpBtn, &QPushButton::clicked, this, &PaletteEditor::moveColorUpClicked);
|
||||
connect(m_moveDownBtn, &QPushButton::clicked, this, &PaletteEditor::moveColorDownClicked);
|
||||
connect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
m_pal = m_ctx->project->loadObj<NostalgiaPalette>(m_itemPath);
|
||||
load();
|
||||
}
|
||||
|
||||
QString PaletteEditor::itemName() const {
|
||||
return m_itemPath.mid(m_itemPath.lastIndexOf('/'));
|
||||
}
|
||||
|
||||
void PaletteEditor::addTableRow(int i, Color16 c) {
|
||||
disconnect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
m_table->insertRow(i);
|
||||
m_table->setItem(i, 0, mkCell(red16(c)));
|
||||
m_table->setItem(i, 1, mkCell(green16(c)));
|
||||
m_table->setItem(i, 2, mkCell(blue16(c)));
|
||||
m_table->setItem(i, 3, mkCell(toQColor(m_pal->colors[static_cast<std::size_t>(i)]).name(QColor::HexRgb), false));
|
||||
connect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
}
|
||||
|
||||
void PaletteEditor::rmTableRow(int idx) {
|
||||
disconnect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
m_table->removeRow(idx);
|
||||
connect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
}
|
||||
|
||||
void PaletteEditor::setTableRow(int idx, Color16 c) {
|
||||
disconnect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
m_table->item(idx, 0)->setText(QString::number(red16(c)));
|
||||
m_table->item(idx, 1)->setText(QString::number(green16(c)));
|
||||
m_table->item(idx, 2)->setText(QString::number(blue16(c)));
|
||||
m_table->item(idx, 3)->setText(toQColor(m_pal->colors[static_cast<std::size_t>(idx)]).name(QColor::HexRgb));
|
||||
connect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
}
|
||||
|
||||
void PaletteEditor::addColor(int idx, Color16 c) {
|
||||
m_pal->colors.insert(static_cast<std::size_t>(idx), c);
|
||||
addTableRow(idx, c);
|
||||
void PaletteEditorImGui::addColor(int idx, Color16 c) noexcept {
|
||||
m_pal.colors.insert(static_cast<std::size_t>(idx), c);
|
||||
setUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void PaletteEditor::rmColor(int idx) {
|
||||
rmTableRow(idx);
|
||||
oxIgnoreError(m_pal->colors.erase(static_cast<std::size_t>(idx)));
|
||||
void PaletteEditorImGui::rmColor(int idx) noexcept {
|
||||
oxIgnoreError(m_pal.colors.erase(static_cast<std::size_t>(idx)));
|
||||
setUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void PaletteEditor::updateColor(int idx, Color16 c) {
|
||||
m_pal->colors[static_cast<std::size_t>(idx)] = c;
|
||||
setTableRow(idx, c);
|
||||
void PaletteEditorImGui::updateColor(int idx, Color16 c) noexcept {
|
||||
m_pal.colors[static_cast<std::size_t>(idx)] = c;
|
||||
setUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void PaletteEditor::moveColor(int idx, int offset) {
|
||||
auto c = m_pal->colors[static_cast<std::size_t>(idx)];
|
||||
oxIgnoreError(m_pal->colors.erase(static_cast<std::size_t>(idx)));
|
||||
m_pal->colors.insert(static_cast<std::size_t>(idx + offset), c);
|
||||
rmTableRow(idx);
|
||||
addTableRow(idx + offset, c);
|
||||
void PaletteEditorImGui::moveColor(int idx, int offset) noexcept {
|
||||
const auto c = m_pal.colors[static_cast<std::size_t>(idx)];
|
||||
oxIgnoreError(m_pal.colors.erase(static_cast<std::size_t>(idx)));
|
||||
m_pal.colors.insert(static_cast<std::size_t>(idx + offset), c);
|
||||
setUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void PaletteEditor::saveItem() {
|
||||
m_ctx->project->writeObj(m_itemPath, m_pal.get());
|
||||
void PaletteEditorImGui::saveItem() {
|
||||
//m_ctx->project->writeObj(m_itemPath, &m_pal);
|
||||
}
|
||||
|
||||
void PaletteEditor::load() {
|
||||
disconnect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
for (std::size_t i = 0; i < m_pal->colors.size(); ++i) {
|
||||
auto c = m_pal->colors[i];
|
||||
addTableRow(i, c);
|
||||
}
|
||||
connect(m_table, &QTableWidget::cellChanged, this, &PaletteEditor::cellChanged);
|
||||
}
|
||||
|
||||
Color16 PaletteEditor::rowColor(int row) const {
|
||||
auto r = static_cast<uint8_t>(m_table->item(row, 0)->text().toInt());
|
||||
auto g = static_cast<uint8_t>(m_table->item(row, 1)->text().toInt());
|
||||
auto b = static_cast<uint8_t>(m_table->item(row, 2)->text().toInt());
|
||||
return color16(r, g, b);
|
||||
}
|
||||
|
||||
void PaletteEditor::colorSelected() {
|
||||
auto selIdxs = m_table->selectionModel()->selectedIndexes();
|
||||
auto row = !selIdxs.empty() ? selIdxs[0].row() : -1;
|
||||
if (row > -1) {
|
||||
m_rmBtn->setEnabled(true);
|
||||
m_moveUpBtn->setEnabled(row > 0);
|
||||
m_moveDownBtn->setEnabled(row < m_table->rowCount() - 1);
|
||||
} else {
|
||||
m_rmBtn->setEnabled(false);
|
||||
m_moveUpBtn->setEnabled(false);
|
||||
m_moveDownBtn->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void PaletteEditor::cellChanged(int row, int) {
|
||||
auto oldColor = m_pal->colors[static_cast<std::size_t>(row)];
|
||||
auto newColor = rowColor(row);
|
||||
undoStack()->push(new UpdateColorCommand(this, row, oldColor, newColor));
|
||||
}
|
||||
|
||||
void PaletteEditor::addColorClicked() {
|
||||
auto row = m_table->rowCount();
|
||||
undoStack()->push(new AddColorCommand(this, 0, row));
|
||||
}
|
||||
|
||||
void PaletteEditor::rmColorClicked() {
|
||||
auto row = m_table->currentRow();
|
||||
undoStack()->push(new RemoveColorCommand(this, m_pal->colors[static_cast<std::size_t>(row)], row));
|
||||
}
|
||||
|
||||
void PaletteEditor::moveColorUpClicked() {
|
||||
auto row = m_table->currentRow();
|
||||
undoStack()->push(new MoveColorCommand(this, row, -1));
|
||||
}
|
||||
|
||||
void PaletteEditor::moveColorDownClicked() {
|
||||
auto row = m_table->currentRow();
|
||||
undoStack()->push(new MoveColorCommand(this, row, 1));
|
||||
ox::Error PaletteEditorImGui::markUnsavedChanges(int) noexcept {
|
||||
setUnsavedChanges(true);
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user