mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-20 09:40:03 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
1c1c4593ed
@ -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" />
|
||||
|
@ -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" />
|
||||
|
@ -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
2
laf
@ -1 +1 @@
|
||||
Subproject commit 17ab4c87f65d24fe5cac6bf94d3fcb0dde29f6fa
|
||||
Subproject commit 50573685f7af01a68233acaed99bea00145b6778
|
@ -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.
|
||||
|
@ -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()) {
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -35,6 +35,8 @@ bool ExprEntry::onProcessMessage(ui::Message* msg)
|
||||
onFormatExprFocusLeave(buf);
|
||||
if (text() != buf)
|
||||
setText(buf);
|
||||
|
||||
Leave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user