mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-23 22:43:32 +00:00
Add progress dialog/bar when we change color mode
Added a new app::RenderTaskJob to execute a lambda function as in a background thread in a app::Job that can be used as a render::TaskDelegate by some render functions.
This commit is contained in:
parent
573cad4777
commit
131336d015
@ -24,34 +24,74 @@
|
||||
#include "doc/palette.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "render/quantization.h"
|
||||
#include "render/task_delegate.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
using namespace doc;
|
||||
|
||||
namespace {
|
||||
|
||||
class SuperDelegate : public render::TaskDelegate {
|
||||
public:
|
||||
SuperDelegate(int ncels, render::TaskDelegate* delegate)
|
||||
: m_ncels(ncels)
|
||||
, m_curCel(0)
|
||||
, m_delegate(delegate) {
|
||||
}
|
||||
|
||||
void notifyTaskProgress(double progress) override {
|
||||
if (m_delegate)
|
||||
m_delegate->notifyTaskProgress(
|
||||
(progress + m_curCel) / m_ncels);
|
||||
}
|
||||
|
||||
bool continueTask() override {
|
||||
if (m_delegate)
|
||||
return m_delegate->continueTask();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void nextCel() {
|
||||
++m_curCel;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_ncels;
|
||||
int m_curCel;
|
||||
TaskDelegate* m_delegate;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
SetPixelFormat::SetPixelFormat(Sprite* sprite,
|
||||
const PixelFormat newFormat,
|
||||
const render::DitheringAlgorithm dithering)
|
||||
const render::DitheringAlgorithm dithering,
|
||||
render::TaskDelegate* delegate)
|
||||
: WithSprite(sprite)
|
||||
, m_oldFormat(sprite->pixelFormat())
|
||||
, m_newFormat(newFormat)
|
||||
, m_dithering(dithering)
|
||||
{
|
||||
if (sprite->pixelFormat() == newFormat)
|
||||
return;
|
||||
|
||||
SuperDelegate superDel(sprite->uniqueCels().size(), delegate);
|
||||
|
||||
for (Cel* cel : sprite->uniqueCels()) {
|
||||
ImageRef old_image = cel->imageRef();
|
||||
ImageRef new_image(
|
||||
render::convert_pixel_format
|
||||
(old_image.get(), NULL, newFormat, m_dithering,
|
||||
(old_image.get(), NULL, newFormat, dithering,
|
||||
sprite->rgbMap(cel->frame()),
|
||||
sprite->palette(cel->frame()),
|
||||
cel->layer()->isBackground(),
|
||||
old_image->maskColor()));
|
||||
old_image->maskColor(),
|
||||
&superDel));
|
||||
|
||||
m_seq.add(new cmd::ReplaceImage(sprite, old_image, new_image));
|
||||
superDel.nextCel();
|
||||
}
|
||||
|
||||
// Set all cels opacity to 100% if we are converting to indexed.
|
||||
|
@ -17,6 +17,10 @@ namespace doc {
|
||||
class Sprite;
|
||||
}
|
||||
|
||||
namespace render {
|
||||
class TaskDelegate;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
@ -25,7 +29,8 @@ namespace cmd {
|
||||
public:
|
||||
SetPixelFormat(doc::Sprite* sprite,
|
||||
const doc::PixelFormat newFormat,
|
||||
const render::DitheringAlgorithm dithering);
|
||||
const render::DitheringAlgorithm dithering,
|
||||
render::TaskDelegate* delegate);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
@ -40,7 +45,6 @@ namespace cmd {
|
||||
|
||||
doc::PixelFormat m_oldFormat;
|
||||
doc::PixelFormat m_newFormat;
|
||||
render::DitheringAlgorithm m_dithering;
|
||||
CmdSequence m_seq;
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/render_task_job.h"
|
||||
#include "app/transaction.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
@ -397,14 +398,20 @@ void ChangePixelFormatCommand::onExecute(Context* context)
|
||||
if (context->activeDocument()->sprite()->pixelFormat() == m_format)
|
||||
return;
|
||||
|
||||
{
|
||||
ContextWriter writer(context);
|
||||
Transaction transaction(writer.context(), "Color Mode Change");
|
||||
Sprite* sprite(writer.sprite());
|
||||
|
||||
transaction.execute(new cmd::SetPixelFormat(sprite, m_format, m_dithering));
|
||||
transaction.commit();
|
||||
}
|
||||
RenderTaskJob job(
|
||||
"Converting Color Mode",
|
||||
[this, &job, context]{
|
||||
ContextWriter writer(context);
|
||||
Transaction transaction(writer.context(), "Color Mode Change");
|
||||
Sprite* sprite(writer.sprite());
|
||||
transaction.execute(
|
||||
new cmd::SetPixelFormat(
|
||||
sprite, m_format, m_dithering, &job));
|
||||
if (!job.isCanceled())
|
||||
transaction.commit();
|
||||
});
|
||||
job.startJob();
|
||||
job.waitJob();
|
||||
|
||||
if (context->isUIAvailable())
|
||||
app_refresh_screen();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "app/job.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/render_task_job.h"
|
||||
#include "app/transaction.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
@ -25,7 +26,6 @@
|
||||
#include "doc/palette.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "render/quantization.h"
|
||||
#include "render/task_delegate.h"
|
||||
#include "ui/manager.h"
|
||||
|
||||
#include "palette_from_sprite.xml.h"
|
||||
@ -42,37 +42,6 @@ protected:
|
||||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
class ColorQuantizationJob : public Job,
|
||||
public render::TaskDelegate {
|
||||
public:
|
||||
ColorQuantizationJob(Sprite* sprite, bool withAlpha, Palette* palette)
|
||||
: Job("Creating Palette")
|
||||
, m_sprite(sprite)
|
||||
, m_withAlpha(withAlpha)
|
||||
, m_palette(palette) {
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void onJob() override {
|
||||
render::create_palette_from_sprite(
|
||||
m_sprite, 0, m_sprite->lastFrame(),
|
||||
m_withAlpha, m_palette, this);
|
||||
}
|
||||
|
||||
bool continueTask() override {
|
||||
return !isCanceled();
|
||||
}
|
||||
|
||||
void notifyTaskProgress(double progress) override {
|
||||
jobProgress(progress);
|
||||
}
|
||||
|
||||
Sprite* m_sprite;
|
||||
bool m_withAlpha;
|
||||
Palette* m_palette;
|
||||
};
|
||||
|
||||
ColorQuantizationCommand::ColorQuantizationCommand()
|
||||
: Command("ColorQuantization",
|
||||
"Create Palette from Current Sprite (Color Quantization)",
|
||||
@ -144,7 +113,14 @@ void ColorQuantizationCommand::onExecute(Context* context)
|
||||
return;
|
||||
|
||||
Palette tmpPalette(frame, entries.picks());
|
||||
ColorQuantizationJob job(sprite, withAlpha, &tmpPalette);
|
||||
|
||||
RenderTaskJob job(
|
||||
"Creating Palette",
|
||||
[sprite, withAlpha, &tmpPalette, &job]{
|
||||
render::create_palette_from_sprite(
|
||||
sprite, 0, sprite->lastFrame(),
|
||||
withAlpha, &tmpPalette, &job);
|
||||
});
|
||||
job.startJob();
|
||||
job.waitJob();
|
||||
if (job.isCanceled())
|
||||
|
@ -707,7 +707,8 @@ void DocumentExporter::renderTexture(const Samples& samples, Image* textureImage
|
||||
cmd::SetPixelFormat(
|
||||
sample.sprite(),
|
||||
textureImage->pixelFormat(),
|
||||
render::DitheringAlgorithm::None)
|
||||
render::DitheringAlgorithm::None,
|
||||
nullptr) // TODO add a delegate to show progress
|
||||
.execute(UIContext::instance());
|
||||
}
|
||||
|
||||
|
46
src/app/render_task_job.h
Normal file
46
src/app/render_task_job.h
Normal file
@ -0,0 +1,46 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_RENDER_TASK_JOB_H_INCLUDED
|
||||
#define APP_RENDER_TASK_JOB_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/job.h"
|
||||
#include "render/task_delegate.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace app {
|
||||
|
||||
class RenderTaskJob : public Job,
|
||||
public render::TaskDelegate {
|
||||
public:
|
||||
template<typename T>
|
||||
RenderTaskJob(const char* jobName, T&& func)
|
||||
: Job(jobName)
|
||||
, m_func(std::move(func)) {
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void onJob() override {
|
||||
m_func();
|
||||
}
|
||||
|
||||
// render::TaskDelegate impl
|
||||
bool continueTask() override {
|
||||
return !isCanceled();
|
||||
}
|
||||
void notifyTaskProgress(double progress) override {
|
||||
jobProgress(progress);
|
||||
}
|
||||
|
||||
std::function<void()> m_func;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
// Copyright (c) 2001-2017 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -64,6 +64,13 @@ namespace doc {
|
||||
iterator begin() { return m_begin; }
|
||||
iterator end() { return m_end; }
|
||||
|
||||
int size() {
|
||||
int count = 0;
|
||||
for (auto it=begin(), e=end(); it!=e; ++it)
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
private:
|
||||
SelectedFrames m_selFrames;
|
||||
iterator m_begin, m_end;
|
||||
|
Loading…
x
Reference in New Issue
Block a user