mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 03:39:51 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
04fa9a47ab
@ -127,6 +127,12 @@
|
||||
<value id="YES" value="1" />
|
||||
<value id="NO" value="2" />
|
||||
</enum>
|
||||
<enum id="Downsampling">
|
||||
<value id="NEAREST" value="0" />
|
||||
<value id="BILINEAR" value="1" />
|
||||
<value id="BILINEAR_MIPMAP" value="2" />
|
||||
<value id="TRILINEAR_MIPMAP" value="3" />
|
||||
</enum>
|
||||
</types>
|
||||
|
||||
<global>
|
||||
@ -176,6 +182,7 @@
|
||||
some performance issue rendering huge sprites with small
|
||||
zoom levels -->
|
||||
<option id="auto_fit" type="bool" default="false" />
|
||||
<option id="downsampling" type="Downsampling" default="Downsampling::BILINEAR_MIPMAP" />
|
||||
</section>
|
||||
<section id="cels">
|
||||
<option id="user_data_visibility" type="bool" default="false" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2018-2021 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018-2022 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2001-2018 David Capello -->
|
||||
<gui>
|
||||
<window id="options" text="@.title">
|
||||
@ -230,6 +230,7 @@
|
||||
pref="editor.auto_fit" />
|
||||
<check text="@.straight_line_preview" id="straight_line_preview" tooltip="@.straight_line_preview_tooltip" />
|
||||
<check text="@.discard_brush" id="discard_brush" />
|
||||
<hbox id="sampling_placeholder" />
|
||||
<hbox>
|
||||
<label text="@.right_click" />
|
||||
<combobox id="right_click_behavior" expansive="true" />
|
||||
@ -500,7 +501,8 @@
|
||||
<check id="multiple_windows" text="@.multiple_windows"
|
||||
pref="experimental.multiple_windows" />
|
||||
<hbox>
|
||||
<check text="@.new_render_engine"
|
||||
<check id="new_render_engine"
|
||||
text="@.new_render_engine"
|
||||
pref="experimental.new_render_engine" />
|
||||
<link text="(#1671)" url="https://github.com/aseprite/aseprite/issues/1671" />
|
||||
</hbox>
|
||||
|
2
laf
2
laf
@ -1 +1 @@
|
||||
Subproject commit f473cc6f8c68629ef0e8c480afbba5659ef5de75
|
||||
Subproject commit 7c819791e50116b54e0666dbf96822e0993d1d1f
|
@ -389,6 +389,7 @@ if(ENABLE_UI)
|
||||
ui/recent_listbox.cpp
|
||||
ui/resources_listbox.cpp
|
||||
ui/rgbmap_algorithm_selector.cpp
|
||||
ui/sampling_selector.cpp
|
||||
ui/search_entry.cpp
|
||||
ui/select_accelerator.cpp
|
||||
ui/selection_mode_field.cpp
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/pref_widget.h"
|
||||
#include "app/ui/rgbmap_algorithm_selector.h"
|
||||
#include "app/ui/sampling_selector.h"
|
||||
#include "app/ui/separator_in_view.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "base/clamp.h"
|
||||
@ -502,8 +503,18 @@ public:
|
||||
|
||||
showHome()->setSelected(m_pref.general.showHome());
|
||||
|
||||
// Right-click
|
||||
// Editor sampling
|
||||
samplingPlaceholder()->addChild(
|
||||
m_samplingSelector = new SamplingSelector(
|
||||
SamplingSelector::Behavior::ChangeOnSave));
|
||||
|
||||
m_samplingSelector->setEnabled(newRenderEngine()->isSelected());
|
||||
newRenderEngine()->Click.connect(
|
||||
[this]{
|
||||
m_samplingSelector->setEnabled(newRenderEngine()->isSelected());
|
||||
});
|
||||
|
||||
// Right-click
|
||||
static_assert(int(app::gen::RightClickMode::PAINT_BGCOLOR) == 0, "");
|
||||
static_assert(int(app::gen::RightClickMode::PICK_FGCOLOR) == 1, "");
|
||||
static_assert(int(app::gen::RightClickMode::ERASE) == 2, "");
|
||||
@ -671,6 +682,8 @@ public:
|
||||
m_pref.editor.straightLinePreview(straightLinePreview()->isSelected());
|
||||
m_pref.eyedropper.discardBrush(discardBrush()->isSelected());
|
||||
m_pref.editor.rightClickMode(static_cast<app::gen::RightClickMode>(rightClickBehavior()->getSelectedItemIndex()));
|
||||
if (m_samplingSelector)
|
||||
m_samplingSelector->save();
|
||||
m_pref.cursor.paintingCursorType(static_cast<app::gen::PaintingCursorType>(paintingCursorType()->getSelectedItemIndex()));
|
||||
m_pref.cursor.cursorColor(cursorColor()->getColor());
|
||||
m_pref.cursor.brushPreview(static_cast<app::gen::BrushPreview>(brushPreview()->getSelectedItemIndex()));
|
||||
@ -1731,6 +1744,7 @@ private:
|
||||
std::string m_templateTextForDisplayCS;
|
||||
RgbMapAlgorithmSelector m_rgbmapAlgorithmSelector;
|
||||
ButtonSet* m_themeVars = nullptr;
|
||||
SamplingSelector* m_samplingSelector = nullptr;
|
||||
};
|
||||
|
||||
class OptionsCommand : public Command {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -178,6 +178,7 @@ FOR_ENUM(app::gen::BgType)
|
||||
FOR_ENUM(app::gen::BrushPreview)
|
||||
FOR_ENUM(app::gen::BrushType)
|
||||
FOR_ENUM(app::gen::ColorProfileBehavior)
|
||||
FOR_ENUM(app::gen::Downsampling)
|
||||
FOR_ENUM(app::gen::EyedropperChannel)
|
||||
FOR_ENUM(app::gen::EyedropperSample)
|
||||
FOR_ENUM(app::gen::FillReferTo)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "app/ui/expr_entry.h"
|
||||
#include "app/ui/icon_button.h"
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/sampling_selector.h"
|
||||
#include "app/ui/selection_mode_field.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui_context.h"
|
||||
@ -59,6 +60,7 @@
|
||||
#include "doc/slice.h"
|
||||
#include "fmt/format.h"
|
||||
#include "obs/connection.h"
|
||||
#include "os/sampling.h"
|
||||
#include "os/surface.h"
|
||||
#include "os/system.h"
|
||||
#include "render/dithering.h"
|
||||
@ -1721,6 +1723,7 @@ ContextBar::ContextBar(TooltipManager* tooltipManager,
|
||||
m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField());
|
||||
|
||||
addChild(m_zoomButtons = new ZoomButtons);
|
||||
addChild(m_samplingSelector = new SamplingSelector);
|
||||
|
||||
addChild(m_brushBack = new BrushBackField);
|
||||
addChild(m_brushType = new BrushTypeField(this));
|
||||
@ -2032,13 +2035,6 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
||||
(activeBrush()->type() == kSquareBrushType ||
|
||||
activeBrush()->type() == kLineBrushType);
|
||||
|
||||
// True if the current tool is eyedropper.
|
||||
const bool needZoomButtons = tool &&
|
||||
(tool->getInk(0)->isZoom() ||
|
||||
tool->getInk(1)->isZoom() ||
|
||||
tool->getInk(0)->isScrollMovement() ||
|
||||
tool->getInk(1)->isScrollMovement());
|
||||
|
||||
// True if the current tool is eyedropper.
|
||||
const bool isEyedropper = tool &&
|
||||
(tool->getInk(0)->isEyedropper() ||
|
||||
@ -2091,7 +2087,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
||||
const bool supportDynamics = (!hasImageBrush);
|
||||
|
||||
// Show/Hide fields
|
||||
m_zoomButtons->setVisible(needZoomButtons);
|
||||
m_zoomButtons->setVisible(needZoomButtons(tool));
|
||||
m_brushBack->setVisible(supportOpacity && hasImageBrush && !withDithering);
|
||||
m_brushType->setVisible(supportOpacity && (!isFloodfill || (isFloodfill && hasImageBrush && !withDithering)));
|
||||
m_brushSize->setVisible(supportOpacity && !isFloodfill && !hasImageBrush);
|
||||
@ -2133,7 +2129,11 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
||||
if (updateShade)
|
||||
m_inkShades->updateShadeFromColorBarPicks();
|
||||
|
||||
layout();
|
||||
if (!updateSamplingVisibility(tool)) {
|
||||
// updateSamplingVisibility() returns false if it doesn't layout()
|
||||
// the ContextBar.
|
||||
layout();
|
||||
}
|
||||
}
|
||||
|
||||
void ContextBar::updateForMovingPixels(const Transformation& t)
|
||||
@ -2175,6 +2175,26 @@ void ContextBar::updateToolLoopModifiersIndicators(tools::ToolLoopModifiers modi
|
||||
m_selectionMode->setSelectionMode(mode);
|
||||
}
|
||||
|
||||
bool ContextBar::updateSamplingVisibility(tools::Tool* tool)
|
||||
{
|
||||
if (!tool)
|
||||
tool = App::instance()->activeTool();
|
||||
|
||||
const bool newVisibility =
|
||||
needZoomButtons(tool) &&
|
||||
current_editor &&
|
||||
(current_editor->projection().scaleX() < 1.0 ||
|
||||
current_editor->projection().scaleY() < 1.0) &&
|
||||
current_editor->isUsingNewRenderEngine();
|
||||
|
||||
if (newVisibility == m_samplingSelector->hasFlags(HIDDEN)) {
|
||||
m_samplingSelector->setVisible(newVisibility);
|
||||
layout();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ContextBar::updateAutoSelectLayer(bool state)
|
||||
{
|
||||
m_autoSelectLayer->setSelected(state);
|
||||
@ -2480,4 +2500,13 @@ void ContextBar::showDynamics()
|
||||
m_dynamics->switchPopup();
|
||||
}
|
||||
|
||||
bool ContextBar::needZoomButtons(tools::Tool* tool) const
|
||||
{
|
||||
return tool &&
|
||||
(tool->getInk(0)->isZoom() ||
|
||||
tool->getInk(1)->isZoom() ||
|
||||
tool->getInk(0)->isScrollMovement() ||
|
||||
tool->getInk(1)->isScrollMovement());
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -53,6 +53,7 @@ namespace app {
|
||||
class ColorBar;
|
||||
class DitheringSelector;
|
||||
class GradientTypeSelector;
|
||||
class SamplingSelector;
|
||||
class Transformation;
|
||||
|
||||
class ContextBar : public DocObserverWidget<ui::HBox>
|
||||
@ -68,6 +69,7 @@ namespace app {
|
||||
void updateForMovingPixels(const Transformation& t);
|
||||
void updateForSelectingBox(const std::string& text);
|
||||
void updateToolLoopModifiersIndicators(tools::ToolLoopModifiers modifiers);
|
||||
bool updateSamplingVisibility(tools::Tool* tool = nullptr);
|
||||
void updateAutoSelectLayer(bool state);
|
||||
bool isAutoSelectLayer() const;
|
||||
|
||||
@ -131,6 +133,7 @@ namespace app {
|
||||
void registerCommands();
|
||||
void showBrushes();
|
||||
void showDynamics();
|
||||
bool needZoomButtons(tools::Tool* tool) const;
|
||||
|
||||
class ZoomButtons;
|
||||
class BrushBackField;
|
||||
@ -161,6 +164,7 @@ namespace app {
|
||||
class SliceFields;
|
||||
|
||||
ZoomButtons* m_zoomButtons;
|
||||
SamplingSelector* m_samplingSelector;
|
||||
BrushBackField* m_brushBack;
|
||||
BrushTypeField* m_brushType;
|
||||
BrushAngleField* m_brushAngle;
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "doc/slice.h"
|
||||
#include "fmt/format.h"
|
||||
#include "os/color_space.h"
|
||||
#include "os/sampling.h"
|
||||
#include "os/surface.h"
|
||||
#include "os/system.h"
|
||||
#include "render/rasterize.h"
|
||||
@ -180,6 +181,10 @@ Editor::Editor(Doc* document, EditorFlags flags)
|
||||
Preferences::instance().colorBar.fgColor.AfterChange.connect(
|
||||
[this]{ onFgColorChange(); });
|
||||
|
||||
m_samplingChangeConn =
|
||||
Preferences::instance().editor.downsampling.AfterChange.connect(
|
||||
[this]{ onSamplingChange(); });
|
||||
|
||||
m_contextBarBrushChangeConn =
|
||||
App::instance()->contextBar()->BrushChange.connect(
|
||||
[this]{ onContextBarBrushChange(); });
|
||||
@ -245,6 +250,18 @@ bool Editor::isActive() const
|
||||
return (current_editor == this);
|
||||
}
|
||||
|
||||
bool Editor::isUsingNewRenderEngine() const
|
||||
{
|
||||
ASSERT(m_sprite);
|
||||
return
|
||||
(Preferences::instance().experimental.newRenderEngine()
|
||||
// Reference layers + zoom > 100% need the old render engine for
|
||||
// sub-pixel rendering.
|
||||
&& (!m_sprite->hasVisibleReferenceLayers()
|
||||
|| (m_proj.scaleX() <= 1.0
|
||||
&& m_proj.scaleY() <= 1.0)));
|
||||
}
|
||||
|
||||
// static
|
||||
WidgetType Editor::Type()
|
||||
{
|
||||
@ -454,6 +471,9 @@ void Editor::setZoom(const render::Zoom& zoom)
|
||||
if (m_proj.zoom() != zoom) {
|
||||
m_proj.setZoom(zoom);
|
||||
notifyZoomChanged();
|
||||
|
||||
if (isActive())
|
||||
App::instance()->contextBar()->updateSamplingVisibility();
|
||||
}
|
||||
else {
|
||||
// Just copy the zoom as the internal "Zoom::m_internalScale"
|
||||
@ -626,13 +646,8 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
||||
return;
|
||||
|
||||
// rc2 is the rectangle used to create a temporal rendered image of the sprite
|
||||
const bool newEngine =
|
||||
(Preferences::instance().experimental.newRenderEngine()
|
||||
// Reference layers + zoom > 100% need the old render engine for
|
||||
// sub-pixel rendering.
|
||||
&& (!m_sprite->hasVisibleReferenceLayers()
|
||||
|| (m_proj.scaleX() <= 1.0
|
||||
&& m_proj.scaleY() <= 1.0)));
|
||||
const auto& pref = Preferences::instance();
|
||||
const bool newEngine = isUsingNewRenderEngine();
|
||||
gfx::Rect rc2;
|
||||
if (newEngine) {
|
||||
rc2 = expose; // New engine, exposed rectangle (without zoom)
|
||||
@ -658,11 +673,11 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
||||
rendered.reset(Image::create(IMAGE_RGB, rc2.w, rc2.h,
|
||||
m_renderEngine->getRenderImageBuffer()));
|
||||
|
||||
m_renderEngine->setNewBlendMethod(Preferences::instance().experimental.newBlend());
|
||||
m_renderEngine->setNewBlendMethod(pref.experimental.newBlend());
|
||||
m_renderEngine->setRefLayersVisiblity(true);
|
||||
m_renderEngine->setSelectedLayer(m_layer);
|
||||
if (m_flags & Editor::kUseNonactiveLayersOpacityWhenEnabled)
|
||||
m_renderEngine->setNonactiveLayersOpacity(Preferences::instance().experimental.nonactiveLayersOpacity());
|
||||
m_renderEngine->setNonactiveLayersOpacity(pref.experimental.nonactiveLayersOpacity());
|
||||
else
|
||||
m_renderEngine->setNonactiveLayersOpacity(255);
|
||||
m_renderEngine->setProjection(
|
||||
@ -755,7 +770,30 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
||||
tmp.get(), 0, 0, 0, 0, rc2.w, rc2.h);
|
||||
|
||||
if (newEngine) {
|
||||
g->drawSurface(tmp.get(), gfx::Rect(0, 0, rc2.w, rc2.h), dest);
|
||||
os::Sampling sampling;
|
||||
if (m_proj.scaleX() < 1.0) {
|
||||
switch (pref.editor.downsampling()) {
|
||||
case gen::Downsampling::NEAREST:
|
||||
sampling = os::Sampling(os::Sampling::Filter::Nearest);
|
||||
break;
|
||||
case gen::Downsampling::BILINEAR:
|
||||
sampling = os::Sampling(os::Sampling::Filter::Linear);
|
||||
break;
|
||||
case gen::Downsampling::BILINEAR_MIPMAP:
|
||||
sampling = os::Sampling(os::Sampling::Filter::Linear,
|
||||
os::Sampling::Mipmap::Nearest);
|
||||
break;
|
||||
case gen::Downsampling::TRILINEAR_MIPMAP:
|
||||
sampling = os::Sampling(os::Sampling::Filter::Linear,
|
||||
os::Sampling::Mipmap::Linear);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g->drawSurface(tmp.get(),
|
||||
gfx::Rect(0, 0, rc2.w, rc2.h),
|
||||
dest,
|
||||
sampling);
|
||||
}
|
||||
else {
|
||||
g->blit(tmp.get(), 0, 0, dest.x, dest.y, dest.w, dest.h);
|
||||
@ -2217,6 +2255,15 @@ void Editor::onActiveToolChange(tools::Tool* tool)
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::onSamplingChange()
|
||||
{
|
||||
if (m_proj.scaleX() < 1.0 &&
|
||||
m_proj.scaleY() < 1.0 &&
|
||||
isUsingNewRenderEngine()) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::onFgColorChange()
|
||||
{
|
||||
m_brushPreview.redraw();
|
||||
|
@ -113,6 +113,7 @@ namespace app {
|
||||
static void destroyEditorSharedInternals();
|
||||
|
||||
bool isActive() const;
|
||||
bool isUsingNewRenderEngine() const;
|
||||
|
||||
DocView* getDocView() { return m_docView; }
|
||||
void setDocView(DocView* docView) { m_docView = docView; }
|
||||
@ -324,6 +325,7 @@ namespace app {
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
void onInvalidateRegion(const gfx::Region& region) override;
|
||||
void onSamplingChange();
|
||||
void onFgColorChange();
|
||||
void onContextBarBrushChange();
|
||||
void onTiledModeBeforeChange();
|
||||
@ -422,6 +424,7 @@ namespace app {
|
||||
ui::Timer m_antsTimer;
|
||||
int m_antsOffset;
|
||||
|
||||
obs::scoped_connection m_samplingChangeConn;
|
||||
obs::scoped_connection m_fgColorChangeConn;
|
||||
obs::scoped_connection m_contextBarBrushChangeConn;
|
||||
obs::scoped_connection m_showExtrasConn;
|
||||
|
54
src/app/ui/sampling_selector.cpp
Normal file
54
src/app/ui/sampling_selector.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/sampling_selector.h"
|
||||
|
||||
#include "ui/listitem.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
SamplingSelector::SamplingSelector(Behavior behavior)
|
||||
: m_behavior(behavior)
|
||||
, m_downsamplingLabel("Downsampling:")
|
||||
{
|
||||
addChild(&m_downsamplingLabel);
|
||||
addChild(&m_downsampling);
|
||||
|
||||
m_downsampling.addItem(new ListItem("Nearest"));
|
||||
m_downsampling.addItem(new ListItem("Bilinear"));
|
||||
m_downsampling.addItem(new ListItem("Bilinear mipmapping"));
|
||||
m_downsampling.addItem(new ListItem("Trilinear mipmapping"));
|
||||
m_downsampling.setSelectedItemIndex(
|
||||
(int)Preferences::instance().editor.downsampling());
|
||||
|
||||
if (m_behavior == Behavior::ChangeOnRealTime)
|
||||
m_downsampling.Change.connect([this]{ save(); });
|
||||
|
||||
m_samplingChangeConn =
|
||||
Preferences::instance().editor.downsampling.AfterChange.connect(
|
||||
[this]{ onPreferenceChange(); });
|
||||
}
|
||||
|
||||
void SamplingSelector::save()
|
||||
{
|
||||
const int i = m_downsampling.getSelectedItemIndex();
|
||||
Preferences::instance().editor.downsampling((gen::Downsampling)i);
|
||||
}
|
||||
|
||||
void SamplingSelector::onPreferenceChange()
|
||||
{
|
||||
const int i = (int)Preferences::instance().editor.downsampling();
|
||||
if (m_downsampling.getSelectedItemIndex() != i)
|
||||
m_downsampling.setSelectedItemIndex(i);
|
||||
}
|
||||
|
||||
} // namespace app
|
41
src/app/ui/sampling_selector.h
Normal file
41
src/app/ui/sampling_selector.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_UI_FILE_SELECTOR_H_INCLUDED
|
||||
#define APP_UI_FILE_SELECTOR_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/pref/preferences.h"
|
||||
#include "obs/connection.h"
|
||||
#include "ui/box.h"
|
||||
#include "ui/combobox.h"
|
||||
#include "ui/label.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class SamplingSelector : public ui::HBox {
|
||||
public:
|
||||
enum class Behavior {
|
||||
ChangeOnRealTime,
|
||||
ChangeOnSave
|
||||
};
|
||||
|
||||
SamplingSelector(Behavior behavior = Behavior::ChangeOnRealTime);
|
||||
|
||||
void save();
|
||||
|
||||
private:
|
||||
void onPreferenceChange();
|
||||
|
||||
Behavior m_behavior;
|
||||
ui::Label m_downsamplingLabel;
|
||||
ui::ComboBox m_downsampling;
|
||||
obs::scoped_connection m_samplingChangeConn;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -21,6 +21,7 @@
|
||||
#include "gfx/size.h"
|
||||
#include "os/draw_text.h"
|
||||
#include "os/font.h"
|
||||
#include "os/sampling.h"
|
||||
#include "os/surface.h"
|
||||
#include "os/system.h"
|
||||
#include "os/window.h"
|
||||
@ -271,6 +272,25 @@ void Graphics::drawSurface(os::Surface* surface,
|
||||
gfx::Rect(dstRect).offset(m_dx, m_dy));
|
||||
}
|
||||
|
||||
void Graphics::drawSurface(os::Surface* surface,
|
||||
const gfx::Rect& srcRect,
|
||||
const gfx::Rect& dstRect,
|
||||
const os::Sampling& sampling,
|
||||
const ui::Paint* paint)
|
||||
{
|
||||
dirty(gfx::Rect(m_dx+dstRect.x, m_dy+dstRect.y,
|
||||
dstRect.w, dstRect.h));
|
||||
|
||||
os::SurfaceLock lockSrc(surface);
|
||||
os::SurfaceLock lockDst(m_surface.get());
|
||||
m_surface->drawSurface(
|
||||
surface,
|
||||
srcRect,
|
||||
gfx::Rect(dstRect).offset(m_dx, m_dy),
|
||||
sampling,
|
||||
paint);
|
||||
}
|
||||
|
||||
void Graphics::drawRgbaSurface(os::Surface* surface, int x, int y)
|
||||
{
|
||||
dirty(gfx::Rect(m_dx+x, m_dy+y, surface->width(), surface->height()));
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -30,6 +30,7 @@ namespace gfx {
|
||||
|
||||
namespace os {
|
||||
class DrawTextDelegate;
|
||||
class Sampling;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
@ -92,6 +93,11 @@ namespace ui {
|
||||
void drawSurface(os::Surface* surface,
|
||||
const gfx::Rect& srcRect,
|
||||
const gfx::Rect& dstRect);
|
||||
void drawSurface(os::Surface* surface,
|
||||
const gfx::Rect& srcRect,
|
||||
const gfx::Rect& dstRect,
|
||||
const os::Sampling& sampling,
|
||||
const ui::Paint* paint = nullptr);
|
||||
void drawRgbaSurface(os::Surface* surface, int x, int y);
|
||||
void drawRgbaSurface(os::Surface* surface, int srcx, int srcy, int dstx, int dsty, int w, int h);
|
||||
void drawRgbaSurface(os::Surface* surface,
|
||||
|
Loading…
x
Reference in New Issue
Block a user