Compare commits

...

8 Commits

Author SHA1 Message Date
Gaspar Capello 2ffdf04ecc
Merge 1a5361b637 into 2ba051b59b 2025-07-23 18:49:17 -04:00
David Capello 2ba051b59b Fix crash deselecting moved pixels when using certain extensions (fix #5280)
build / build (Debug, macos-latest, lua, cli) (push) Waiting to run Details
build / build (Debug, macos-latest, noscripts, cli) (push) Waiting to run Details
build / build (Debug, ubuntu-latest, lua, cli) (push) Waiting to run Details
build / build (Debug, ubuntu-latest, noscripts, cli) (push) Waiting to run Details
build / build (Debug, windows-latest, lua, cli) (push) Waiting to run Details
build / build (Debug, windows-latest, noscripts, cli) (push) Waiting to run Details
build / build (RelWithDebInfo, macos-latest, lua, gui) (push) Waiting to run Details
build / build (RelWithDebInfo, ubuntu-latest, lua, gui) (push) Waiting to run Details
build / build (RelWithDebInfo, windows-latest, lua, gui) (push) Waiting to run Details
Although the issue refers to deselecting MovingPixelsState, the same
crash could happen when canceling/finishing WritingTextState or
MovingSelectionState. This fixes the crash for all these states.
2025-07-23 19:01:37 -03:00
Christian Kaiser 3fcb000eb1 Fix slice transformations not updating editors
build / build (Debug, macos-latest, lua, cli) (push) Has been cancelled Details
build / build (Debug, macos-latest, noscripts, cli) (push) Has been cancelled Details
build / build (Debug, ubuntu-latest, lua, cli) (push) Has been cancelled Details
build / build (Debug, ubuntu-latest, noscripts, cli) (push) Has been cancelled Details
build / build (Debug, windows-latest, lua, cli) (push) Has been cancelled Details
build / build (Debug, windows-latest, noscripts, cli) (push) Has been cancelled Details
build / build (RelWithDebInfo, macos-latest, lua, gui) (push) Has been cancelled Details
build / build (RelWithDebInfo, ubuntu-latest, lua, gui) (push) Has been cancelled Details
build / build (RelWithDebInfo, windows-latest, lua, gui) (push) Has been cancelled Details
2025-07-22 02:11:07 -03:00
David Capello af9dc3c817 Fix brush boundaries accumulation switching brush type only (fix #5281)
build / build (Debug, macos-latest, lua, cli) (push) Waiting to run Details
build / build (Debug, macos-latest, noscripts, cli) (push) Waiting to run Details
build / build (Debug, ubuntu-latest, lua, cli) (push) Waiting to run Details
build / build (Debug, ubuntu-latest, noscripts, cli) (push) Waiting to run Details
build / build (Debug, windows-latest, lua, cli) (push) Waiting to run Details
build / build (Debug, windows-latest, noscripts, cli) (push) Waiting to run Details
build / build (RelWithDebInfo, macos-latest, lua, gui) (push) Waiting to run Details
build / build (RelWithDebInfo, ubuntu-latest, lua, gui) (push) Waiting to run Details
build / build (RelWithDebInfo, windows-latest, lua, gui) (push) Waiting to run Details
2025-07-21 17:28:11 -03:00
David Capello 250dfdc86a Convert the brush generation counter into an atomic var 2025-07-21 17:27:23 -03:00
David Capello c904c41b39 Don't show stroke/fill option for theme fonts
build / build (Debug, macos-latest, lua, cli) (push) Has been cancelled Details
build / build (Debug, macos-latest, noscripts, cli) (push) Has been cancelled Details
build / build (Debug, ubuntu-latest, lua, cli) (push) Has been cancelled Details
build / build (Debug, ubuntu-latest, noscripts, cli) (push) Has been cancelled Details
build / build (Debug, windows-latest, lua, cli) (push) Has been cancelled Details
build / build (Debug, windows-latest, noscripts, cli) (push) Has been cancelled Details
build / build (RelWithDebInfo, macos-latest, lua, gui) (push) Has been cancelled Details
build / build (RelWithDebInfo, ubuntu-latest, lua, gui) (push) Has been cancelled Details
build / build (RelWithDebInfo, windows-latest, lua, gui) (push) Has been cancelled Details
2025-07-18 18:48:35 -03:00
David Capello 9e941e9a8b [win32] Fix listing hidden files on Windows (related to #5269 / #3079) 2025-07-18 18:37:44 -03:00
Liebranca bbab4d5875 Add 'Show hidden' check to file selector 2025-07-18 18:26:35 -03:00
16 changed files with 92 additions and 34 deletions

View File

@ -356,6 +356,7 @@
<section id="file_selector">
<option id="current_folder" type="std::string" default="&quot;&lt;empty&gt;&quot;" />
<option id="zoom" type="double" default="1.0" />
<option id="show_hidden" type="bool" default="false" />
</section>
<section id="text_tool">
<option id="font_face" type="std::string" />

View File

@ -765,6 +765,7 @@ pinned_folders = Pinned Folders
recent_folders = Recent Folders
all_formats = All formats
all_files = All files
show_hidden = Show hidden
[filters]
selected_cels = Selected

View File

@ -23,6 +23,7 @@
<combobox id="location" expansive="true" />
<button text="" id="refresh_button" style="refresh_button"
tooltip="@.refresh_button_tooltip" tooltip_dir="bottom" />
<check id="show_hidden_check" text="@.show_hidden" />
</box>
<vbox id="file_view_placeholder" expansive="true" />
<grid columns="2">

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2019-2025 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -82,6 +82,9 @@ public:
unsigned int m_version;
bool m_removed;
mutable bool m_is_folder;
#ifdef _WIN32
bool m_isHidden = false;
#endif
std::atomic<double> m_thumbnailProgress;
std::atomic<os::Surface*> m_thumbnail;
#ifdef _WIN32
@ -266,7 +269,7 @@ IFileItem* FileSystemModule::getRootFileItem()
fileitem->m_pidl = pidl;
fileitem->m_fullpidl = pidl;
SFGAOF attrib = SFGAO_FOLDER;
SFGAOF attrib = SFGAO_FOLDER | SFGAO_HIDDEN;
shl_idesktop->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attrib);
update_by_pidl(fileitem, attrib);
@ -357,7 +360,7 @@ bool FileItem::isHidden() const
ASSERT(m_displayname != NOTINITIALIZED);
#ifdef _WIN32
return false;
return m_isHidden;
#else
return m_displayname[0] == '.';
#endif
@ -462,7 +465,7 @@ const FileItemList& FileItem::children()
// Get the interface to enumerate subitems
hr = pFolder->EnumObjects(
reinterpret_cast<HWND>(os::System::instance()->defaultWindow()->nativeHandle()),
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN,
&pEnum);
if (hr == S_OK && pEnum) {
@ -473,10 +476,9 @@ const FileItemList& FileItem::children()
while (pEnum->Next(256, itempidl, &fetched) == S_OK && fetched > 0) {
// Request the SFGAO_FOLDER attribute to know what of the
// item is file or a folder
for (c = 0; c < fetched; ++c) {
attribs[c] = SFGAO_FOLDER;
pFolder->GetAttributesOf(1, (LPCITEMIDLIST*)itempidl, attribs + c);
}
for (c = 0; c < fetched; ++c)
attribs[c] = SFGAO_FOLDER | SFGAO_HIDDEN;
pFolder->GetAttributesOf(fetched, (LPCITEMIDLIST*)itempidl, attribs);
// Generate the FileItems
for (c = 0; c < fetched; ++c) {
@ -755,6 +757,9 @@ static void update_by_pidl(FileItem* fileitem, SFGAOF attrib)
// Is it a folder?
fileitem->m_is_folder = calc_is_folder(fileitem->m_filename, attrib);
#if _WIN32
fileitem->m_isHidden = (attrib & SFGAO_HIDDEN ? true : false);
#endif
// Get the name to display

View File

@ -1857,7 +1857,7 @@ private:
class ContextBar::FontSelector : public FontEntry {
public:
FontSelector(ContextBar* contextBar)
FontSelector(ContextBar* contextBar) : FontEntry(true) // With stroke and fill options
{
// Load the font from the preferences
setInfo(FontInfo::getFromPreferences(), FontEntry::From::Init);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2019-2025 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -457,6 +457,8 @@ void BrushPreview::show(const gfx::Point& screenPos)
// Here we re-use the cached surface
if (!cached && m_uiLayer->surface()) {
m_uiLayer->surface()->clear();
gfx::Rect layerBounds = m_uiLayer->surface()->bounds();
ui::Graphics g(display, m_uiLayer->surface(), 0, 0);

View File

@ -58,6 +58,7 @@
#include "app/util/tile_flags_utils.h"
#include "base/chrono.h"
#include "base/convert_to.h"
#include "base/scoped_value.h"
#include "doc/doc.h"
#include "doc/mask_boundaries.h"
#include "doc/slice.h"
@ -266,6 +267,23 @@ void Editor::setStateInternal(const EditorStatePtr& newState)
{
m_brushPreview.hide();
// Some onLeaveState impls (like the ones from MovingPixelsState,
// WritingTextState, MovingSelectionState) might generate a
// Tx/Transaction::commit(), which will add a new undo state,
// triggering a sprite change scripting event
// (SpriteEvents::onAddUndoState). This event could be handled by an
// extension and that extension might want to save the current
// sprite (e.g. calling Sprite_saveCopyAs, the kind of extension
// that takes snapshots after each sprite change). That will be a
// new Context::executeCommand() for the save command, generating a
// BeforeCommandExecution signal, getting back to onLeaveState
// again. In that case, we just ignore the reentry as the first
// onLeaveState should handle everything (to avoid an stack
// overflow/infinite recursion).
if (m_leavingState)
return;
base::ScopedValue leaving(m_leavingState, true);
// Fire before change state event, set the state, and fire after
// change state event.
EditorState::LeaveAction leaveAction = m_state->onLeaveState(this, newState.get());

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2024 Igara Studio S.A.
// Copyright (C) 2018-2025 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -458,6 +458,13 @@ private:
DocView* m_docView;
// Special flag to avoid re-entering a new state when we are leaving
// the current one. This avoids an infinite onLeaveState() recursion
// in some special cases when an extension (third-party code)
// creates a new sprite change in the same sprite change scripting
// event.
bool m_leavingState = false;
// Last known mouse position received by this editor when the
// mouse button was pressed. Used for auto-scrolling. To get the
// current mouse position on the editor you can use

View File

@ -428,8 +428,8 @@ bool MovingSliceState::onMouseMove(Editor* editor, MouseMessage* msg)
if (editor->slicesTransforms())
drawExtraCel();
// Redraw the editor.
editor->invalidate();
// Notify changes
m_site.document()->notifyGeneralUpdate();
// Use StandbyState implementation
return StandbyState::onMouseMove(editor, msg);

View File

@ -45,6 +45,7 @@ FileList::FileList()
, m_multiselect(false)
, m_zoom(1.0)
, m_itemsPerRow(0)
, m_showHidden(Preferences::instance().fileSelector.showHidden())
{
setFocusStop(true);
setDoubleBuffered(true);
@ -173,6 +174,14 @@ void FileList::animateToZoom(const double zoom)
startAnimation(ANI_ZOOM, 10);
}
void FileList::setShowHidden(const bool show)
{
m_showHidden = show;
m_req_valid = false;
m_selected = nullptr;
regenerateList();
}
bool FileList::onProcessMessage(Message* msg)
{
switch (msg->type()) {
@ -825,7 +834,7 @@ void FileList::regenerateList()
for (FileItemList::iterator it = m_list.begin(); it != m_list.end();) {
IFileItem* fileitem = *it;
if (fileitem->isHidden())
if (fileitem->isHidden() && !m_showHidden)
it = m_list.erase(it);
else if (!fileitem->isFolder() && !fileitem->hasExtension(m_exts)) {
it = m_list.erase(it);

View File

@ -54,6 +54,7 @@ public:
double zoom() const { return m_zoom; }
void setZoom(const double zoom);
void animateToZoom(const double zoom);
void setShowHidden(const bool show);
obs::signal<void()> FileSelected;
obs::signal<void()> FileAccepted;
@ -137,6 +138,7 @@ private:
double m_toZoom;
int m_itemsPerRow;
bool m_showHidden;
};
} // namespace app

View File

@ -316,6 +316,7 @@ FileSelector::FileSelector(FileSelectorType type) : m_type(type), m_navigationLo
for (auto child : viewType()->children())
child->setFocusStop(false);
showHiddenCheck()->setSelected(Preferences::instance().fileSelector.showHidden());
m_fileList = new FileList();
m_fileList->setId("fileview");
m_fileName->setAssociatedFileList(m_fileList);
@ -334,6 +335,10 @@ FileSelector::FileSelector(FileSelectorType type) : m_type(type), m_navigationLo
viewType()->ItemChange.connect([this] { onChangeViewType(); });
location()->CloseListBox.connect([this] { onLocationCloseListBox(); });
fileType()->Change.connect([this] { onFileTypeChange(); });
showHiddenCheck()->Click.connect([this] {
Preferences::instance().fileSelector.showHidden(showHiddenCheck()->isSelected());
m_fileList->setShowHidden(showHiddenCheck()->isSelected());
});
m_fileList->FileSelected.connect([this] { onFileListFileSelected(); });
m_fileList->FileAccepted.connect([this] { onFileListFileAccepted(); });
m_fileList->CurrentFolderChanged.connect([this] { onFileListCurrentFolderChanged(); });

View File

@ -332,7 +332,9 @@ int FontEntry::FontStroke::WidthEntry::onGetValueFromText(const std::string& tex
return int(10.0 * base::convert_to<double>(text));
}
FontEntry::FontEntry() : m_style(&m_tooltips), m_stroke(&m_tooltips)
FontEntry::FontEntry(const bool withStrokeAndFill)
: m_style(&m_tooltips)
, m_stroke(withStrokeAndFill ? std::make_unique<FontStroke>(&m_tooltips) : nullptr)
{
m_face.setExpansive(true);
m_size.setExpansive(false);
@ -342,7 +344,8 @@ FontEntry::FontEntry() : m_style(&m_tooltips), m_stroke(&m_tooltips)
addChild(&m_face);
addChild(&m_size);
addChild(&m_style);
addChild(&m_stroke);
if (m_stroke)
addChild(m_stroke.get());
m_tooltips.addTooltipFor(&m_face, Strings::text_tool_font_family(), BOTTOM);
m_tooltips.addTooltipFor(m_size.getEntryWidget(), Strings::text_tool_font_size(), BOTTOM);
@ -367,7 +370,8 @@ FontEntry::FontEntry() : m_style(&m_tooltips), m_stroke(&m_tooltips)
});
m_style.ItemChange.connect(&FontEntry::onStyleItemClick, this);
m_stroke.Change.connect(&FontEntry::onStrokeChange, this);
if (m_stroke)
m_stroke->Change.connect(&FontEntry::onStrokeChange, this);
}
// Defined here as FontPopup type is not fully defined in the header
@ -399,22 +403,23 @@ void FontEntry::setInfo(const FontInfo& info, const From fromField)
ui::Paint FontEntry::paint()
{
ui::Paint paint;
const float stroke = m_stroke.stroke();
ui::Paint::Style style = ui::Paint::Fill;
ui::Paint::Style style = ui::Paint::StrokeAndFill;
if (m_stroke.fill()) {
if (stroke <= 0.0f)
style = ui::Paint::Fill;
else
if (m_stroke) {
const float stroke = m_stroke->stroke();
if (m_stroke->fill()) {
if (stroke > 0.0f) {
style = ui::Paint::StrokeAndFill;
paint.strokeWidth(stroke);
}
}
else {
style = ui::Paint::Stroke;
paint.strokeWidth(stroke);
}
}
paint.style(style);
return paint;
}

View File

@ -18,6 +18,7 @@
#include "ui/paint.h"
#include "ui/tooltips.h"
#include <memory>
#include <string>
namespace app {
@ -36,7 +37,7 @@ public:
Paint,
};
FontEntry();
FontEntry(bool withStrokeAndFill);
~FontEntry();
FontInfo info() { return m_info; }
@ -113,7 +114,7 @@ private:
FontFace m_face;
FontSize m_size;
FontStyle m_style;
FontStroke m_stroke;
std::unique_ptr<FontStroke> m_stroke;
bool m_lockFace = false;
};

View File

@ -532,7 +532,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const XMLElement* elem,
}
else if (elem_name == "font") {
if (!widget)
widget = new FontEntry;
widget = new FontEntry(false);
}
// Was the widget created?

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2019-2025 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
@ -20,11 +20,12 @@
#include "doc/primitives.h"
#include <algorithm>
#include <atomic>
#include <cmath>
namespace doc {
static int generation = 0;
static std::atomic<int> g_generation = 0;
Brush::Brush()
{
@ -300,7 +301,7 @@ void Brush::setCenter(const gfx::Point& center)
// Cleans the brush's data (image and region).
void Brush::clean()
{
m_gen = ++generation;
m_gen = ++g_generation;
m_image.reset();
m_maskBitmap.reset();
m_backupImage.reset();