mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-16 04:13:50 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
77771b703b
@ -2,11 +2,12 @@
|
||||
# Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
# Copyright (C) 2001-2018 David Capello
|
||||
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF) # We use -std=c++17 instead of -std=gnu++17 in macOS
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
if(COMMAND cmake_policy)
|
||||
# CMP0003: Libraries linked via full path no longer produce linker search paths.
|
||||
|
@ -226,6 +226,7 @@
|
||||
<option id="new_blend" type="bool" default="true" />
|
||||
<option id="use_native_clipboard" type="bool" default="true" />
|
||||
<option id="use_native_file_dialog" type="bool" default="false" />
|
||||
<option id="use_shaders_for_color_selectors" type="bool" default="true" />
|
||||
<option id="one_finger_as_mouse_movement" type="bool" default="true" />
|
||||
<option id="load_wintab_driver" type="bool" default="false" />
|
||||
<option id="flash_layer" type="bool" default="false" />
|
||||
|
@ -1387,6 +1387,7 @@ new_blend = New layer blending method
|
||||
new_render_engine = New render engine for sprite editor
|
||||
native_clipboard = Use native clipboard
|
||||
native_file_dialog = Use native file dialog
|
||||
shaders_for_color_selectors = Use shaders for color selectors
|
||||
one_finger_as_mouse_movement = Interpret one finger as mouse movement
|
||||
one_finger_as_mouse_movement_tooltip = <<<END
|
||||
Only for Windows 8/10 Pointer API: Interprets one finger as mouse movement
|
||||
|
@ -513,6 +513,12 @@
|
||||
</hbox>
|
||||
<check id="native_clipboard" text="@.native_clipboard" />
|
||||
<check id="native_file_dialog" text="@.native_file_dialog" />
|
||||
<hbox>
|
||||
<check id="shaders_for_color_selectors"
|
||||
text="@.shaders_for_color_selectors"
|
||||
pref="experimental.use_shaders_for_color_selectors" />
|
||||
<link text="(#960)" url="https://github.com/aseprite/aseprite/issues/960" />
|
||||
</hbox>
|
||||
<hbox id="load_wintab_driver_box">
|
||||
<check id="load_wintab_driver2"
|
||||
text="@.load_wintab_driver"
|
||||
|
2
laf
2
laf
@ -1 +1 @@
|
||||
Subproject commit 8b0422877a39d655bf6a405eb2e2985763b150da
|
||||
Subproject commit 68a44741998e5a769a9b952ddb422e993dc5b6a9
|
@ -961,7 +961,7 @@ static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST fullpidl, bool create_if_
|
||||
return nullptr;
|
||||
|
||||
// new file-item
|
||||
FileItem* fileitem = new FileItem(nullptr);
|
||||
auto fileitem = std::make_unique<FileItem>(nullptr);
|
||||
fileitem->m_fullpidl = clone_pidl(fullpidl);
|
||||
|
||||
{
|
||||
@ -973,19 +973,26 @@ static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST fullpidl, bool create_if_
|
||||
|
||||
free_pidl(parent_fullpidl);
|
||||
|
||||
// The parent folder is sometimes deleted for some reasons. In
|
||||
// that case, m_parent becomes nullptr, so we cannot use it
|
||||
// anymore. Here we just return nullptr to indicate that the item
|
||||
// doesn't exist anymore.
|
||||
if (fileitem->m_parent == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// Get specific pidl attributes
|
||||
if (fileitem->m_pidl &&
|
||||
fileitem->m_parent) {
|
||||
attrib = get_pidl_attrib(fileitem, attrib);
|
||||
attrib = get_pidl_attrib(fileitem.get(), attrib);
|
||||
}
|
||||
}
|
||||
|
||||
update_by_pidl(fileitem, attrib);
|
||||
put_fileitem(fileitem);
|
||||
update_by_pidl(fileitem.get(), attrib);
|
||||
put_fileitem(fileitem.get());
|
||||
|
||||
//LOG("FS: fileitem %p created %s with parent %p\n", fileitem, fileitem->keyname.c_str(), fileitem->parent);
|
||||
|
||||
return fileitem;
|
||||
return fileitem.release();
|
||||
}
|
||||
|
||||
// Inserts the fileitem in the hash map of items.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2020 Igara Studio S.A.
|
||||
// Copyright (C) 2020-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -46,7 +46,7 @@ void HttpLoader::abort()
|
||||
void HttpLoader::threadHttpRequest()
|
||||
{
|
||||
try {
|
||||
base::ScopedValue<bool> scoped(m_done, false, true);
|
||||
base::ScopedValue<std::atomic<bool>, bool> scoped(m_done, false, true);
|
||||
|
||||
LOG("HTTP: Sending http request to %s\n", m_url.c_str());
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -9,6 +10,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/thread.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
namespace net {
|
||||
@ -30,7 +33,7 @@ namespace app {
|
||||
void threadHttpRequest();
|
||||
|
||||
std::string m_url;
|
||||
bool m_done;
|
||||
std::atomic<bool> m_done;
|
||||
net::HttpRequest* m_request;
|
||||
base::thread m_thread;
|
||||
std::string m_filename;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "app/resource_finder.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/log.h"
|
||||
#include "base/string.h"
|
||||
#include "ver/info.h"
|
||||
|
||||
@ -110,6 +111,33 @@ bool Sentry::areThereCrashesToReport()
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void Sentry::addBreadcrumb(const std::string& message)
|
||||
{
|
||||
LOG(VERBOSE, "BC: %s\n", message.c_str());
|
||||
|
||||
sentry_value_t c = sentry_value_new_breadcrumb(nullptr, message.c_str());
|
||||
sentry_add_breadcrumb(c);
|
||||
}
|
||||
|
||||
// static
|
||||
void Sentry::addBreadcrumb(const std::string& message,
|
||||
const std::map<std::string, std::string>& data)
|
||||
{
|
||||
LOG(VERBOSE, "BC: %s\n", message.c_str());
|
||||
|
||||
sentry_value_t c = sentry_value_new_breadcrumb(nullptr, message.c_str());
|
||||
sentry_value_t d = sentry_value_new_object();
|
||||
for (const auto& kv : data) {
|
||||
LOG(VERBOSE, " - [%s]=%s\n", kv.first.c_str(), kv.second.c_str());
|
||||
sentry_value_set_by_key(d,
|
||||
kv.first.c_str(),
|
||||
sentry_value_new_string(kv.second.c_str()));
|
||||
}
|
||||
sentry_value_set_by_key(c, "data", d);
|
||||
sentry_add_breadcrumb(c);
|
||||
}
|
||||
|
||||
void Sentry::setupDirs(sentry_options_t* options)
|
||||
{
|
||||
// The expected handler executable name is aseprite_crashpad_handler (.exe)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2021 Igara Studio S.A.
|
||||
// Copyright (C) 2021-2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include "sentry.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
@ -33,6 +34,10 @@ public:
|
||||
// the "give consent" check box for first time.
|
||||
static bool areThereCrashesToReport();
|
||||
|
||||
static void addBreadcrumb(const std::string& message);
|
||||
static void addBreadcrumb(const std::string& message,
|
||||
const std::map<std::string, std::string>& data);
|
||||
|
||||
private:
|
||||
void setupDirs(sentry_options_t* options);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "app/color_spaces.h"
|
||||
#include "app/color_utils.h"
|
||||
#include "app/modules/gfx.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/util/shader_helpers.h"
|
||||
@ -441,8 +442,7 @@ void ColorSelector::onPaint(ui::PaintEvent& ev)
|
||||
os::Surface* painterSurface = nullptr;
|
||||
|
||||
#if SK_ENABLE_SKSL // Paint with shaders
|
||||
buildEffects();
|
||||
if (m_mainEffect && m_bottomEffect && m_alphaEffect) {
|
||||
if (buildEffects()) {
|
||||
SkCanvas* canvas;
|
||||
bool isSRGB;
|
||||
// TODO compare both color spaces
|
||||
@ -471,6 +471,7 @@ void ColorSelector::onPaint(ui::PaintEvent& ev)
|
||||
SkRuntimeShaderBuilder builder1(m_mainEffect);
|
||||
builder1.uniform("iRes") = SkV3{float(rc2.w), float(rc2.h), 0.0f};
|
||||
builder1.uniform("iColor") = appColor_to_SkV4(m_color);
|
||||
setShaderMainAreaParams(builder1);
|
||||
p.setShader(builder1.makeShader());
|
||||
|
||||
if (isSRGB)
|
||||
@ -647,8 +648,11 @@ half4 main(vec2 fragcoord) {
|
||||
)";
|
||||
}
|
||||
|
||||
void ColorSelector::buildEffects()
|
||||
bool ColorSelector::buildEffects()
|
||||
{
|
||||
if (!Preferences::instance().experimental.useShadersForColorSelectors())
|
||||
return false;
|
||||
|
||||
if (!m_mainEffect) {
|
||||
if (const char* code = getMainAreaShader())
|
||||
m_mainEffect = buildEffect(code);
|
||||
@ -663,6 +667,8 @@ void ColorSelector::buildEffects()
|
||||
if (const char* code = getAlphaBarShader())
|
||||
m_alphaEffect = buildEffect(code);
|
||||
}
|
||||
|
||||
return (m_mainEffect && m_bottomEffect && m_alphaEffect);
|
||||
}
|
||||
|
||||
sk_sp<SkRuntimeEffect> ColorSelector::buildEffect(const char* code)
|
||||
@ -677,6 +683,6 @@ sk_sp<SkRuntimeEffect> ColorSelector::buildEffect(const char* code)
|
||||
return result.effect;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // SK_ENABLE_SKSL
|
||||
|
||||
} // namespace app
|
||||
|
@ -70,6 +70,9 @@ namespace app {
|
||||
|
||||
virtual const char* getMainAreaShader() { return nullptr; }
|
||||
virtual const char* getBottomBarShader() { return nullptr; }
|
||||
#if SK_ENABLE_SKSL
|
||||
virtual void setShaderMainAreaParams(SkRuntimeShaderBuilder& builder) { }
|
||||
#endif
|
||||
virtual app::Color getMainAreaColor(const int u, const int umax,
|
||||
const int v, const int vmax) = 0;
|
||||
virtual app::Color getBottomBarColor(const int u, const int umax) = 0;
|
||||
@ -112,7 +115,7 @@ namespace app {
|
||||
|
||||
#if SK_ENABLE_SKSL
|
||||
static const char* getAlphaBarShader();
|
||||
void buildEffects();
|
||||
bool buildEffects();
|
||||
sk_sp<SkRuntimeEffect> buildEffect(const char* code);
|
||||
#endif
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/util/shader_helpers.h"
|
||||
#include "base/clamp.h"
|
||||
#include "base/pi.h"
|
||||
#include "filters/color_curve.h"
|
||||
#include "os/surface.h"
|
||||
#include "ui/graphics.h"
|
||||
#include "ui/menu.h"
|
||||
@ -67,6 +67,117 @@ ColorWheel::ColorWheel()
|
||||
initTheme();
|
||||
}
|
||||
|
||||
const char* ColorWheel::getMainAreaShader()
|
||||
{
|
||||
#if SK_ENABLE_SKSL
|
||||
// TODO create one shader for each wheel mode (RGB, RYB, normal)
|
||||
if (m_mainShader.empty()) {
|
||||
m_mainShader += "uniform half3 iRes;"
|
||||
"uniform half4 iColor;"
|
||||
"uniform half4 iBack;"
|
||||
"uniform int iDiscrete;"
|
||||
"uniform int iMode;";
|
||||
m_mainShader += kRGB_to_HSV_sksl;
|
||||
m_mainShader += kHSV_to_RGB_sksl;
|
||||
m_mainShader += R"(
|
||||
const half PI = 3.1415;
|
||||
|
||||
half rybhue_to_rgbhue(half h) {
|
||||
if (h >= 0 && h < 120) return h / 2; // from red to yellow
|
||||
else if (h < 180) return (h-60.0); // from yellow to green
|
||||
else if (h < 240) return 120 + 2*(h-180); // from green to blue
|
||||
else return h; // from blue to red (same hue)
|
||||
}
|
||||
|
||||
half4 main(vec2 fragcoord) {
|
||||
vec2 res = vec2(min(iRes.x, iRes.y), min(iRes.x, iRes.y));
|
||||
vec2 d = (fragcoord.xy-iRes.xy/2) / res.xy;
|
||||
half r = length(d);
|
||||
|
||||
if (r <= 0.5) {
|
||||
half a = atan(-d.y, d.x);
|
||||
half hue = (floor(180.0 * a / PI)
|
||||
+ 180 // To avoid [-180,0) range
|
||||
+ 180 + 30 // To locate green at 12 o'clock
|
||||
);
|
||||
|
||||
hue = mod(hue, 360); // To leave hue in [0,360) range
|
||||
if (iDiscrete != 0) {
|
||||
hue += 15.0;
|
||||
hue = floor(hue / 30.0);
|
||||
hue *= 30.0;
|
||||
}
|
||||
if (iMode == 1) { // RYB color wheel
|
||||
hue = rybhue_to_rgbhue(hue);
|
||||
}
|
||||
hue /= 360.0;
|
||||
|
||||
if (iMode == 2) { // Normal map mode
|
||||
float di = 0.5 * r / 0.5;
|
||||
half3 rgb = half3(0.5+di*cos(a), 0.5+di*sin(a), 1.0-di);
|
||||
return half4(
|
||||
clamp(rgb.x, 0, 1),
|
||||
clamp(rgb.y, 0, 1),
|
||||
clamp(rgb.z, 0.5, 1), 1);
|
||||
}
|
||||
|
||||
half sat = r / 0.5;
|
||||
if (iDiscrete != 0) {
|
||||
sat *= 120.0;
|
||||
sat = floor(sat / 20.0);
|
||||
sat *= 20.0;
|
||||
sat /= 100.0;
|
||||
sat = clamp(sat, 0.0, 1.0);
|
||||
}
|
||||
vec3 hsv = rgb_to_hsv(iColor.rgb);
|
||||
return hsv_to_rgb(vec3(hue, sat, iColor.w > 0 ? hsv.z: 1.0)).rgb1;
|
||||
}
|
||||
else {
|
||||
if (iMode == 2) // Normal map mode
|
||||
return half4(0.5, 0.5, 1, 1);
|
||||
return iBack;
|
||||
}
|
||||
}
|
||||
)";
|
||||
}
|
||||
return m_mainShader.c_str();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* ColorWheel::getBottomBarShader()
|
||||
{
|
||||
#if SK_ENABLE_SKSL
|
||||
if (m_bottomShader.empty()) {
|
||||
m_bottomShader += "uniform half3 iRes;"
|
||||
"uniform half4 iColor;";
|
||||
m_bottomShader += kRGB_to_HSV_sksl;
|
||||
m_bottomShader += kHSV_to_RGB_sksl;
|
||||
// TODO should we display the hue bar with the current sat/value?
|
||||
m_bottomShader += R"(
|
||||
half4 main(vec2 fragcoord) {
|
||||
half v = (fragcoord.x / iRes.x);
|
||||
half3 hsv = rgb_to_hsv(iColor.rgb);
|
||||
return hsv_to_rgb(half3(hsv.x, hsv.y, v)).rgb1;
|
||||
}
|
||||
)";
|
||||
}
|
||||
return m_bottomShader.c_str();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SK_ENABLE_SKSL
|
||||
void ColorWheel::setShaderMainAreaParams(SkRuntimeShaderBuilder& builder)
|
||||
{
|
||||
builder.uniform("iBack") = gfxColor_to_SkV4(m_bgColor);
|
||||
builder.uniform("iDiscrete") = (m_discrete ? 1: 0);
|
||||
builder.uniform("iMode") = int(m_colorModel);
|
||||
}
|
||||
#endif
|
||||
|
||||
app::Color ColorWheel::getMainAreaColor(const int _u, const int umax,
|
||||
const int _v, const int vmax)
|
||||
{
|
||||
@ -89,7 +200,7 @@ app::Color ColorWheel::getMainAreaColor(const int _u, const int umax,
|
||||
boxsize, boxsize).contains(pos)) {
|
||||
m_harmonyPicked = true;
|
||||
|
||||
color = app::Color::fromHsv(convertHueAngle(int(color.getHsvHue()), 1),
|
||||
color = app::Color::fromHsv(convertHueAngle(color.getHsvHue(), 1),
|
||||
color.getHsvSaturation(),
|
||||
color.getHsvValue(),
|
||||
m_color.getAlpha());
|
||||
@ -212,7 +323,7 @@ void ColorWheel::onPaintMainArea(ui::Graphics* g, const gfx::Rect& rc)
|
||||
double angle = color.getHsvHue()-30.0;
|
||||
double dist = color.getHsvSaturation();
|
||||
|
||||
color = app::Color::fromHsv(convertHueAngle(int(color.getHsvHue()), 1),
|
||||
color = app::Color::fromHsv(convertHueAngle(color.getHsvHue(), 1),
|
||||
color.getHsvSaturation(),
|
||||
color.getHsvValue());
|
||||
|
||||
@ -347,7 +458,7 @@ app::Color ColorWheel::getColorInHarmony(int j) const
|
||||
{
|
||||
int i = base::clamp((int)m_harmony, 0, (int)Harmony::LAST);
|
||||
j = base::clamp(j, 0, harmonies[i].n-1);
|
||||
double hue = convertHueAngle(int(m_color.getHsvHue()), -1) + harmonies[i].hues[j];
|
||||
double hue = convertHueAngle(m_color.getHsvHue(), -1) + harmonies[i].hues[j];
|
||||
double sat = m_color.getHsvSaturation() * harmonies[i].sats[j] / 100.0;
|
||||
return app::Color::fromHsv(std::fmod(hue, 360),
|
||||
base::clamp(sat, 0.0, 1.0),
|
||||
@ -421,51 +532,33 @@ void ColorWheel::onOptions()
|
||||
menu.showPopup(gfx::Point(rc.x2(), rc.y), display());
|
||||
}
|
||||
|
||||
int ColorWheel::convertHueAngle(int hue, int dir) const
|
||||
float ColorWheel::convertHueAngle(float h, int dir) const
|
||||
{
|
||||
switch (m_colorModel) {
|
||||
|
||||
case ColorModel::RGB:
|
||||
return hue;
|
||||
|
||||
case ColorModel::RYB: {
|
||||
static std::vector<int> map1;
|
||||
static std::vector<int> map2;
|
||||
|
||||
if (map2.empty()) {
|
||||
filters::ColorCurve curve1(filters::ColorCurve::Linear);
|
||||
curve1.addPoint(gfx::Point(0, 0));
|
||||
curve1.addPoint(gfx::Point(60, 35));
|
||||
curve1.addPoint(gfx::Point(122, 60));
|
||||
curve1.addPoint(gfx::Point(165, 120));
|
||||
curve1.addPoint(gfx::Point(218, 180));
|
||||
curve1.addPoint(gfx::Point(275, 240));
|
||||
curve1.addPoint(gfx::Point(330, 300));
|
||||
curve1.addPoint(gfx::Point(360, 360));
|
||||
|
||||
filters::ColorCurve curve2(filters::ColorCurve::Linear);
|
||||
for (const auto& pt : curve1)
|
||||
curve2.addPoint(gfx::Point(pt.y, pt.x));
|
||||
|
||||
map1.resize(360);
|
||||
map2.resize(360);
|
||||
curve1.getValues(0, 359, map1);
|
||||
curve2.getValues(0, 359, map2);
|
||||
}
|
||||
|
||||
if (hue < 0)
|
||||
hue += 360;
|
||||
hue %= 360;
|
||||
|
||||
ASSERT(hue >= 0 && hue < 360);
|
||||
if (dir > 0)
|
||||
return map1[hue];
|
||||
else if (dir < 0)
|
||||
return map2[hue];
|
||||
if (m_colorModel == ColorModel::RYB) {
|
||||
if (dir == 1) {
|
||||
// rybhue_to_rgbhue() maps:
|
||||
// [0,120) -> [0,60)
|
||||
// [120,180) -> [60,120)
|
||||
// [180,240) -> [120,240)
|
||||
// [240,360] -> [240,360]
|
||||
if (h >= 0 && h < 120) return h / 2; // from red to yellow
|
||||
else if (h < 180) return (h-60); // from yellow to green
|
||||
else if (h < 240) return 120 + 2*(h-180); // from green to blue
|
||||
else return h; // from blue to red (same hue)
|
||||
}
|
||||
else {
|
||||
// rgbhue_to_rybhue()
|
||||
// [0,60) -> [0,120)
|
||||
// [60,120) -> [120,180)
|
||||
// [120,240) -> [180,240)
|
||||
// [240,360] -> [240,360]
|
||||
if (h >= 0 && h < 60) return 2 * h; // from red to yellow
|
||||
else if (h < 120) return 60 + h; // from yellow to green
|
||||
else if (h < 240) return 180 + (h-120)/2; // from green to blue
|
||||
else return h; // from blue to red (same hue)
|
||||
}
|
||||
|
||||
}
|
||||
return hue;
|
||||
return h;
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2021 Igara Studio S.A.
|
||||
// Copyright (C) 2021-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -43,9 +43,14 @@ namespace app {
|
||||
void setHarmony(Harmony harmony);
|
||||
|
||||
protected:
|
||||
const char* getMainAreaShader() override;
|
||||
const char* getBottomBarShader() override;
|
||||
app::Color getMainAreaColor(const int u, const int umax,
|
||||
const int v, const int vmax) override;
|
||||
app::Color getBottomBarColor(const int u, const int umax) override;
|
||||
#if SK_ENABLE_SKSL
|
||||
void setShaderMainAreaParams(SkRuntimeShaderBuilder& builder) override;
|
||||
#endif
|
||||
void onPaintMainArea(ui::Graphics* g, const gfx::Rect& rc) override;
|
||||
void onPaintBottomBar(ui::Graphics* g, const gfx::Rect& rc) override;
|
||||
void onPaintSurfaceInBgThread(os::Surface* s,
|
||||
@ -65,8 +70,10 @@ namespace app {
|
||||
// Converts an hue angle from HSV <-> current color model hue.
|
||||
// With dir == +1, the angle is from the color model and it's converted to HSV hue.
|
||||
// With dir == -1, the angle came from HSV and is converted to the current color model.
|
||||
int convertHueAngle(int angle, int dir) const;
|
||||
float convertHueAngle(float angle, int dir) const;
|
||||
|
||||
std::string m_mainShader;
|
||||
std::string m_bottomShader;
|
||||
gfx::Rect m_wheelBounds;
|
||||
gfx::Color m_bgColor;
|
||||
double m_wheelRadius;
|
||||
|
@ -352,8 +352,8 @@ bool DrawingState::onScrollChange(Editor* editor)
|
||||
m_lastPointer = tools::Pointer(editor->screenToEditor(mousePos),
|
||||
m_velocity.velocity(),
|
||||
m_lastPointer.button(),
|
||||
tools::Pointer::Type::Unknown,
|
||||
0.0f);
|
||||
m_lastPointer.type(),
|
||||
m_lastPointer.pressure());
|
||||
handleMouseMovement();
|
||||
}
|
||||
return true;
|
||||
|
@ -227,9 +227,7 @@ bool ToolBar::onProcessMessage(Message* msg)
|
||||
|
||||
MouseMessage* mouseMsg2 = new MouseMessage(
|
||||
kMouseDownMessage,
|
||||
mouseMsg->pointerType(),
|
||||
mouseMsg->button(),
|
||||
mouseMsg->modifiers(),
|
||||
*mouseMsg,
|
||||
mouseMsg->positionForDisplay(strip->display()));
|
||||
mouseMsg2->setRecipient(strip);
|
||||
mouseMsg2->setDisplay(strip->display());
|
||||
@ -659,9 +657,7 @@ bool ToolBar::ToolStrip::onProcessMessage(Message* msg)
|
||||
|
||||
MouseMessage* mouseMsg2 = new MouseMessage(
|
||||
kMouseDownMessage,
|
||||
mouseMsg->pointerType(),
|
||||
mouseMsg->button(),
|
||||
mouseMsg->modifiers(),
|
||||
*mouseMsg,
|
||||
mouseMsg->positionForDisplay(pick->display()));
|
||||
mouseMsg2->setRecipient(bar);
|
||||
mouseMsg2->setDisplay(pick->display());
|
||||
|
@ -24,6 +24,10 @@
|
||||
|
||||
#if ENABLE_SENTRY
|
||||
#include "app/sentry_wrapper.h"
|
||||
#if LAF_WINDOWS
|
||||
#define USE_SENTRY_BREADCRUMB_FOR_WINTAB 1
|
||||
#include "os/win/wintab.h"
|
||||
#endif
|
||||
#else
|
||||
#include "base/memory_dump.h"
|
||||
#endif
|
||||
@ -64,7 +68,31 @@ namespace {
|
||||
CoUninitialize();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif // LAF_WINDOWS
|
||||
|
||||
#if USE_SENTRY_BREADCRUMB_FOR_WINTAB
|
||||
// Delegate to write Wintab information as a Sentry breadcrumb (to
|
||||
// know if there is a specific Wintab driver giving problems)
|
||||
class WintabApiDelegate : public os::WintabAPI::Delegate {
|
||||
bool m_done = false;
|
||||
public:
|
||||
WintabApiDelegate() {
|
||||
os::instance()->setWintabDelegate(this);
|
||||
}
|
||||
~WintabApiDelegate() {
|
||||
os::instance()->setWintabDelegate(nullptr);
|
||||
}
|
||||
void onWintabID(const std::string& id) override {
|
||||
if (!m_done) {
|
||||
m_done = true;
|
||||
app::Sentry::addBreadcrumb("Wintab ID=" + id);
|
||||
}
|
||||
}
|
||||
void onWintabFields(const std::map<std::string, std::string>& fields) override {
|
||||
app::Sentry::addBreadcrumb("Wintab DLL", fields);
|
||||
}
|
||||
};
|
||||
#endif // USE_SENTRY_BREADCRUMB_FOR_WINTAB
|
||||
|
||||
}
|
||||
|
||||
@ -99,6 +127,9 @@ int app_main(int argc, char* argv[])
|
||||
|
||||
#if ENABLE_SENTRY
|
||||
sentry.init();
|
||||
#if USE_SENTRY_BREADCRUMB_FOR_WINTAB
|
||||
WintabApiDelegate wintabDelegate;
|
||||
#endif
|
||||
#else
|
||||
// Change the memory dump filename to save on disk (.dmp
|
||||
// file). Note: Only useful on Windows.
|
||||
|
@ -536,9 +536,7 @@ bool ComboBoxEntry::onProcessMessage(Message* msg)
|
||||
|
||||
MouseMessage mouseMsg2(
|
||||
kMouseDownMessage,
|
||||
mouseMsg->pointerType(),
|
||||
mouseMsg->button(),
|
||||
mouseMsg->modifiers(),
|
||||
*mouseMsg,
|
||||
mouseMsg->positionForDisplay(pick->display()));
|
||||
mouseMsg2.setDisplay(pick->display());
|
||||
pick->sendMessage(&mouseMsg2);
|
||||
|
@ -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-2017 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -97,9 +97,7 @@ bool IntEntry::onProcessMessage(Message* msg)
|
||||
releaseMouse();
|
||||
|
||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||
mouseMsg->pointerType(),
|
||||
mouseMsg->button(),
|
||||
mouseMsg->modifiers(),
|
||||
*mouseMsg,
|
||||
mouseMsg->positionForDisplay(pick->display()));
|
||||
mouseMsg2.setDisplay(pick->display());
|
||||
pick->sendMessage(&mouseMsg2);
|
||||
|
@ -540,7 +540,8 @@ void Manager::generateMessagesFromOSEvents()
|
||||
osEvent.position(),
|
||||
m_mouseButton = mouse_button_from_os_to_ui(osEvent),
|
||||
osEvent.modifiers(),
|
||||
osEvent.pointerType());
|
||||
osEvent.pointerType(),
|
||||
osEvent.pressure());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -561,7 +562,8 @@ void Manager::generateMessagesFromOSEvents()
|
||||
osEvent.position(),
|
||||
m_mouseButton = mouse_button_from_os_to_ui(osEvent),
|
||||
osEvent.modifiers(),
|
||||
osEvent.pointerType());
|
||||
osEvent.pointerType(),
|
||||
osEvent.pressure());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -634,7 +636,8 @@ void Manager::handleMouseDown(Display* display,
|
||||
const gfx::Point& mousePos,
|
||||
MouseButton mouseButton,
|
||||
KeyModifiers modifiers,
|
||||
PointerType pointerType)
|
||||
PointerType pointerType,
|
||||
const float pressure)
|
||||
{
|
||||
handleWindowZOrder();
|
||||
|
||||
@ -646,7 +649,10 @@ void Manager::handleMouseDown(Display* display,
|
||||
mousePos,
|
||||
pointerType,
|
||||
mouseButton,
|
||||
modifiers));
|
||||
modifiers,
|
||||
gfx::Point(0, 0),
|
||||
false,
|
||||
pressure));
|
||||
}
|
||||
|
||||
void Manager::handleMouseUp(Display* display,
|
||||
@ -670,7 +676,8 @@ void Manager::handleMouseDoubleClick(Display* display,
|
||||
const gfx::Point& mousePos,
|
||||
MouseButton mouseButton,
|
||||
KeyModifiers modifiers,
|
||||
PointerType pointerType)
|
||||
PointerType pointerType,
|
||||
const float pressure)
|
||||
{
|
||||
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
|
||||
if (dst) {
|
||||
@ -678,7 +685,9 @@ void Manager::handleMouseDoubleClick(Display* display,
|
||||
newMouseMessage(
|
||||
kDoubleClickMessage,
|
||||
display, dst, mousePos, pointerType,
|
||||
mouseButton, modifiers));
|
||||
mouseButton, modifiers,
|
||||
gfx::Point(0, 0), false,
|
||||
pressure));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,8 @@ namespace ui {
|
||||
const gfx::Point& mousePos,
|
||||
MouseButton mouseButton,
|
||||
KeyModifiers modifiers,
|
||||
PointerType pointerType);
|
||||
PointerType pointerType,
|
||||
const float pressure);
|
||||
void handleMouseUp(Display* display,
|
||||
const gfx::Point& mousePos,
|
||||
MouseButton mouseButton,
|
||||
@ -139,7 +140,8 @@ namespace ui {
|
||||
const gfx::Point& mousePos,
|
||||
MouseButton mouseButton,
|
||||
KeyModifiers modifiers,
|
||||
PointerType pointerType);
|
||||
PointerType pointerType,
|
||||
const float pressure);
|
||||
void handleMouseWheel(Display* display,
|
||||
const gfx::Point& mousePos,
|
||||
KeyModifiers modifiers,
|
||||
|
@ -137,6 +137,19 @@ namespace ui {
|
||||
m_pressure(pressure) {
|
||||
}
|
||||
|
||||
// Copy other MouseMessage converting its type
|
||||
MouseMessage(MessageType type,
|
||||
const MouseMessage& other,
|
||||
const gfx::Point& newPosition)
|
||||
: Message(type, other.modifiers()),
|
||||
m_pointerType(other.pointerType()),
|
||||
m_button(other.button()),
|
||||
m_pos(newPosition),
|
||||
m_wheelDelta(other.wheelDelta()),
|
||||
m_preciseWheel(other.preciseWheel()),
|
||||
m_pressure(other.pressure()) {
|
||||
}
|
||||
|
||||
PointerType pointerType() const { return m_pointerType; }
|
||||
MouseButton button() const { return m_button; }
|
||||
bool left() const { return (m_button == kButtonLeft); }
|
||||
|
@ -1462,9 +1462,7 @@ bool Widget::offerCapture(ui::MouseMessage* mouseMsg, int widget_type)
|
||||
|
||||
MouseMessage* mouseMsg2 = new MouseMessage(
|
||||
kMouseDownMessage,
|
||||
mouseMsg->pointerType(),
|
||||
mouseMsg->button(),
|
||||
mouseMsg->modifiers(),
|
||||
*mouseMsg,
|
||||
mouseMsg->positionForDisplay(pick->display()));
|
||||
mouseMsg2->setDisplay(pick->display());
|
||||
mouseMsg2->setRecipient(pick);
|
||||
@ -1554,11 +1552,8 @@ bool Widget::onProcessMessage(Message* msg)
|
||||
// Convert double clicks into mouse down
|
||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||
mouseMsg->pointerType(),
|
||||
mouseMsg->button(),
|
||||
mouseMsg->modifiers(),
|
||||
mouseMsg->position(),
|
||||
mouseMsg->wheelDelta());
|
||||
*mouseMsg,
|
||||
mouseMsg->position());
|
||||
mouseMsg2.setDisplay(mouseMsg->display());
|
||||
sendMessage(&mouseMsg2);
|
||||
break;
|
||||
|
2
third_party/harfbuzz
vendored
2
third_party/harfbuzz
vendored
@ -1 +1 @@
|
||||
Subproject commit a52c6df38a38c4e36ff991dfb4b7d92e48a44553
|
||||
Subproject commit 3412c32b35db911832c0b396894203899f8f5157
|
2
third_party/pixman
vendored
2
third_party/pixman
vendored
@ -1 +1 @@
|
||||
Subproject commit eb0dfaa0c6eb54ca9f8a6d8bf63d346c0fc4f2b9
|
||||
Subproject commit 285b9a907caffeb979322e629d4e57aa42061b5a
|
Loading…
Reference in New Issue
Block a user