Merge branch 'main' into beta

This commit is contained in:
David Capello 2024-08-22 14:26:18 -03:00
commit 1c1c4593ed
18 changed files with 82 additions and 33 deletions

View File

@ -695,9 +695,7 @@
<background color="check_hot_face" state="selected" />
<icon part="pal_options" />
</style>
<style id="new_frame_button" extends="mini_button" padding-bottom="1">
<icon part="icon_add" />
</style>
<style id="new_frame_button" extends="mini_button" padding-left="2" width="11" />
<style id="color_button" extends="mini_button" font="mini" padding-bottom="1" />
<style id="splitter">
<background color="face" />

View File

@ -688,9 +688,7 @@
<background color="check_hot_face" state="selected" />
<icon part="pal_options" />
</style>
<style id="new_frame_button" extends="mini_button" padding-bottom="1">
<icon part="icon_add" />
</style>
<style id="new_frame_button" extends="mini_button" padding-left="2" width="11" />
<style id="color_button" extends="mini_button" font="mini" padding-bottom="1" />
<style id="splitter">
<background color="face" />

View File

@ -510,7 +510,7 @@ The data of this chunk is as follows:
of the the External Files Chunk.
DWORD Tileset ID in the external file
+ If flag 2 is set
DWORD Compressed data length
DWORD Data length of the compressed Tileset image
PIXEL[] Compressed Tileset image (see NOTE.3):
(Tile Width) x (Tile Height x Number of Tiles)

2
laf

@ -1 +1 @@
Subproject commit 17ab4c87f65d24fe5cac6bf94d3fcb0dde29f6fa
Subproject commit 50573685f7af01a68233acaed99bea00145b6778

View File

@ -102,7 +102,7 @@ set(DATA_OUTPUT_DIR ${CMAKE_BINARY_DIR}/bin/data)
######################################################################
# Clone "strings" repo with translations into bin/data/strings.git
if(ENABLE_I18N_STRINGS_REPO)
if(ENABLE_I18N_STRINGS)
include(FetchContent)
find_package(Git)
if(GIT_FOUND)
@ -137,7 +137,7 @@ foreach(fn ${src_data_files})
list(APPEND out_data_files ${DATA_OUTPUT_DIR}/${fn})
endforeach()
if(ENABLE_I18N_STRINGS_REPO AND GIT_FOUND)
if(ENABLE_I18N_STRINGS AND GIT_FOUND)
# Copy original en.ini to strings.git/en.ini to keep it updated. We
# have to manually sync the "en.ini" file in the "strings" repo from
# the "aseprite" repo.

View File

@ -114,6 +114,16 @@ void GridSettingsCommand::onExecute(Context* context)
window.gridY()->setTextf("%d", bounds.y);
window.gridW()->setTextf("%d", bounds.w);
window.gridH()->setTextf("%d", bounds.h);
window.gridW()->Leave.connect([&window]{
// Prevent entering a width lesser than 1
if (window.gridW()->textInt() <= 0)
window.gridW()->setText("1");
});
window.gridH()->Leave.connect([&window]{
// Prevent entering a height lesser than 1
if (window.gridH()->textInt() <= 0)
window.gridH()->setText("1");
});
window.openWindowInForeground();
if (window.closer() == window.ok()) {

View File

@ -321,6 +321,18 @@ public:
}
cursorColorType()->Change.connect([this]{ onCursorColorType(); });
// Grid
gridW()->Leave.connect([this] {
// Prevent entering a width lesser than 1
if (gridW()->textInt() <= 0)
gridW()->setText("1");
});
gridH()->Leave.connect([this] {
// Prevent entering a height lesser than 1
if (gridH()->textInt() <= 0)
gridH()->setText("1");
});
// Brush preview
brushPreview()->setSelectedItemIndex(
(int)m_pref.cursor.brushPreview());

View File

@ -936,15 +936,15 @@ const render::DitheringMatrix* Extensions::ditheringMatrix(const std::string& ma
return nullptr;
}
std::vector<Extension::DitheringMatrixInfo> Extensions::ditheringMatrices()
std::vector<Extension::DitheringMatrixInfo*> Extensions::ditheringMatrices()
{
std::vector<Extension::DitheringMatrixInfo> result;
std::vector<Extension::DitheringMatrixInfo*> result;
for (auto ext : m_extensions) {
if (!ext->isEnabled()) // Ignore disabled themes
continue;
for (auto it : ext->m_ditheringMatrices)
result.push_back(it.second);
for (auto& it : ext->m_ditheringMatrices)
result.push_back(&it.second);
}
return result;
}

View File

