mirror of https://github.com/aseprite/aseprite.git
Compare commits
8 Commits
83f4b2a95e
...
2ffdf04ecc
Author | SHA1 | Date |
---|---|---|
|
2ffdf04ecc | |
|
2ba051b59b | |
|
3fcb000eb1 | |
|
af9dc3c817 | |
|
250dfdc86a | |
|
c904c41b39 | |
|
9e941e9a8b | |
|
bbab4d5875 |
|
@ -356,6 +356,7 @@
|
|||
<section id="file_selector">
|
||||
<option id="current_folder" type="std::string" default=""<empty>"" />
|
||||
<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" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(); });
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
else {
|
||||
style = ui::Paint::Stroke;
|
||||
paint.strokeWidth(stroke);
|
||||
}
|
||||
}
|
||||
|
||||
paint.style(style);
|
||||
|
||||
return paint;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue