Fix #67: Per-image grid settings

This commit is contained in:
David Capello 2014-09-08 23:08:06 -03:00
parent 289401ce04
commit eb1fd4ff0d
11 changed files with 187 additions and 64 deletions

View File

@ -36,6 +36,7 @@
#include "app/ui/status_bar.h"
#include "app/ui_context.h"
#include "base/bind.h"
#include "doc/context_observer.h"
#include "gfx/size.h"
#include "raster/mask.h"
#include "ui/ui.h"
@ -55,13 +56,15 @@ static void on_exit_delete_this_widget()
delete window;
}
class ConfigureTools : public Command {
class ConfigureTools : public Command,
public doc::ContextObserver {
public:
ConfigureTools();
Command* clone() const override { return new ConfigureTools(*this); }
protected:
void onExecute(Context* context);
void onExecute(Context* context) override;
void onSetActiveDocument(doc::Document* document) override;
private:
CheckBox* m_tiled;
@ -93,8 +96,8 @@ ConfigureTools::ConfigureTools()
void ConfigureTools::onExecute(Context* context)
{
m_settings = UIContext::instance()->settings();
m_docSettings = m_settings->getDocumentSettings(NULL);
m_settings = context->settings();
m_docSettings = NULL;
Button* set_grid;
bool first_time = false;
@ -105,10 +108,13 @@ void ConfigureTools::onExecute(Context* context)
}
// If the window is opened, close it
else if (window->isVisible()) {
context->removeObserver(this);
window->closeWindow(NULL);
return;
}
context->addObserver(this);
try {
m_tiled = app::find_widget<CheckBox>(window, "tiled");
m_tiledX = app::find_widget<CheckBox>(window, "tiled_x");
@ -124,15 +130,7 @@ void ConfigureTools::onExecute(Context* context)
throw;
}
if (m_docSettings->getTiledMode() != filters::TILED_NONE) {
m_tiled->setSelected(true);
if (m_docSettings->getTiledMode() & filters::TILED_X_AXIS) m_tiledX->setSelected(true);
if (m_docSettings->getTiledMode() & filters::TILED_Y_AXIS) m_tiledY->setSelected(true);
}
if (m_docSettings->getSnapToGrid()) m_snapToGrid->setSelected(true);
if (m_docSettings->getGridVisible()) m_viewGrid->setSelected(true);
if (m_docSettings->getPixelGridVisible()) m_pixelGrid->setSelected(true);
onSetActiveDocument(context->activeDocument());
if (first_time) {
// Slots
@ -227,6 +225,24 @@ void ConfigureTools::onSetGridClick()
}
}
void ConfigureTools::onSetActiveDocument(doc::Document* document)
{
if (!document)
return;
m_docSettings = m_settings->getDocumentSettings(document);
ASSERT(m_docSettings);
if (!m_docSettings)
return;
m_tiled->setSelected(m_docSettings->getTiledMode() != filters::TILED_NONE);
m_tiledX->setSelected(m_docSettings->getTiledMode() & filters::TILED_X_AXIS ? true: false);
m_tiledY->setSelected(m_docSettings->getTiledMode() & filters::TILED_Y_AXIS ? true: false);
m_snapToGrid->setSelected(m_docSettings->getSnapToGrid());
m_viewGrid->setSelected(m_docSettings->getGridVisible());
m_pixelGrid->setSelected(m_docSettings->getPixelGridVisible());
}
Command* CommandFactory::createConfigureToolsCommand()
{
return new ConfigureTools;

View File

@ -23,6 +23,7 @@
#include "app/app.h"
#include "app/commands/command.h"
#include "app/context.h"
#include "app/document.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "app/modules/editors.h"

View File

@ -23,6 +23,7 @@
#include "app/app.h"
#include "app/commands/command.h"
#include "app/context.h"
#include "app/document.h"
#include "app/settings/document_settings.h"
#include "app/settings/settings.h"

View File

@ -52,7 +52,7 @@ class OptionsWindow : public app::gen::Options {
public:
OptionsWindow(Context* context)
: m_settings(context->settings())
, m_docSettings(m_settings->getDocumentSettings(NULL))
, m_docSettings(m_settings->getDocumentSettings(context->activeDocument()))
, m_checked_bg_color1(new ColorButton(RenderEngine::getCheckedBgColor1(), IMAGE_RGB))
, m_checked_bg_color2(new ColorButton(RenderEngine::getCheckedBgColor2(), IMAGE_RGB))
, m_pixelGridColor(new ColorButton(m_docSettings->getPixelGridColor(), IMAGE_RGB))

View File

@ -26,6 +26,7 @@
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/context.h"
#include "app/document.h"
#include "app/find_widget.h"
#include "app/ini_file.h"
#include "app/load_widget.h"

View File

@ -24,6 +24,7 @@
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/context.h"
#include "app/document.h"
#include "app/find_widget.h"
#include "app/ini_file.h"
#include "app/load_widget.h"

View File

@ -54,13 +54,12 @@ ConfigModule::ConfigModule()
}
#endif
override_config_file(fn.c_str());
set_config_file(fn.c_str());
g_configFilename = fn;
}
ConfigModule::~ConfigModule()
{
//override_config_file(NULL);
flush_config_file();
}

View File

@ -31,10 +31,13 @@
#include "gfx/rect.h"
#include "raster/brush_type.h"
namespace doc {
class Document;
}
namespace app {
class ColorSwatches;
class Document;
class IColorSwatchesStore;
class IDocumentSettings;
class IBrushSettings;
@ -82,7 +85,7 @@ namespace app {
// Returns the specific settings for the given document. If the
// document is null, it should return an interface for
// global/default settings.
virtual IDocumentSettings* getDocumentSettings(const Document* document) = 0;
virtual IDocumentSettings* getDocumentSettings(const doc::Document* document) = 0;
// Specific configuration for the given tool.
virtual IToolSettings* getToolSettings(tools::Tool* tool) = 0;

View File

@ -24,7 +24,9 @@
#include "app/app.h"
#include "app/color_swatches.h"
#include "app/document.h"
#include "app/ini_file.h"
#include "app/resource_finder.h"
#include "app/settings/document_settings.h"
#include "app/tools/controller.h"
#include "app/tools/ink.h"
@ -32,7 +34,10 @@
#include "app/tools/tool.h"
#include "app/tools/tool_box.h"
#include "app/ui/color_bar.h"
#include "app/ui_context.h"
#include "base/observable.h"
#include "doc/context.h"
#include "doc/documents_observer.h"
#include "ui/manager.h"
#include "ui/system.h"
@ -55,45 +60,88 @@ namespace {
class UIDocumentSettingsImpl : public IDocumentSettings,
public base::Observable<DocumentSettingsObserver> {
public:
UIDocumentSettingsImpl()
: m_tiledMode((TiledMode)get_config_int("Tools", "Tiled", (int)TILED_NONE))
, m_use_onionskin(get_config_bool("Onionskin", "Enabled", false))
, m_prev_frames_onionskin(get_config_int("Onionskin", "PrevFrames", 1))
, m_next_frames_onionskin(get_config_int("Onionskin", "NextFrames", 1))
, m_onionskin_opacity_base(get_config_int("Onionskin", "OpacityBase", DEFAULT_ONIONSKIN_OPACITY_BASE))
, m_onionskin_opacity_step(get_config_int("Onionskin", "OpacityStep", DEFAULT_ONIONSKIN_OPACITY_STEP))
, m_onionskinType((OnionskinType)get_config_int("Onionskin", "Type", (int)DEFAULT_ONIONSKIN_TYPE))
, m_snapToGrid(get_config_bool("Grid", "SnapTo", false))
, m_gridVisible(get_config_bool("Grid", "Visible", false))
, m_gridBounds(get_config_rect("Grid", "Bounds", Rect(0, 0, 16, 16)))
, m_gridColor(get_config_color("Grid", "Color", app::Color::fromRgb(0, 0, 255)))
, m_pixelGridVisible(get_config_bool("PixelGrid", "Visible", false))
, m_pixelGridColor(get_config_color("PixelGrid", "Color", app::Color::fromRgb(200, 200, 200)))
UIDocumentSettingsImpl(const doc::Document* doc)
: m_doc(doc)
, m_tiledMode(TILED_NONE)
, m_use_onionskin(false)
, m_prev_frames_onionskin(1)
, m_next_frames_onionskin(1)
, m_onionskin_opacity_base(DEFAULT_ONIONSKIN_OPACITY_BASE)
, m_onionskin_opacity_step(DEFAULT_ONIONSKIN_OPACITY_STEP)
, m_onionskinType(DEFAULT_ONIONSKIN_TYPE)
, m_snapToGrid(false)
, m_gridVisible(false)
, m_gridBounds(0, 0, 16, 16)
, m_gridColor(app::Color::fromRgb(0, 0, 255))
, m_pixelGridVisible(false)
, m_pixelGridColor(app::Color::fromRgb(200, 200, 200))
, m_isLoop(false)
, m_loopBegin(0)
, m_loopEnd(-1)
, m_loopEnd(1)
, m_aniDir(AniDir_Normal)
{
m_tiledMode = (TiledMode)MID(0, (int)m_tiledMode, (int)TILED_BOTH);
m_onionskinType = (OnionskinType)MID(0, (int)m_onionskinType, (int)Onionskin_Last);
bool specific_file = false;
if (m_doc && static_cast<const app::Document*>(m_doc)->isAssociatedToFile()) {
push_config_state();
set_config_file(configFileName().c_str());
specific_file = true;
m_tiledMode = (TiledMode)get_config_int("Tools", "Tiled", (int)m_tiledMode);
m_use_onionskin = get_config_bool("Onionskin", "Enabled", m_use_onionskin);
m_prev_frames_onionskin = get_config_int("Onionskin", "PrevFrames", m_prev_frames_onionskin);
m_next_frames_onionskin = get_config_int("Onionskin", "NextFrames", m_next_frames_onionskin);
m_onionskin_opacity_base = get_config_int("Onionskin", "OpacityBase", m_onionskin_opacity_base);
m_onionskin_opacity_step = get_config_int("Onionskin", "OpacityStep", m_onionskin_opacity_step);
m_onionskinType = (OnionskinType)get_config_int("Onionskin", "Type", m_onionskinType);
m_snapToGrid = get_config_bool("Grid", "SnapTo", m_snapToGrid);
m_gridVisible = get_config_bool("Grid", "Visible", m_gridVisible);
m_gridBounds = get_config_rect("Grid", "Bounds", m_gridBounds);
m_pixelGridVisible = get_config_bool("PixelGrid", "Visible", m_pixelGridVisible);
// Limit values
m_tiledMode = (TiledMode)MID(0, (int)m_tiledMode, (int)TILED_BOTH);
m_onionskinType = (OnionskinType)MID(0, (int)m_onionskinType, (int)Onionskin_Last);
}
m_gridColor = get_config_color("Grid", "Color", m_gridColor);
m_pixelGridColor = get_config_color("PixelGrid", "Color", m_pixelGridColor);
if (specific_file)
pop_config_state();
}
~UIDocumentSettingsImpl()
{
set_config_int("Tools", "Tiled", m_tiledMode);
set_config_bool("Grid", "SnapTo", m_snapToGrid);
set_config_bool("Grid", "Visible", m_gridVisible);
set_config_rect("Grid", "Bounds", m_gridBounds);
set_config_color("Grid", "Color", m_gridColor);
set_config_bool("PixelGrid", "Visible", m_pixelGridVisible);
set_config_color("PixelGrid", "Color", m_pixelGridColor);
bool specific_file = false;
if (m_doc) {
// We don't save the document configuration if it isn't associated with a file.
if (!static_cast<const app::Document*>(m_doc)->isAssociatedToFile())
return;
set_config_bool("Onionskin", "Enabled", m_use_onionskin);
set_config_int("Onionskin", "PrevFrames", m_prev_frames_onionskin);
set_config_int("Onionskin", "NextFrames", m_next_frames_onionskin);
set_config_int("Onionskin", "OpacityBase", m_onionskin_opacity_base);
set_config_int("Onionskin", "OpacityStep", m_onionskin_opacity_step);
set_config_int("Onionskin", "Type", m_onionskinType);
push_config_state();
set_config_file(configFileName().c_str());
specific_file = true;
set_config_int("Tools", "Tiled", m_tiledMode);
set_config_bool("Grid", "SnapTo", m_snapToGrid);
set_config_bool("Grid", "Visible", m_gridVisible);
set_config_rect("Grid", "Bounds", m_gridBounds);
set_config_bool("PixelGrid", "Visible", m_pixelGridVisible);
set_config_bool("Onionskin", "Enabled", m_use_onionskin);
set_config_int("Onionskin", "PrevFrames", m_prev_frames_onionskin);
set_config_int("Onionskin", "NextFrames", m_next_frames_onionskin);
set_config_int("Onionskin", "OpacityBase", m_onionskin_opacity_base);
set_config_int("Onionskin", "OpacityStep", m_onionskin_opacity_step);
set_config_int("Onionskin", "Type", m_onionskinType);
}
saveSharedSettings();
if (specific_file) {
flush_config_file();
pop_config_state();
}
}
// Tiled mode
@ -154,11 +202,36 @@ public:
virtual void removeObserver(DocumentSettingsObserver* observer) override;
private:
void saveSharedSettings() {
set_config_color("Grid", "Color", m_gridColor);
set_config_color("PixelGrid", "Color", m_pixelGridColor);
}
std::string configFileName() {
if (!m_doc)
return "";
if (m_cfgName.empty()) {
ResourceFinder rf;
std::string fn = m_doc->filename();
for (size_t i=0; i<fn.size(); ++i) {
if (fn[i] == ' ' || fn[i] == '/' || fn[i] == '\\' || fn[i] == ':' || fn[i] == '.') {
fn[i] = '-';
}
}
rf.includeUserDir(("files/" + fn + ".ini").c_str());
m_cfgName = rf.getFirstOrCreateDefault();
}
return m_cfgName;
}
void redrawDocumentViews() {
// TODO Redraw only document's views
ui::Manager::getDefault()->invalidate();
}
const doc::Document* m_doc;
std::string m_cfgName;
TiledMode m_tiledMode;
bool m_use_onionskin;
int m_prev_frames_onionskin;
@ -176,7 +249,6 @@ private:
raster::FrameNumber m_loopBegin;
raster::FrameNumber m_loopEnd;
AniDir m_aniDir;
};
class UISelectionSettingsImpl
@ -210,7 +282,6 @@ private:
UISettingsImpl::UISettingsImpl()
: m_currentTool(NULL)
, m_globalDocumentSettings(new UIDocumentSettingsImpl)
, m_colorSwatches(NULL)
, m_selectionSettings(new UISelectionSettingsImpl)
, m_zoomWithScrollWheel(get_config_bool("Options", "ZoomWithMouseWheel", true))
@ -233,17 +304,22 @@ UISettingsImpl::~UISettingsImpl()
set_config_bool("Options", "GrabAlpha", m_grabAlpha);
set_config_int("Options", "RightClickMode", static_cast<int>(m_rightClickMode));
// Delete all tool settings.
for (std::map<std::string, IToolSettings*>::iterator
it = m_toolSettings.begin(), end = m_toolSettings.end(); it != end; ++it) {
delete it->second;
}
for (auto it : m_docSettings)
delete it.second;
// Delete all color swatches
for (std::vector<app::ColorSwatches*>::iterator
it = m_colorSwatchesStore.begin(), end = m_colorSwatchesStore.end();
it != end; ++it) {
delete *it;
for (auto it : m_toolSettings)
delete it.second;
for (auto it : m_colorSwatchesStore)
delete it;
}
void UISettingsImpl::onRemoveDocument(doc::Document* doc)
{
auto it = m_docSettings.find(doc->id());
if (it != m_docSettings.end()) {
delete it->second;
m_docSettings.erase(it);
}
}
@ -369,9 +445,20 @@ void UISettingsImpl::setColorSwatches(app::ColorSwatches* colorSwatches)
notifyObservers<app::ColorSwatches*>(&GlobalSettingsObserver::onSetColorSwatches, colorSwatches);
}
IDocumentSettings* UISettingsImpl::getDocumentSettings(const Document* document)
IDocumentSettings* UISettingsImpl::getDocumentSettings(const doc::Document* document)
{
return m_globalDocumentSettings;
doc::ObjectId id;
if (!document)
id = doc::NullId;
else
id = document->id();
auto it = m_docSettings.find(id);
if (it != m_docSettings.end())
return it->second;
return m_docSettings[id] = new UIDocumentSettingsImpl(document);
}
IColorSwatchesStore* UISettingsImpl::getColorSwatchesStore()
@ -482,6 +569,8 @@ void UIDocumentSettingsImpl::setGridColor(const app::Color& color)
{
m_gridColor = color;
notifyObservers<const app::Color&>(&DocumentSettingsObserver::onSetGridColor, color);
saveSharedSettings();
}
void UIDocumentSettingsImpl::snapToGrid(gfx::Point& point) const
@ -520,6 +609,8 @@ void UIDocumentSettingsImpl::setPixelGridColor(const app::Color& color)
{
m_pixelGridColor = color;
redrawDocumentViews();
saveSharedSettings();
}
bool UIDocumentSettingsImpl::getUseOnionskin()

View File

@ -28,6 +28,8 @@
#include "app/settings/settings_observers.h"
#include "base/observable.h"
#include "base/unique_ptr.h"
#include "doc/documents_observer.h"
#include "doc/object_id.h"
namespace app {
@ -35,11 +37,15 @@ namespace app {
: public ISettings
, public IExperimentalSettings
, public IColorSwatchesStore
, public doc::DocumentsObserver
, base::Observable<GlobalSettingsObserver> {
public:
UISettingsImpl();
~UISettingsImpl();
// doc::DocumentsObserver
void onRemoveDocument(doc::Document* doc) override;
// Undo settings
size_t undoSizeLimit() const override;
bool undoGotoModified() const override;
@ -65,7 +71,7 @@ namespace app {
void setCurrentTool(tools::Tool* tool) override;
void setColorSwatches(app::ColorSwatches* colorSwatches) override;
IDocumentSettings* getDocumentSettings(const Document* document) override;
IDocumentSettings* getDocumentSettings(const doc::Document* document) override;
IToolSettings* getToolSettings(tools::Tool* tool) override;
IColorSwatchesStore* getColorSwatchesStore() override;
@ -87,7 +93,6 @@ namespace app {
private:
tools::Tool* m_currentTool;
base::UniquePtr<IDocumentSettings> m_globalDocumentSettings;
std::map<std::string, IToolSettings*> m_toolSettings;
app::ColorSwatches* m_colorSwatches;
std::vector<app::ColorSwatches*> m_colorSwatchesStore;
@ -96,6 +101,7 @@ namespace app {
bool m_showSpriteEditorScrollbars;
bool m_grabAlpha;
RightClickMode m_rightClickMode;
std::map<doc::ObjectId, IDocumentSettings*> m_docSettings;
};
} // namespace app

View File

@ -48,6 +48,8 @@ UIContext::UIContext()
: Context(new UISettingsImpl)
, m_lastSelectedView(NULL)
{
documents().addObserver(static_cast<UISettingsImpl*>(settings()));
ASSERT(m_instance == NULL);
m_instance = this;
}
@ -57,6 +59,8 @@ UIContext::~UIContext()
ASSERT(m_instance == this);
m_instance = NULL;
documents().removeObserver(static_cast<UISettingsImpl*>(settings()));
// The context must be empty at this point. (It's to check if the UI
// is working correctly, i.e. closing all files when the user can
// take any action about it.)