mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-31 00:32:48 +00:00
Merge branch 'master' into tilemap-editor
This commit is contained in:
commit
81b6a99c2c
2
laf
2
laf
@ -1 +1 @@
|
|||||||
Subproject commit 9c6ecadd9cbcfd2b87b7cfa61e01466013da3797
|
Subproject commit e1fb70a069c6482be282bf6f6d9190e3a0def14a
|
@ -539,7 +539,7 @@ App::~App()
|
|||||||
m_instance = NULL;
|
m_instance = NULL;
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
LOG(ERROR) << "APP: Error: " << e.what() << "\n";
|
LOG(ERROR, "APP: Error: %s\n", e.what());
|
||||||
os::error_message(e.what());
|
os::error_message(e.what());
|
||||||
|
|
||||||
// no re-throw
|
// no re-throw
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -184,7 +185,7 @@ AppBrushes::AppBrushes()
|
|||||||
load(fn);
|
load(fn);
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex) {
|
catch (const std::exception& ex) {
|
||||||
LOG(ERROR) << "BRSH: Error loading user brushes: " << ex.what() << "\n";
|
LOG(ERROR, "BRSH: Error loading user brushes: %s\n", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -14,6 +15,7 @@
|
|||||||
#include "ui/timer.h"
|
#include "ui/timer.h"
|
||||||
#include "updater/check_update.h"
|
#include "updater/check_update.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -47,7 +49,7 @@ namespace app {
|
|||||||
std::unique_ptr<base::thread> m_thread;
|
std::unique_ptr<base::thread> m_thread;
|
||||||
std::unique_ptr<CheckUpdateBackgroundJob> m_bgJob;
|
std::unique_ptr<CheckUpdateBackgroundJob> m_bgJob;
|
||||||
bool m_doCheck;
|
bool m_doCheck;
|
||||||
bool m_received;
|
std::atomic<bool> m_received;
|
||||||
|
|
||||||
// Mini-stats
|
// Mini-stats
|
||||||
int m_inits;
|
int m_inits;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "base/time.h"
|
#include "base/time.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -49,7 +50,7 @@ namespace app {
|
|||||||
base::tick_t timestamp;
|
base::tick_t timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool m_done;
|
std::atomic<bool> m_done;
|
||||||
base::tick_t m_dataRecoveryPeriodMSecs;
|
base::tick_t m_dataRecoveryPeriodMSecs;
|
||||||
base::tick_t m_keepClosedDocAliveForMSecs;
|
base::tick_t m_keepClosedDocAliveForMSecs;
|
||||||
std::vector<ClosedDoc> m_docs;
|
std::vector<ClosedDoc> m_docs;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -35,11 +35,13 @@ void DeselectMask::onUndo()
|
|||||||
{
|
{
|
||||||
Doc* doc = document();
|
Doc* doc = document();
|
||||||
|
|
||||||
doc->setMask(m_oldMask.get());
|
if (m_oldMask) {
|
||||||
doc->setMaskVisible(true);
|
doc->setMask(m_oldMask.get());
|
||||||
doc->notifySelectionChanged();
|
doc->setMaskVisible(true);
|
||||||
|
m_oldMask.reset();
|
||||||
|
}
|
||||||
|
|
||||||
m_oldMask.reset();
|
doc->notifySelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DeselectMask::onMemSize() const
|
size_t DeselectMask::onMemSize() const
|
||||||
|
@ -189,7 +189,8 @@ void PasteTextCommand::onExecute(Context* ctx)
|
|||||||
image.get(), NULL, sprite->pixelFormat(),
|
image.get(), NULL, sprite->pixelFormat(),
|
||||||
render::Dithering(),
|
render::Dithering(),
|
||||||
rgbmap, sprite->palette(editor->frame()),
|
rgbmap, sprite->palette(editor->frame()),
|
||||||
false, 0));
|
false,
|
||||||
|
sprite->transparentColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO we don't support pasting text in multiple cels at the
|
// TODO we don't support pasting text in multiple cels at the
|
||||||
|
@ -110,6 +110,8 @@ void BackupObserver::onRemoveDocument(Doc* doc)
|
|||||||
// then it's deleted from ClosedDocs::backgroundThread()
|
// then it's deleted from ClosedDocs::backgroundThread()
|
||||||
|
|
||||||
TRACE("RECO: Adding to CLOSEDOC %p\n", doc);
|
TRACE("RECO: Adding to CLOSEDOC %p\n", doc);
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_closedDocs.push_back(doc);
|
m_closedDocs.push_back(doc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include "app/doc_observer.h"
|
#include "app/doc_observer.h"
|
||||||
#include "app/docs_observer.h"
|
#include "app/docs_observer.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -48,7 +49,7 @@ namespace crash {
|
|||||||
Context* m_ctx;
|
Context* m_ctx;
|
||||||
std::vector<Doc*> m_documents;
|
std::vector<Doc*> m_documents;
|
||||||
std::vector<Doc*> m_closedDocs;
|
std::vector<Doc*> m_closedDocs;
|
||||||
bool m_done;
|
std::atomic<bool> m_done;
|
||||||
|
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
|
|
||||||
|
@ -210,8 +210,8 @@ void Session::removeFromDisk()
|
|||||||
}
|
}
|
||||||
catch (const std::exception& ex) {
|
catch (const std::exception& ex) {
|
||||||
(void)ex;
|
(void)ex;
|
||||||
LOG(ERROR) << "RECO: Session directory cannot be removed, it's not empty.\n"
|
LOG(ERROR, "RECO: Session directory cannot be removed, it's not empty.\n"
|
||||||
<< " Error: " << ex.what() << "\n";
|
" Error: %s\n", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ void Session::removeDocument(Doc* doc)
|
|||||||
markDocumentAsCorrectlyClosed(doc);
|
markDocumentAsCorrectlyClosed(doc);
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex) {
|
catch (const std::exception& ex) {
|
||||||
LOG(FATAL) << "Exception deleting document " << ex.what() << "\n";
|
LOG(FATAL, "Exception deleting document %s\n", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ void Doc::unlock()
|
|||||||
m_rwLock.unlock();
|
m_rwLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Doc::weakLock(base::RWLock::WeakLock* weak_lock_flag)
|
bool Doc::weakLock(std::atomic<base::RWLock::WeakLock>* weak_lock_flag)
|
||||||
{
|
{
|
||||||
return m_rwLock.weakLock(weak_lock_flag);
|
return m_rwLock.weakLock(weak_lock_flag);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "obs/observable.h"
|
#include "obs/observable.h"
|
||||||
#include "os/color_space.h"
|
#include "os/color_space.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ namespace app {
|
|||||||
void downgradeToRead();
|
void downgradeToRead();
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|
||||||
bool weakLock(base::RWLock::WeakLock* weak_lock_flag);
|
bool weakLock(std::atomic<base::RWLock::WeakLock>* weak_lock_flag);
|
||||||
void weakUnlock();
|
void weakUnlock();
|
||||||
|
|
||||||
// Sets active/running transaction.
|
// Sets active/running transaction.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include "app/doc.h"
|
#include "app/doc.h"
|
||||||
#include "base/exception.h"
|
#include "base/exception.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -245,7 +246,7 @@ namespace app {
|
|||||||
WeakDocReader(const WeakDocReader&);
|
WeakDocReader(const WeakDocReader&);
|
||||||
WeakDocReader& operator=(const WeakDocReader&);
|
WeakDocReader& operator=(const WeakDocReader&);
|
||||||
|
|
||||||
base::RWLock::WeakLock m_weak_lock;
|
std::atomic<base::RWLock::WeakLock> m_weak_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -107,7 +107,7 @@ static void output_message(j_common_ptr cinfo)
|
|||||||
(*cinfo->err->format_message)(cinfo, buffer);
|
(*cinfo->err->format_message)(cinfo, buffer);
|
||||||
|
|
||||||
// Put in the log file if.
|
// Put in the log file if.
|
||||||
LOG(ERROR) << "JPEG: \"" << buffer << "\"\n";
|
LOG(ERROR, "JPEG: \"%s\"\n", buffer);
|
||||||
|
|
||||||
// Leave the message for the application.
|
// Leave the message for the application.
|
||||||
((struct error_mgr *)cinfo->err)->fop->setError("%s\n", buffer);
|
((struct error_mgr *)cinfo->err)->fop->setError("%s\n", buffer);
|
||||||
|
@ -80,8 +80,8 @@ public:
|
|||||||
unsigned int m_version;
|
unsigned int m_version;
|
||||||
bool m_removed;
|
bool m_removed;
|
||||||
mutable bool m_is_folder;
|
mutable bool m_is_folder;
|
||||||
double m_thumbnailProgress;
|
std::atomic<double> m_thumbnailProgress;
|
||||||
os::Surface* m_thumbnail;
|
std::atomic<os::Surface*> m_thumbnail;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
LPITEMIDLIST m_pidl; // relative to parent
|
LPITEMIDLIST m_pidl; // relative to parent
|
||||||
LPITEMIDLIST m_fullpidl; // relative to the Desktop folder
|
LPITEMIDLIST m_fullpidl; // relative to the Desktop folder
|
||||||
@ -593,9 +593,9 @@ os::Surface* FileItem::getThumbnail()
|
|||||||
|
|
||||||
void FileItem::setThumbnail(os::Surface* thumbnail)
|
void FileItem::setThumbnail(os::Surface* thumbnail)
|
||||||
{
|
{
|
||||||
if (m_thumbnail)
|
auto old = m_thumbnail.exchange(thumbnail);
|
||||||
m_thumbnail->dispose();
|
if (old)
|
||||||
m_thumbnail = thumbnail;
|
old->dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileItem::FileItem(FileItem* parent)
|
FileItem::FileItem(FileItem* parent)
|
||||||
@ -621,8 +621,8 @@ FileItem::~FileItem()
|
|||||||
{
|
{
|
||||||
FS_TRACE("FS: Destroying FileItem() with parent %p\n", m_parent);
|
FS_TRACE("FS: Destroying FileItem() with parent %p\n", m_parent);
|
||||||
|
|
||||||
if (m_thumbnail)
|
if (auto ptr = m_thumbnail.load())
|
||||||
m_thumbnail->dispose();
|
ptr->dispose();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (m_fullpidl && m_fullpidl != m_pidl) {
|
if (m_fullpidl && m_fullpidl != m_pidl) {
|
||||||
|
@ -72,10 +72,10 @@ void HttpLoader::threadHttpRequest()
|
|||||||
LOG("HTTP: Response: %d\n", response.status());
|
LOG("HTTP: Response: %d\n", response.status());
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
LOG(ERROR) << "HTTP: Unexpected exception sending http request: " << e.what() << "\n";
|
LOG(ERROR, "HTTP: Unexpected exception sending http request: %s\n", e.what());
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
LOG(ERROR) << "HTTP: Unexpected unknown exception sending http request\n";
|
LOG(ERROR, "HTTP: Unexpected unknown exception sending http request\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_request;
|
delete m_request;
|
||||||
|
@ -28,8 +28,8 @@ namespace app {
|
|||||||
|
|
||||||
ResourceFinder::ResourceFinder(bool log)
|
ResourceFinder::ResourceFinder(bool log)
|
||||||
: m_log(log)
|
: m_log(log)
|
||||||
|
, m_current(-1)
|
||||||
{
|
{
|
||||||
m_current = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& ResourceFinder::filename() const
|
const std::string& ResourceFinder::filename() const
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -12,6 +12,7 @@
|
|||||||
#include "base/disable_copying.h"
|
#include "base/disable_copying.h"
|
||||||
#include "base/paths.h"
|
#include "base/paths.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -64,7 +65,7 @@ namespace app {
|
|||||||
private:
|
private:
|
||||||
bool m_log;
|
bool m_log;
|
||||||
base::paths m_paths;
|
base::paths m_paths;
|
||||||
int m_current;
|
std::atomic<int> m_current;
|
||||||
std::string m_default;
|
std::string m_default;
|
||||||
|
|
||||||
DISABLE_COPYING(ResourceFinder);
|
DISABLE_COPYING(ResourceFinder);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2015-2018 David Capello
|
// Copyright (C) 2015-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -116,9 +116,11 @@ int Selection_deselect(lua_State* L)
|
|||||||
Doc* doc = static_cast<Doc*>(sprite->document());
|
Doc* doc = static_cast<Doc*>(sprite->document());
|
||||||
ASSERT(doc);
|
ASSERT(doc);
|
||||||
|
|
||||||
Tx tx;
|
if (doc->isMaskVisible()) {
|
||||||
tx(new cmd::DeselectMask(doc));
|
Tx tx;
|
||||||
tx.commit();
|
tx(new cmd::DeselectMask(doc));
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto mask = obj->mask(L);
|
auto mask = obj->mask(L);
|
||||||
|
@ -29,6 +29,7 @@ Task::~Task()
|
|||||||
|
|
||||||
void Task::run(base::task::func_t&& func)
|
void Task::run(base::task::func_t&& func)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_token_mutex);
|
||||||
m_task.on_execute(std::move(func));
|
m_task.on_execute(std::move(func));
|
||||||
m_token = &m_task.start(tasks_pool);
|
m_token = &m_task.start(tasks_pool);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "base/task.h"
|
#include "base/task.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ namespace app {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool canceled() const {
|
bool canceled() const {
|
||||||
|
std::lock_guard<std::mutex> lock(m_token_mutex);
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->canceled();
|
return m_token->canceled();
|
||||||
else
|
else
|
||||||
@ -40,6 +42,7 @@ namespace app {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float progress() const {
|
float progress() const {
|
||||||
|
std::lock_guard<std::mutex> lock(m_token_mutex);
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->progress();
|
return m_token->progress();
|
||||||
else
|
else
|
||||||
@ -47,17 +50,20 @@ namespace app {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cancel() {
|
void cancel() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_token_mutex);
|
||||||
if (m_token)
|
if (m_token)
|
||||||
m_token->cancel();
|
m_token->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_progress(float progress) {
|
void set_progress(float progress) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_token_mutex);
|
||||||
if (m_token)
|
if (m_token)
|
||||||
m_token->set_progress(progress);
|
m_token->set_progress(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
base::task m_task;
|
base::task m_task;
|
||||||
|
mutable std::mutex m_token_mutex;
|
||||||
base::task_token* m_token;
|
base::task_token* m_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "render/render.h"
|
#include "render/render.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@ -167,7 +168,10 @@ private:
|
|||||||
thumbnailImage.get(), palette.get(), thumbnail,
|
thumbnailImage.get(), palette.get(), thumbnail,
|
||||||
0, 0, 0, 0, thumbnailImage->width(), thumbnailImage->height());
|
0, 0, 0, 0, thumbnailImage->width(), thumbnailImage->height());
|
||||||
|
|
||||||
m_item.fileitem->setThumbnail(thumbnail);
|
{
|
||||||
|
base::scoped_lock lock(m_mutex);
|
||||||
|
m_item.fileitem->setThumbnail(thumbnail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
THUMB_TRACE("FOP done with thumbnail: %s %s\n",
|
THUMB_TRACE("FOP done with thumbnail: %s %s\n",
|
||||||
@ -176,7 +180,10 @@ private:
|
|||||||
|
|
||||||
// Reset the m_item (first the fileitem so this worker is not
|
// Reset the m_item (first the fileitem so this worker is not
|
||||||
// associated to this fileitem anymore, and then the FileOp).
|
// associated to this fileitem anymore, and then the FileOp).
|
||||||
m_item.fileitem = nullptr;
|
{
|
||||||
|
base::scoped_lock lock(m_mutex);
|
||||||
|
m_item.fileitem = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
m_fop->setError("Error loading file:\n%s", e.what());
|
m_fop->setError("Error loading file:\n%s", e.what());
|
||||||
@ -205,7 +212,7 @@ private:
|
|||||||
app::ThumbnailGenerator::Item m_item;
|
app::ThumbnailGenerator::Item m_item;
|
||||||
FileOp* m_fop;
|
FileOp* m_fop;
|
||||||
mutable base::mutex m_mutex;
|
mutable base::mutex m_mutex;
|
||||||
bool m_isDone;
|
std::atomic<bool> m_isDone;
|
||||||
base::thread m_thread;
|
base::thread m_thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ void ToolBox::loadTools()
|
|||||||
if (!groupId)
|
if (!groupId)
|
||||||
throw base::Exception("The configuration file has a <group> without 'id' or 'text' attributes.");
|
throw base::Exception("The configuration file has a <group> without 'id' or 'text' attributes.");
|
||||||
|
|
||||||
LOG(VERBOSE) << "TOOL: Group " << groupId << "\n";
|
LOG(VERBOSE, "TOOL: %s group\n", groupId);
|
||||||
|
|
||||||
// Find an existent ToolGroup (this is useful in case we are
|
// Find an existent ToolGroup (this is useful in case we are
|
||||||
// reloading tool text/tooltips).
|
// reloading tool text/tooltips).
|
||||||
@ -258,7 +258,7 @@ void ToolBox::loadTools()
|
|||||||
tool->setDefaultBrushSize(
|
tool->setDefaultBrushSize(
|
||||||
defaultBrushSize ? std::strtol(defaultBrushSize, nullptr, 10): 1);
|
defaultBrushSize ? std::strtol(defaultBrushSize, nullptr, 10): 1);
|
||||||
|
|
||||||
LOG(VERBOSE) << "TOOL: Tool " << toolId << " in group " << groupId << " found\n";
|
LOG(VERBOSE, "TOOL: %s.%s tool\n", groupId, toolId);
|
||||||
|
|
||||||
loadToolProperties(xmlTool, tool, 0, "left");
|
loadToolProperties(xmlTool, tool, 0, "left");
|
||||||
loadToolProperties(xmlTool, tool, 1, "right");
|
loadToolProperties(xmlTool, tool, 1, "right");
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "app/app_menus.h"
|
#include "app/app_menus.h"
|
||||||
#include "app/crash/data_recovery.h"
|
#include "app/crash/data_recovery.h"
|
||||||
#include "app/crash/session.h"
|
#include "app/crash/session.h"
|
||||||
|
#include "app/doc.h"
|
||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
@ -28,6 +29,7 @@
|
|||||||
#include "app/ui/workspace.h"
|
#include "app/ui/workspace.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
|
#include "base/fs.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
#include "ui/button.h"
|
#include "ui/button.h"
|
||||||
@ -174,6 +176,15 @@ private:
|
|||||||
restoreView = nullptr;
|
restoreView = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the original path of the recovered document exists, in
|
||||||
|
// other case remove the path so we use the default one (last path
|
||||||
|
// used, or user docs folder, etc.)
|
||||||
|
{
|
||||||
|
std::string dir = base::get_file_path(doc->filename());
|
||||||
|
if (!base::is_directory(dir))
|
||||||
|
doc->setFilename(base::get_file_name(doc->filename()));
|
||||||
|
}
|
||||||
|
|
||||||
UIContext::instance()->documents().add(doc);
|
UIContext::instance()->documents().add(doc);
|
||||||
|
|
||||||
if (restoreView)
|
if (restoreView)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -488,7 +488,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
|
|||||||
if (tool) {
|
if (tool) {
|
||||||
KeyPtr key = this->tool(tool);
|
KeyPtr key = this->tool(tool);
|
||||||
if (key && tool_key) {
|
if (key && tool_key) {
|
||||||
LOG(VERBOSE) << "KEYS: Shortcut for tool " << tool_id << ": " << tool_key << "\n";
|
LOG(VERBOSE, "KEYS: Shortcut for tool %s: %s\n", tool_id, tool_key);
|
||||||
Accelerator accel(tool_key);
|
Accelerator accel(tool_key);
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
@ -516,7 +516,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
|
|||||||
if (tool) {
|
if (tool) {
|
||||||
KeyPtr key = this->quicktool(tool);
|
KeyPtr key = this->quicktool(tool);
|
||||||
if (key && tool_key) {
|
if (key && tool_key) {
|
||||||
LOG(VERBOSE) << "KEYS: Shortcut for quicktool " << tool_id << ": " << tool_key << "\n";
|
LOG(VERBOSE, "KEYS: Shortcut for quicktool %s: %s\n", tool_id, tool_key);
|
||||||
Accelerator accel(tool_key);
|
Accelerator accel(tool_key);
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
@ -544,8 +544,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
|
|||||||
if (action != KeyAction::None) {
|
if (action != KeyAction::None) {
|
||||||
KeyPtr key = this->action(action);
|
KeyPtr key = this->action(action);
|
||||||
if (key && action_key) {
|
if (key && action_key) {
|
||||||
LOG(VERBOSE) << "KEYS: Shortcut for action " << action_id
|
LOG(VERBOSE, "KEYS: Shortcut for action %s: %s\n", action_id, action_key);
|
||||||
<< ": " << action_key << "\n";
|
|
||||||
Accelerator accel(action_key);
|
Accelerator accel(action_key);
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
@ -573,8 +572,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
|
|||||||
if (action != WheelAction::None) {
|
if (action != WheelAction::None) {
|
||||||
KeyPtr key = this->wheelAction(action);
|
KeyPtr key = this->wheelAction(action);
|
||||||
if (key && action_key) {
|
if (key && action_key) {
|
||||||
LOG(VERBOSE) << "KEYS: Shortcut for wheel action " << action_id
|
LOG(VERBOSE, "KEYS: Shortcut for wheel action %s: %s\n", action_id, action_key);
|
||||||
<< ": " << action_key << "\n";
|
|
||||||
Accelerator accel(action_key);
|
Accelerator accel(action_key);
|
||||||
|
|
||||||
if (!removed)
|
if (!removed)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -533,6 +533,7 @@ void MainWindow::configureWorkspaceLayout()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_menuBar->setVisible(normal);
|
m_menuBar->setVisible(normal);
|
||||||
|
m_notifications->setVisible(normal && m_notifications->hasNotifications());
|
||||||
m_tabsBar->setVisible(normal);
|
m_tabsBar->setVisible(normal);
|
||||||
colorBarPlaceholder()->setVisible(normal && isDoc);
|
colorBarPlaceholder()->setVisible(normal && isDoc);
|
||||||
m_toolBar->setVisible(normal && isDoc);
|
m_toolBar->setVisible(normal && isDoc);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -41,14 +42,14 @@ private:
|
|||||||
Notifications::Notifications()
|
Notifications::Notifications()
|
||||||
: Button("")
|
: Button("")
|
||||||
, m_flagStyle(skin::SkinTheme::instance()->styles.flag())
|
, m_flagStyle(skin::SkinTheme::instance()->styles.flag())
|
||||||
, m_withNotifications(false)
|
, m_red(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notifications::addLink(INotificationDelegate* del)
|
void Notifications::addLink(INotificationDelegate* del)
|
||||||
{
|
{
|
||||||
m_popup.addChild(new NotificationItem(del));
|
m_popup.addChild(new NotificationItem(del));
|
||||||
m_withNotifications = true;
|
m_red = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notifications::onSizeHint(SizeHintEvent& ev)
|
void Notifications::onSizeHint(SizeHintEvent& ev)
|
||||||
@ -62,7 +63,7 @@ void Notifications::onPaint(PaintEvent& ev)
|
|||||||
|
|
||||||
PaintWidgetPartInfo info;
|
PaintWidgetPartInfo info;
|
||||||
if (hasMouseOver()) info.styleFlags |= ui::Style::Layer::kMouse;
|
if (hasMouseOver()) info.styleFlags |= ui::Style::Layer::kMouse;
|
||||||
if (m_withNotifications) info.styleFlags |= ui::Style::Layer::kFocus;
|
if (m_red) info.styleFlags |= ui::Style::Layer::kFocus;
|
||||||
if (isSelected()) info.styleFlags |= ui::Style::Layer::kSelected;
|
if (isSelected()) info.styleFlags |= ui::Style::Layer::kSelected;
|
||||||
|
|
||||||
theme()->paintWidgetPart(
|
theme()->paintWidgetPart(
|
||||||
@ -71,7 +72,7 @@ void Notifications::onPaint(PaintEvent& ev)
|
|||||||
|
|
||||||
void Notifications::onClick(ui::Event& ev)
|
void Notifications::onClick(ui::Event& ev)
|
||||||
{
|
{
|
||||||
m_withNotifications = false;
|
m_red = false;
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
gfx::Rect bounds = this->bounds();
|
gfx::Rect bounds = this->bounds();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -23,6 +24,7 @@ namespace app {
|
|||||||
Notifications();
|
Notifications();
|
||||||
|
|
||||||
void addLink(INotificationDelegate* del);
|
void addLink(INotificationDelegate* del);
|
||||||
|
bool hasNotifications() const { return m_popup.hasChildren(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onSizeHint(ui::SizeHintEvent& ev) override;
|
void onSizeHint(ui::SizeHintEvent& ev) override;
|
||||||
@ -31,7 +33,7 @@ namespace app {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ui::Style* m_flagStyle;
|
ui::Style* m_flagStyle;
|
||||||
bool m_withNotifications;
|
bool m_red;
|
||||||
ui::Menu m_popup;
|
ui::Menu m_popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ static FontData* load_font(std::map<std::string, FontData*>& fonts,
|
|||||||
if (it != fonts.end())
|
if (it != fonts.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
||||||
LOG(VERBOSE) << "THEME: Loading font '" << name << "'\n";
|
LOG(VERBOSE, "THEME: Loading font '%s'\n", name.c_str());
|
||||||
|
|
||||||
const char* typeStr = xmlFont->Attribute("type");
|
const char* typeStr = xmlFont->Attribute("type");
|
||||||
if (!typeStr)
|
if (!typeStr)
|
||||||
@ -185,7 +185,7 @@ static FontData* load_font(std::map<std::string, FontData*>& fonts,
|
|||||||
font->setAntialias(antialias);
|
font->setAntialias(antialias);
|
||||||
|
|
||||||
if (!fontFilename.empty())
|
if (!fontFilename.empty())
|
||||||
LOG(VERBOSE) << "THEME: Font file '" << fontFilename << "' found\n";
|
LOG(VERBOSE, "THEME: Font file '%s' found\n", fontFilename.c_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw base::Exception("Invalid type=\"%s\" in '%s' for <font name=\"%s\" ...>\n",
|
throw base::Exception("Invalid type=\"%s\" in '%s' for <font name=\"%s\" ...>\n",
|
||||||
@ -389,7 +389,7 @@ void SkinTheme::loadXml(BackwardCompatibility* backward)
|
|||||||
FontData* fontData = load_font(m_fonts, xmlFont, xml_filename);
|
FontData* fontData = load_font(m_fonts, xmlFont, xml_filename);
|
||||||
if (idStr && fontData) {
|
if (idStr && fontData) {
|
||||||
std::string id(idStr);
|
std::string id(idStr);
|
||||||
LOG(VERBOSE) << "THEME: Loading theme font '" << id << "\n";
|
LOG(VERBOSE, "THEME: Loading theme font %s\n", idStr);
|
||||||
|
|
||||||
int size = 10;
|
int size = 10;
|
||||||
const char* sizeStr = xmlFont->Attribute("size");
|
const char* sizeStr = xmlFont->Attribute("size");
|
||||||
@ -425,7 +425,7 @@ void SkinTheme::loadXml(BackwardCompatibility* backward)
|
|||||||
std::string id = xmlDim->Attribute("id");
|
std::string id = xmlDim->Attribute("id");
|
||||||
uint32_t value = strtol(xmlDim->Attribute("value"), NULL, 10);
|
uint32_t value = strtol(xmlDim->Attribute("value"), NULL, 10);
|
||||||
|
|
||||||
LOG(VERBOSE) << "THEME: Loading dimension '" << id << "\n";
|
LOG(VERBOSE, "THEME: Loading dimension %s\n", id.c_str());
|
||||||
|
|
||||||
m_dimensions_by_id[id] = value;
|
m_dimensions_by_id[id] = value;
|
||||||
xmlDim = xmlDim->NextSiblingElement();
|
xmlDim = xmlDim->NextSiblingElement();
|
||||||
@ -446,7 +446,7 @@ void SkinTheme::loadXml(BackwardCompatibility* backward)
|
|||||||
(value & 0xff00) >> 8,
|
(value & 0xff00) >> 8,
|
||||||
(value & 0xff));
|
(value & 0xff));
|
||||||
|
|
||||||
LOG(VERBOSE) << "THEME: Loading color " << id << "\n";
|
LOG(VERBOSE, "THEME: Loading color %s\n", id.c_str());
|
||||||
|
|
||||||
m_colors_by_id[id] = color;
|
m_colors_by_id[id] = color;
|
||||||
xmlColor = xmlColor->NextSiblingElement();
|
xmlColor = xmlColor->NextSiblingElement();
|
||||||
@ -467,7 +467,7 @@ void SkinTheme::loadXml(BackwardCompatibility* backward)
|
|||||||
int w = (xmlPart->Attribute("w") ? scale*strtol(xmlPart->Attribute("w"), nullptr, 10): 0);
|
int w = (xmlPart->Attribute("w") ? scale*strtol(xmlPart->Attribute("w"), nullptr, 10): 0);
|
||||||
int h = (xmlPart->Attribute("h") ? scale*strtol(xmlPart->Attribute("h"), nullptr, 10): 0);
|
int h = (xmlPart->Attribute("h") ? scale*strtol(xmlPart->Attribute("h"), nullptr, 10): 0);
|
||||||
|
|
||||||
LOG(VERBOSE) << "THEME: Loading part " << part_id << "\n";
|
LOG(VERBOSE, "THEME: Loading part %s\n", part_id);
|
||||||
|
|
||||||
SkinPartPtr part = m_parts_by_id[part_id];
|
SkinPartPtr part = m_parts_by_id[part_id];
|
||||||
if (!part)
|
if (!part)
|
||||||
@ -504,7 +504,7 @@ void SkinTheme::loadXml(BackwardCompatibility* backward)
|
|||||||
int focusx = scale*std::strtol(xmlPart->Attribute("focusx"), NULL, 10);
|
int focusx = scale*std::strtol(xmlPart->Attribute("focusx"), NULL, 10);
|
||||||
int focusy = scale*std::strtol(xmlPart->Attribute("focusy"), NULL, 10);
|
int focusy = scale*std::strtol(xmlPart->Attribute("focusy"), NULL, 10);
|
||||||
|
|
||||||
LOG(VERBOSE) << "THEME: Loading cursor '" << cursorName << "'\n";
|
LOG(VERBOSE, "THEME: Loading cursor '%s'\n", cursorName.c_str());
|
||||||
|
|
||||||
auto it = m_cursors.find(cursorName);
|
auto it = m_cursors.find(cursorName);
|
||||||
if (it != m_cursors.end() && it->second != nullptr) {
|
if (it != m_cursors.end() && it->second != nullptr) {
|
||||||
@ -622,8 +622,7 @@ void SkinTheme::loadXml(BackwardCompatibility* backward)
|
|||||||
while (xmlLayer) {
|
while (xmlLayer) {
|
||||||
const std::string layerName = xmlLayer->Value();
|
const std::string layerName = xmlLayer->Value();
|
||||||
|
|
||||||
LOG(VERBOSE) << "THEME: Layer " << layerName
|
LOG(VERBOSE, "THEME: Layer %s for %s\n", layerName.c_str(), style_id);
|
||||||
<< " for " << style_id << "\n";
|
|
||||||
|
|
||||||
ui::Style::Layer layer;
|
ui::Style::Layer layer;
|
||||||
|
|
||||||
|
@ -1523,7 +1523,6 @@ void Timeline::onResize(ui::ResizeEvent& ev)
|
|||||||
{
|
{
|
||||||
gfx::Rect rc = ev.bounds();
|
gfx::Rect rc = ev.bounds();
|
||||||
setBoundsQuietly(rc);
|
setBoundsQuietly(rc);
|
||||||
setSeparatorX(m_separator_x);
|
|
||||||
|
|
||||||
gfx::Size sz = m_aniControls.sizeHint();
|
gfx::Size sz = m_aniControls.sizeHint();
|
||||||
m_aniControls.setBounds(
|
m_aniControls.setBounds(
|
||||||
@ -1531,7 +1530,7 @@ void Timeline::onResize(ui::ResizeEvent& ev)
|
|||||||
rc.x,
|
rc.x,
|
||||||
rc.y+(visibleTagBands()-1)*oneTagHeight(),
|
rc.y+(visibleTagBands()-1)*oneTagHeight(),
|
||||||
(!m_sprite || m_sprite->tags().empty() ? std::min(sz.w, rc.w):
|
(!m_sprite || m_sprite->tags().empty() ? std::min(sz.w, rc.w):
|
||||||
std::min(sz.w, m_separator_x)),
|
std::min(sz.w, separatorX())),
|
||||||
oneTagHeight()));
|
oneTagHeight()));
|
||||||
|
|
||||||
updateScrollBars();
|
updateScrollBars();
|
||||||
@ -2637,7 +2636,7 @@ void Timeline::drawPaddings(ui::Graphics* g)
|
|||||||
gfx::Rect Timeline::getLayerHeadersBounds() const
|
gfx::Rect Timeline::getLayerHeadersBounds() const
|
||||||
{
|
{
|
||||||
gfx::Rect rc = clientBounds();
|
gfx::Rect rc = clientBounds();
|
||||||
rc.w = m_separator_x;
|
rc.w = separatorX();
|
||||||
int h = topHeight() + headerBoxHeight();
|
int h = topHeight() + headerBoxHeight();
|
||||||
rc.y += h;
|
rc.y += h;
|
||||||
rc.h -= h;
|
rc.h -= h;
|
||||||
@ -2647,9 +2646,9 @@ gfx::Rect Timeline::getLayerHeadersBounds() const
|
|||||||
gfx::Rect Timeline::getFrameHeadersBounds() const
|
gfx::Rect Timeline::getFrameHeadersBounds() const
|
||||||
{
|
{
|
||||||
gfx::Rect rc = clientBounds();
|
gfx::Rect rc = clientBounds();
|
||||||
rc.x += m_separator_x;
|
rc.x += separatorX();
|
||||||
rc.y += topHeight();
|
rc.y += topHeight();
|
||||||
rc.w -= m_separator_x;
|
rc.w -= separatorX();
|
||||||
rc.h = headerBoxHeight();
|
rc.h = headerBoxHeight();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -2676,8 +2675,8 @@ gfx::Rect Timeline::getOnionskinFramesBounds() const
|
|||||||
gfx::Rect Timeline::getCelsBounds() const
|
gfx::Rect Timeline::getCelsBounds() const
|
||||||
{
|
{
|
||||||
gfx::Rect rc = clientBounds();
|
gfx::Rect rc = clientBounds();
|
||||||
rc.x += m_separator_x;
|
rc.x += separatorX();
|
||||||
rc.w -= m_separator_x;
|
rc.w -= separatorX();
|
||||||
rc.y += headerBoxHeight() + topHeight();
|
rc.y += headerBoxHeight() + topHeight();
|
||||||
rc.h -= headerBoxHeight() + topHeight();
|
rc.h -= headerBoxHeight() + topHeight();
|
||||||
return rc;
|
return rc;
|
||||||
@ -2697,8 +2696,8 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
|||||||
return gfx::Rect(bounds.x, bounds.y, bounds.w, y);
|
return gfx::Rect(bounds.x, bounds.y, bounds.w, y);
|
||||||
|
|
||||||
case PART_SEPARATOR:
|
case PART_SEPARATOR:
|
||||||
return gfx::Rect(bounds.x + m_separator_x, bounds.y + y,
|
return gfx::Rect(bounds.x + separatorX(), bounds.y + y,
|
||||||
m_separator_x + m_separator_w, bounds.h - y);
|
separatorX() + m_separator_w, bounds.h - y);
|
||||||
|
|
||||||
case PART_HEADER_EYE:
|
case PART_HEADER_EYE:
|
||||||
return gfx::Rect(bounds.x + headerBoxWidth()*0, bounds.y + y,
|
return gfx::Rect(bounds.x + headerBoxWidth()*0, bounds.y + y,
|
||||||
@ -2722,11 +2721,11 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
|||||||
|
|
||||||
case PART_HEADER_LAYER:
|
case PART_HEADER_LAYER:
|
||||||
return gfx::Rect(bounds.x + headerBoxWidth()*5, bounds.y + y,
|
return gfx::Rect(bounds.x + headerBoxWidth()*5, bounds.y + y,
|
||||||
m_separator_x - headerBoxWidth()*5, headerBoxHeight());
|
separatorX() - headerBoxWidth()*5, headerBoxHeight());
|
||||||
|
|
||||||
case PART_HEADER_FRAME:
|
case PART_HEADER_FRAME:
|
||||||
return gfx::Rect(
|
return gfx::Rect(
|
||||||
bounds.x + m_separator_x + m_separator_w - 1
|
bounds.x + separatorX() + m_separator_w - 1
|
||||||
+ frameBoxWidth()*std::max(firstFrame(), hit.frame) - viewScroll().x,
|
+ frameBoxWidth()*std::max(firstFrame(), hit.frame) - viewScroll().x,
|
||||||
bounds.y + y, frameBoxWidth(), headerBoxHeight());
|
bounds.y + y, frameBoxWidth(), headerBoxHeight());
|
||||||
|
|
||||||
@ -2734,7 +2733,7 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
|||||||
if (validLayer(hit.layer)) {
|
if (validLayer(hit.layer)) {
|
||||||
return gfx::Rect(bounds.x,
|
return gfx::Rect(bounds.x,
|
||||||
bounds.y + y + headerBoxHeight() + layerBoxHeight()*(lastLayer()-hit.layer) - viewScroll().y,
|
bounds.y + y + headerBoxHeight() + layerBoxHeight()*(lastLayer()-hit.layer) - viewScroll().y,
|
||||||
m_separator_x, layerBoxHeight());
|
separatorX(), layerBoxHeight());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2767,14 +2766,14 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
|||||||
int x = headerBoxWidth()*3;
|
int x = headerBoxWidth()*3;
|
||||||
return gfx::Rect(bounds.x + x,
|
return gfx::Rect(bounds.x + x,
|
||||||
bounds.y + y + headerBoxHeight() + layerBoxHeight()*(lastLayer()-hit.layer) - viewScroll().y,
|
bounds.y + y + headerBoxHeight() + layerBoxHeight()*(lastLayer()-hit.layer) - viewScroll().y,
|
||||||
m_separator_x - x, layerBoxHeight());
|
separatorX() - x, layerBoxHeight());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PART_CEL:
|
case PART_CEL:
|
||||||
if (validLayer(hit.layer) && hit.frame >= frame_t(0)) {
|
if (validLayer(hit.layer) && hit.frame >= frame_t(0)) {
|
||||||
return gfx::Rect(
|
return gfx::Rect(
|
||||||
bounds.x + m_separator_x + m_separator_w - 1 + frameBoxWidth()*hit.frame - viewScroll().x,
|
bounds.x + separatorX() + m_separator_w - 1 + frameBoxWidth()*hit.frame - viewScroll().x,
|
||||||
bounds.y + y + headerBoxHeight() + layerBoxHeight()*(lastLayer()-hit.layer) - viewScroll().y,
|
bounds.y + y + headerBoxHeight() + layerBoxHeight()*(lastLayer()-hit.layer) - viewScroll().y,
|
||||||
frameBoxWidth(), layerBoxHeight());
|
frameBoxWidth(), layerBoxHeight());
|
||||||
}
|
}
|
||||||
@ -2818,16 +2817,16 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
|||||||
|
|
||||||
case PART_TAGS:
|
case PART_TAGS:
|
||||||
return gfx::Rect(
|
return gfx::Rect(
|
||||||
bounds.x + m_separator_x + m_separator_w - 1,
|
bounds.x + separatorX() + m_separator_w - 1,
|
||||||
bounds.y,
|
bounds.y,
|
||||||
bounds.w - m_separator_x - m_separator_w + 1, y);
|
bounds.w - separatorX() - m_separator_w + 1, y);
|
||||||
|
|
||||||
case PART_TAG_BAND:
|
case PART_TAG_BAND:
|
||||||
return gfx::Rect(
|
return gfx::Rect(
|
||||||
bounds.x + m_separator_x + m_separator_w - 1,
|
bounds.x + separatorX() + m_separator_w - 1,
|
||||||
bounds.y
|
bounds.y
|
||||||
+ (m_tagFocusBand < 0 ? oneTagHeight() * std::max(0, hit.band): 0),
|
+ (m_tagFocusBand < 0 ? oneTagHeight() * std::max(0, hit.band): 0),
|
||||||
bounds.w - m_separator_x - m_separator_w + 1,
|
bounds.w - separatorX() - m_separator_w + 1,
|
||||||
oneTagHeight());
|
oneTagHeight());
|
||||||
|
|
||||||
case PART_TAG_SWITCH_BUTTONS: {
|
case PART_TAG_SWITCH_BUTTONS: {
|
||||||
@ -3068,7 +3067,7 @@ Timeline::Hit Timeline::hitTest(ui::Message* msg, const gfx::Point& mousePos)
|
|||||||
+ scroll.y) / layerBoxHeight());
|
+ scroll.y) / layerBoxHeight());
|
||||||
|
|
||||||
hit.frame = frame_t((mousePos.x
|
hit.frame = frame_t((mousePos.x
|
||||||
- m_separator_x
|
- separatorX()
|
||||||
- m_separator_w
|
- m_separator_w
|
||||||
+ scroll.x) / frameBoxWidth());
|
+ scroll.x) / frameBoxWidth());
|
||||||
|
|
||||||
@ -3097,8 +3096,8 @@ Timeline::Hit Timeline::hitTest(ui::Message* msg, const gfx::Point& mousePos)
|
|||||||
hit.part = PART_HEADER_ONIONSKIN_RANGE_RIGHT;
|
hit.part = PART_HEADER_ONIONSKIN_RANGE_RIGHT;
|
||||||
}
|
}
|
||||||
// Is the mouse on the separator.
|
// Is the mouse on the separator.
|
||||||
else if (mousePos.x > m_separator_x-4
|
else if (mousePos.x > separatorX()-4
|
||||||
&& mousePos.x <= m_separator_x) {
|
&& mousePos.x <= separatorX()) {
|
||||||
hit.part = PART_SEPARATOR;
|
hit.part = PART_SEPARATOR;
|
||||||
}
|
}
|
||||||
// Is the mouse on the frame tags area?
|
// Is the mouse on the frame tags area?
|
||||||
@ -3173,7 +3172,7 @@ Timeline::Hit Timeline::hitTest(ui::Message* msg, const gfx::Point& mousePos)
|
|||||||
}
|
}
|
||||||
// Is the mouse on the headers?
|
// Is the mouse on the headers?
|
||||||
else if (mousePos.y >= top && mousePos.y < top+headerBoxHeight()) {
|
else if (mousePos.y >= top && mousePos.y < top+headerBoxHeight()) {
|
||||||
if (mousePos.x < m_separator_x) {
|
if (mousePos.x < separatorX()) {
|
||||||
if (getPartBounds(Hit(PART_HEADER_EYE)).contains(mousePos))
|
if (getPartBounds(Hit(PART_HEADER_EYE)).contains(mousePos))
|
||||||
hit.part = PART_HEADER_EYE;
|
hit.part = PART_HEADER_EYE;
|
||||||
else if (getPartBounds(Hit(PART_HEADER_PADLOCK)).contains(mousePos))
|
else if (getPartBounds(Hit(PART_HEADER_PADLOCK)).contains(mousePos))
|
||||||
@ -3195,7 +3194,7 @@ Timeline::Hit Timeline::hitTest(ui::Message* msg, const gfx::Point& mousePos)
|
|||||||
else if (mousePos.y < top+headerBoxHeight())
|
else if (mousePos.y < top+headerBoxHeight())
|
||||||
hit.part = PART_TOP;
|
hit.part = PART_TOP;
|
||||||
// Is the mouse on a layer's label?
|
// Is the mouse on a layer's label?
|
||||||
else if (mousePos.x < m_separator_x) {
|
else if (mousePos.x < separatorX()) {
|
||||||
if (getPartBounds(Hit(PART_ROW_EYE_ICON, hit.layer)).contains(mousePos))
|
if (getPartBounds(Hit(PART_ROW_EYE_ICON, hit.layer)).contains(mousePos))
|
||||||
hit.part = PART_ROW_EYE_ICON;
|
hit.part = PART_ROW_EYE_ICON;
|
||||||
else if (getPartBounds(Hit(PART_ROW_PADLOCK_ICON, hit.layer)).contains(mousePos))
|
else if (getPartBounds(Hit(PART_ROW_PADLOCK_ICON, hit.layer)).contains(mousePos))
|
||||||
@ -3251,7 +3250,7 @@ Timeline::Hit Timeline::hitTestCel(const gfx::Point& mousePos)
|
|||||||
+ scroll.y) / layerBoxHeight());
|
+ scroll.y) / layerBoxHeight());
|
||||||
|
|
||||||
hit.frame = frame_t((mousePos.x
|
hit.frame = frame_t((mousePos.x
|
||||||
- m_separator_x
|
- separatorX()
|
||||||
- m_separator_w
|
- m_separator_w
|
||||||
+ scroll.x) / frameBoxWidth());
|
+ scroll.x) / frameBoxWidth());
|
||||||
|
|
||||||
@ -4233,9 +4232,14 @@ void Timeline::setLayerCollapsedFlag(const layer_t l, const bool state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Timeline::separatorX() const
|
||||||
|
{
|
||||||
|
return base::clamp(m_separator_x, headerBoxWidth(), bounds().w-guiscale());
|
||||||
|
}
|
||||||
|
|
||||||
void Timeline::setSeparatorX(int newValue)
|
void Timeline::setSeparatorX(int newValue)
|
||||||
{
|
{
|
||||||
m_separator_x = base::clamp(newValue, headerBoxWidth(), bounds().w-guiscale());
|
m_separator_x = std::max(0, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -357,6 +357,7 @@ namespace app {
|
|||||||
void setLayerContinuousFlag(const layer_t layer, const bool state);
|
void setLayerContinuousFlag(const layer_t layer, const bool state);
|
||||||
void setLayerCollapsedFlag(const layer_t layer, const bool state);
|
void setLayerCollapsedFlag(const layer_t layer, const bool state);
|
||||||
|
|
||||||
|
int separatorX() const;
|
||||||
void setSeparatorX(int newValue);
|
void setSeparatorX(int newValue);
|
||||||
|
|
||||||
ui::ScrollBar m_hbar;
|
ui::ScrollBar m_hbar;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Config Library
|
// Aseprite Config Library
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2014-2017 David Capello
|
// Copyright (C) 2014-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -96,7 +96,8 @@ public:
|
|||||||
m_ini.SetMultiLine();
|
m_ini.SetMultiLine();
|
||||||
SI_Error err = m_ini.LoadFile(file.get());
|
SI_Error err = m_ini.LoadFile(file.get());
|
||||||
if (err != SI_OK) {
|
if (err != SI_OK) {
|
||||||
LOG(ERROR) << "CFG: Error " << err << " loading configuration from " << m_filename << "\n";
|
LOG(ERROR, "CFG: Error %d loading configuration from %s\n",
|
||||||
|
(int)err, m_filename.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +107,8 @@ public:
|
|||||||
if (file) {
|
if (file) {
|
||||||
SI_Error err = m_ini.SaveFile(file.get());
|
SI_Error err = m_ini.SaveFile(file.get());
|
||||||
if (err != SI_OK) {
|
if (err != SI_OK) {
|
||||||
LOG(ERROR) << "CFG: Error " << err << " saving configuration into " << m_filename << "\n";
|
LOG(ERROR, "CFG: Error %d saving configuration into %s\n",
|
||||||
|
(int)err, m_filename.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
|
// Copyright (c) 2020 Igara Studio S.A.
|
||||||
// Copyright (c) 2001-2018 David Capello
|
// Copyright (c) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -25,7 +26,7 @@
|
|||||||
namespace doc {
|
namespace doc {
|
||||||
namespace file {
|
namespace file {
|
||||||
|
|
||||||
Palette* load_gpl_file(const char *filename)
|
Palette* load_gpl_file(const char* filename)
|
||||||
{
|
{
|
||||||
std::ifstream f(FSTREAM_PATH(filename));
|
std::ifstream f(FSTREAM_PATH(filename));
|
||||||
if (f.bad()) return NULL;
|
if (f.bad()) return NULL;
|
||||||
@ -93,7 +94,7 @@ Palette* load_gpl_file(const char *filename)
|
|||||||
|
|
||||||
base::trim_string(comment, comment);
|
base::trim_string(comment, comment);
|
||||||
if (!comment.empty()) {
|
if (!comment.empty()) {
|
||||||
LOG(VERBOSE) << "PAL: " << filename << " comment: " << comment << "\n";
|
LOG(VERBOSE, "PAL: %s comment: %s\n", filename, comment.c_str());
|
||||||
pal->setComment(comment);
|
pal->setComment(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,9 +173,8 @@ void Widget::setBgColor(gfx::Color color)
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (m_style) {
|
if (m_style) {
|
||||||
LOG(WARNING) << "UI: " << typeid(*this).name()
|
LOG(WARNING, "UI: %s: Warning setting bgColor to a widget with style (%s)\n",
|
||||||
<< ": Warning setting bgColor to a widget with style ("
|
typeid(*this).name(), m_style->id().c_str());
|
||||||
<< m_style->id() << ")\n";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -707,9 +706,8 @@ void Widget::setBorder(const Border& br)
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (m_style) {
|
if (m_style) {
|
||||||
LOG(WARNING) << "UI: " << typeid(*this).name()
|
LOG(WARNING, "UI: %s: Warning setting border to a widget with style (%s)\n",
|
||||||
<< ": Warning setting border to a widget with style ("
|
typeid(*this).name(), m_style->id().c_str());
|
||||||
<< m_style->id() << ")\n";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -720,9 +718,8 @@ void Widget::setChildSpacing(int childSpacing)
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (m_style) {
|
if (m_style) {
|
||||||
LOG(WARNING) << "UI: " << typeid(*this).name()
|
LOG(WARNING, "UI: %s: Warning setting child spacing to a widget with style (%s)\n",
|
||||||
<< ": Warning setting child spacing to a widget with style ("
|
typeid(*this).name(), m_style->id().c_str());
|
||||||
<< m_style->id() << ")\n";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -734,9 +731,8 @@ void Widget::noBorderNoChildSpacing()
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (m_style) {
|
if (m_style) {
|
||||||
LOG(WARNING) << "UI: " << typeid(*this).name()
|
LOG(WARNING, "UI: %s: Warning setting no border to a widget with style (%s)\n",
|
||||||
<< ": Warning setting no border to a widget with style ("
|
typeid(*this).name(), m_style->id().c_str());
|
||||||
<< m_style->id() << ")\n";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -167,16 +167,17 @@ namespace ui {
|
|||||||
|
|
||||||
// Returns a list of children.
|
// Returns a list of children.
|
||||||
const WidgetsList& children() const { return m_children; }
|
const WidgetsList& children() const { return m_children; }
|
||||||
|
bool hasChildren() const { return !m_children.empty(); }
|
||||||
|
|
||||||
Widget* at(int index) { return m_children[index]; }
|
Widget* at(int index) { return m_children[index]; }
|
||||||
int getChildIndex(Widget* child);
|
int getChildIndex(Widget* child);
|
||||||
|
|
||||||
// Returns the first/last child or nullptr if it doesn't exist.
|
// Returns the first/last child or nullptr if it doesn't exist.
|
||||||
Widget* firstChild() {
|
Widget* firstChild() {
|
||||||
return (!m_children.empty() ? m_children.front(): nullptr);
|
return (hasChildren() ? m_children.front(): nullptr);
|
||||||
}
|
}
|
||||||
Widget* lastChild() {
|
Widget* lastChild() {
|
||||||
return (!m_children.empty() ? m_children.back(): nullptr);
|
return (hasChildren() ? m_children.back(): nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the next or previous siblings.
|
// Returns the next or previous siblings.
|
||||||
|
6
third_party/tinyxml/CMakeLists.txt
vendored
6
third_party/tinyxml/CMakeLists.txt
vendored
@ -1,8 +1,12 @@
|
|||||||
# ASEPRITE
|
# ASEPRITE
|
||||||
|
# Copyright (C) 2020 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2013 David Capello
|
# Copyright (C) 2001-2013 David Capello
|
||||||
|
|
||||||
add_library(tinyxml
|
add_library(tinyxml
|
||||||
tinystr.cpp
|
|
||||||
tinyxml.cpp
|
tinyxml.cpp
|
||||||
tinyxmlerror.cpp
|
tinyxmlerror.cpp
|
||||||
tinyxmlparser.cpp)
|
tinyxmlparser.cpp)
|
||||||
|
|
||||||
|
# Use std::string instead of TiXmlString (we've found some threading
|
||||||
|
# issues related to TiXmlString::nullrep_)
|
||||||
|
target_compile_definitions(tinyxml PUBLIC TIXML_USE_STL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user