@ -222,7 +222,13 @@ namespace app {
std::string palettePath(const std::string& palId);
ExtensionItems palettes() const;
const render::DitheringMatrix* ditheringMatrix(const std::string& matrixId);
std::vector<Extension::DitheringMatrixInfo> ditheringMatrices();
// The returned collection can be used temporarily while
// extensions are not installed/uninstalled. Each element is
// pointing to the real matrix info owned by extensions, this is
// needed to cache the matrix because it is lazy loaded from an
// image file. These pointers cannot be deleted.
std::vector<Extension::DitheringMatrixInfo*> ditheringMatrices();
obs::signal<void(Extension*)> NewExtension;
obs::signal<void(Extension*)> KeysChange;

View File

@ -152,6 +152,12 @@ bool ToolLoopManager::releaseButton(const Pointer& pointer)
if (isCanceled())
return false;
if (m_toolLoop->getController()->isOnePoint() &&
m_toolLoop->getInk()->isSelection() &&
!m_toolLoop->getSrcImage()->bounds().contains(pointer.point())) {
return false;
}
Stroke::Pt spritePoint = getSpriteStrokePt(pointer);
bool res = m_toolLoop->getController()->releaseButton(m_stroke, spritePoint);

View File

@ -1260,9 +1260,9 @@ public:
bool found = false;
auto ditheringMatrices = App::instance()
->extensions().ditheringMatrices();
for (const auto& it : ditheringMatrices) {
if (it.name() == dynaPref.matrixName()) {
m_dynamics.ditheringMatrix = it.matrix();
for (const auto* it : ditheringMatrices) {
if (it->name() == dynaPref.matrixName()) {
m_dynamics.ditheringMatrix = it->matrix();
found = true;
break;
}

View File

@ -217,25 +217,25 @@ void DitheringSelector::regenerate(int selectedItemIndex)
addItem(new DitherItem(render::DitheringAlgorithm::None,
render::DitheringMatrix(),
Strings::dithering_selector_no_dithering()));
for (const auto& it : ditheringMatrices) {
for (const auto* it : ditheringMatrices) {
try {
addItem(new DitherItem(
render::DitheringAlgorithm::Ordered,
it.matrix(),
Strings::dithering_selector_ordered_dithering() + it.name()));
it->matrix(),
Strings::dithering_selector_ordered_dithering() + it->name()));
}
catch (const std::exception& e) {
LOG(ERROR, "%s\n", e.what());
Console::showException(e);
}
}
for (const auto& it : ditheringMatrices) {
for (const auto* it : ditheringMatrices) {
try {
addItem(
new DitherItem(
render::DitheringAlgorithm::Old,
it.matrix(),
Strings::dithering_selector_old_dithering() + it.name()));
it->matrix(),
Strings::dithering_selector_old_dithering() + it->name()));
}
catch (const std::exception& e) {
LOG(ERROR, "%s\n", e.what());
@ -251,9 +251,9 @@ void DitheringSelector::regenerate(int selectedItemIndex)
case SelectMatrix:
addItem(new DitherItem(render::DitheringMatrix(),
Strings::dithering_selector_no_dithering()));
for (auto& it : ditheringMatrices) {
for (const auto* it : ditheringMatrices) {
try {
addItem(new DitherItem(it.matrix(), it.name()));
addItem(new DitherItem(it->matrix(), it->name()));
}
catch (const std::exception& e) {
LOG(ERROR, "%s\n", e.what());

View File

@ -199,6 +199,12 @@ void ExportFileWindow::setOutputFilename(const std::string& pathAndFilename)
else {
m_outputPath = base::get_file_path(m_doc->filename());
m_outputFilename = base::get_relative_path(pathAndFilename, base::get_file_path(m_doc->filename()));
// Cannot find a relative path (e.g. we selected other drive)
if (m_outputFilename == pathAndFilename) {
m_outputPath = base::get_file_path(pathAndFilename);
m_outputFilename = base::get_file_name(pathAndFilename);
}
}
updateOutputFilenameEntry();

View File

@ -35,6 +35,8 @@ bool ExprEntry::onProcessMessage(ui::Message* msg)
onFormatExprFocusLeave(buf);
if (text() != buf)
setText(buf);
Leave();
break;
}
}

View File

@ -20,6 +20,9 @@ namespace app {
int decimals() const { return m_decimals; }
void setDecimals(int decimals) { m_decimals = decimals; }
// Signals
obs::signal<void()> Leave;
protected:
bool onProcessMessage(ui::Message* msg) override;
void onChange() override;

View File

@ -695,16 +695,12 @@ StatusBar::StatusBar(TooltipManager* tooltipManager)
// Construct the commands box
{
auto theme = SkinTheme::get(this);
Box* box1 = new Box(HORIZONTAL);
Box* box4 = new Box(HORIZONTAL);
m_frameLabel = new Label(Strings::statusbar_tips_frame());
m_currentFrame = new GotoFrameEntry();
m_newFrame = new Button("");
if (!theme->parts.iconAdd())
m_newFrame->setText("+"); // Fallback for themes without the icon.
m_newFrame = new Button("+");
m_newFrame->Click.connect(&StatusBar::newFrame, this);
m_newFrame->RightClick.connect(&StatusBar::showNewFramePopupMenu, this);
@ -929,7 +925,7 @@ void StatusBar::onInitTheme(ui::InitThemeEvent& ev)
textHeight()+8*guiscale()));
m_newFrame->setStyle(theme->styles.newFrameButton());
m_commandsBox->setBorder(gfx::Border(2, 2, 2, 2)*guiscale());
m_commandsBox->setBorder(gfx::Border(2, 1, 2, 2)*guiscale());
if (m_snapToGridWindow) {
m_snapToGridWindow->initTheme();

View File

@ -49,6 +49,11 @@ gfx::Rect Sprite::DefaultGridBounds()
void Sprite::SetDefaultGridBounds(const gfx::Rect& defGridBounds)
{
g_defaultGridBounds = defGridBounds;
// Prevent setting an empty grid bounds
if (g_defaultGridBounds.w <= 0)
g_defaultGridBounds.w = 1;
if (g_defaultGridBounds.h <= 0)
g_defaultGridBounds.h = 1;
}
// static

View File

@ -127,7 +127,14 @@ namespace doc {
static void SetDefaultRgbMapAlgorithm(const RgbMapAlgorithm mapAlgo);
const gfx::Rect& gridBounds() const { return m_gridBounds; }
void setGridBounds(const gfx::Rect& rc) { m_gridBounds = rc; }
void setGridBounds(const gfx::Rect& rc) {
m_gridBounds = rc;
// Prevent setting an empty grid bounds
if (m_gridBounds.w <= 0)
m_gridBounds.w = 1;
if (m_gridBounds.h <= 0)
m_gridBounds.h = 1;
}
virtual int getMemSize() const override;