mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 03:32:48 +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) 2018-2022 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2018 David Capello
|
# 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 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
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_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)
|
if(COMMAND cmake_policy)
|
||||||
# CMP0003: Libraries linked via full path no longer produce linker search paths.
|
# 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="new_blend" type="bool" default="true" />
|
||||||
<option id="use_native_clipboard" 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_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="one_finger_as_mouse_movement" type="bool" default="true" />
|
||||||
<option id="load_wintab_driver" type="bool" default="false" />
|
<option id="load_wintab_driver" type="bool" default="false" />
|
||||||
<option id="flash_layer" 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
|
new_render_engine = New render engine for sprite editor
|
||||||
native_clipboard = Use native clipboard
|
native_clipboard = Use native clipboard
|
||||||
native_file_dialog = Use native file dialog
|
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 = Interpret one finger as mouse movement
|
||||||
one_finger_as_mouse_movement_tooltip = <<<END
|
one_finger_as_mouse_movement_tooltip = <<<END
|
||||||
Only for Windows 8/10 Pointer API: Interprets one finger as mouse movement
|
Only for Windows 8/10 Pointer API: Interprets one finger as mouse movement
|
||||||
|
@ -513,6 +513,12 @@
|
|||||||
</hbox>
|
</hbox>
|
||||||
<check id="native_clipboard" text="@.native_clipboard" />
|
<check id="native_clipboard" text="@.native_clipboard" />
|
||||||
<check id="native_file_dialog" text="@.native_file_dialog" />
|
<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">
|
<hbox id="load_wintab_driver_box">
|
||||||
<check id="load_wintab_driver2"
|
<check id="load_wintab_driver2"
|
||||||
text="@.load_wintab_driver"
|
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;
|
return nullptr;
|
||||||
|
|
||||||
// new file-item
|
// new file-item
|
||||||
FileItem* fileitem = new FileItem(nullptr);
|
auto fileitem = std::make_unique<FileItem>(nullptr);
|
||||||
fileitem->m_fullpidl = clone_pidl(fullpidl);
|
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);
|
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
|
// Get specific pidl attributes
|
||||||
if (fileitem->m_pidl &&
|
if (fileitem->m_pidl &&
|
||||||
fileitem->m_parent) {
|
fileitem->m_parent) {
|
||||||
attrib = get_pidl_attrib(fileitem, attrib);
|
attrib = get_pidl_attrib(fileitem.get(), attrib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_by_pidl(fileitem, attrib);
|
update_by_pidl(fileitem.get(), attrib);
|
||||||
put_fileitem(fileitem);
|
put_fileitem(fileitem.get());
|
||||||
|
|
||||||
//LOG("FS: fileitem %p created %s with parent %p\n", fileitem, fileitem->keyname.c_str(), fileitem->parent);
|
//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.
|
// Inserts the fileitem in the hash map of items.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2020 Igara Studio S.A.
|
// Copyright (C) 2020-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -46,7 +46,7 @@ void HttpLoader::abort()
|
|||||||
void HttpLoader::threadHttpRequest()
|
void HttpLoader::threadHttpRequest()
|
||||||
{
|
{
|
||||||
try {
|
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());
|
LOG("HTTP: Sending http request to %s\n", m_url.c_str());
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -9,6 +10,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/thread.h"
|
#include "base/thread.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
@ -30,7 +33,7 @@ namespace app {
|
|||||||
void threadHttpRequest();
|
void threadHttpRequest();
|
||||||
|
|
||||||
std::string m_url;
|
std::string m_url;
|
||||||
bool m_done;
|
std::atomic<bool> m_done;
|
||||||
net::HttpRequest* m_request;
|
net::HttpRequest* m_request;
|
||||||
base::thread m_thread;
|
base::thread m_thread;
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
|
#include "base/log.h"
|
||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
#include "ver/info.h"
|
#include "ver/info.h"
|
||||||
|
|
||||||
@ -110,6 +111,33 @@ bool Sentry::areThereCrashesToReport()
|
|||||||
return false;
|
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)
|
void Sentry::setupDirs(sentry_options_t* options)
|
||||||
{
|
{
|
||||||
// The expected handler executable name is aseprite_crashpad_handler (.exe)
|
// The expected handler executable name is aseprite_crashpad_handler (.exe)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2021 Igara Studio S.A.
|
// Copyright (C) 2021-2022 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "sentry.h"
|
#include "sentry.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -33,6 +34,10 @@ public:
|
|||||||
// the "give consent" check box for first time.
|
// the "give consent" check box for first time.
|
||||||
static bool areThereCrashesToReport();
|
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:
|
private:
|
||||||
void setupDirs(sentry_options_t* options);
|
void setupDirs(sentry_options_t* options);
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "app/color_spaces.h"
|
#include "app/color_spaces.h"
|
||||||
#include "app/color_utils.h"
|
#include "app/color_utils.h"
|
||||||
#include "app/modules/gfx.h"
|
#include "app/modules/gfx.h"
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/util/shader_helpers.h"
|
#include "app/util/shader_helpers.h"
|
||||||
@ -441,8 +442,7 @@ void ColorSelector::onPaint(ui::PaintEvent& ev)
|
|||||||
os::Surface* painterSurface = nullptr;
|
os::Surface* painterSurface = nullptr;
|
||||||
|
|
||||||
#if SK_ENABLE_SKSL // Paint with shaders
|
#if SK_ENABLE_SKSL // Paint with shaders
|
||||||
buildEffects();
|
if (buildEffects()) {
|
||||||
if (m_mainEffect && m_bottomEffect && m_alphaEffect) {
|
|
||||||
SkCanvas* canvas;
|
SkCanvas* canvas;
|
||||||
bool isSRGB;
|
bool isSRGB;
|
||||||
// TODO compare both color spaces
|
// TODO compare both color spaces
|
||||||
@ -471,6 +471,7 @@ void ColorSelector::onPaint(ui::PaintEvent& ev)
|
|||||||
SkRuntimeShaderBuilder builder1(m_mainEffect);
|
SkRuntimeShaderBuilder builder1(m_mainEffect);
|
||||||
builder1.uniform("iRes") = SkV3{float(rc2.w), float(rc2.h), 0.0f};
|
builder1.uniform("iRes") = SkV3{float(rc2.w), float(rc2.h), 0.0f};
|
||||||
builder1.uniform("iColor") = appColor_to_SkV4(m_color);
|
builder1.uniform("iColor") = appColor_to_SkV4(m_color);
|
||||||
|
setShaderMainAreaParams(builder1);
|
||||||
p.setShader(builder1.makeShader());
|
p.setShader(builder1.makeShader());
|
||||||
|
|
||||||
if (isSRGB)
|
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 (!m_mainEffect) {
|
||||||
if (const char* code = getMainAreaShader())
|
if (const char* code = getMainAreaShader())
|
||||||
m_mainEffect = buildEffect(code);
|
m_mainEffect = buildEffect(code);
|
||||||
@ -663,6 +667,8 @@ void ColorSelector::buildEffects()
|
|||||||
if (const char* code = getAlphaBarShader())
|
if (const char* code = getAlphaBarShader())
|
||||||
m_alphaEffect = buildEffect(code);
|
m_alphaEffect = buildEffect(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (m_mainEffect && m_bottomEffect && m_alphaEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkRuntimeEffect> ColorSelector::buildEffect(const char* code)
|
sk_sp<SkRuntimeEffect> ColorSelector::buildEffect(const char* code)
|
||||||
@ -677,6 +683,6 @@ sk_sp<SkRuntimeEffect> ColorSelector::buildEffect(const char* code)
|
|||||||
return result.effect;
|
return result.effect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif // SK_ENABLE_SKSL
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -70,6 +70,9 @@ namespace app {
|
|||||||
|
|
||||||
virtual const char* getMainAreaShader() { return nullptr; }
|
virtual const char* getMainAreaShader() { return nullptr; }
|
||||||
virtual const char* getBottomBarShader() { 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,
|
virtual app::Color getMainAreaColor(const int u, const int umax,
|
||||||
const int v, const int vmax) = 0;
|
const int v, const int vmax) = 0;
|
||||||
virtual app::Color getBottomBarColor(const int u, const int umax) = 0;
|
virtual app::Color getBottomBarColor(const int u, const int umax) = 0;
|
||||||
@ -112,7 +115,7 @@ namespace app {
|
|||||||
|
|
||||||
#if SK_ENABLE_SKSL
|
#if SK_ENABLE_SKSL
|
||||||
static const char* getAlphaBarShader();
|
static const char* getAlphaBarShader();
|
||||||
void buildEffects();
|
bool buildEffects();
|
||||||
sk_sp<SkRuntimeEffect> buildEffect(const char* code);
|
sk_sp<SkRuntimeEffect> buildEffect(const char* code);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
|
#include "app/util/shader_helpers.h"
|
||||||
#include "base/clamp.h"
|
#include "base/clamp.h"
|
||||||
#include "base/pi.h"
|
#include "base/pi.h"
|
||||||
#include "filters/color_curve.h"
|
|
||||||
#include "os/surface.h"
|
#include "os/surface.h"
|
||||||
#include "ui/graphics.h"
|
#include "ui/graphics.h"
|
||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
@ -67,6 +67,117 @@ ColorWheel::ColorWheel()
|
|||||||
initTheme();
|
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,
|
app::Color ColorWheel::getMainAreaColor(const int _u, const int umax,
|
||||||
const int _v, const int vmax)
|
const int _v, const int vmax)
|
||||||
{
|
{
|
||||||
@ -89,7 +200,7 @@ app::Color ColorWheel::getMainAreaColor(const int _u, const int umax,
|
|||||||
boxsize, boxsize).contains(pos)) {
|
boxsize, boxsize).contains(pos)) {
|
||||||
m_harmonyPicked = true;
|
m_harmonyPicked = true;
|
||||||
|
|
||||||
color = app::Color::fromHsv(convertHueAngle(int(color.getHsvHue()), 1),
|
color = app::Color::fromHsv(convertHueAngle(color.getHsvHue(), 1),
|
||||||
color.getHsvSaturation(),
|
color.getHsvSaturation(),
|
||||||
color.getHsvValue(),
|
color.getHsvValue(),
|
||||||
m_color.getAlpha());
|
m_color.getAlpha());
|
||||||
@ -212,7 +323,7 @@ void ColorWheel::onPaintMainArea(ui::Graphics* g, const gfx::Rect& rc)
|
|||||||
double angle = color.getHsvHue()-30.0;
|
double angle = color.getHsvHue()-30.0;
|
||||||
double dist = color.getHsvSaturation();
|
double dist = color.getHsvSaturation();
|
||||||
|
|
||||||
color = app::Color::fromHsv(convertHueAngle(int(color.getHsvHue()), 1),
|
color = app::Color::fromHsv(convertHueAngle(color.getHsvHue(), 1),
|
||||||
color.getHsvSaturation(),
|
color.getHsvSaturation(),
|
||||||
color.getHsvValue());
|
color.getHsvValue());
|
||||||
|
|
||||||
@ -347,7 +458,7 @@ app::Color ColorWheel::getColorInHarmony(int j) const
|
|||||||
{
|
{
|
||||||
int i = base::clamp((int)m_harmony, 0, (int)Harmony::LAST);
|
int i = base::clamp((int)m_harmony, 0, (int)Harmony::LAST);
|
||||||
j = base::clamp(j, 0, harmonies[i].n-1);
|
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;
|
double sat = m_color.getHsvSaturation() * harmonies[i].sats[j] / 100.0;
|
||||||
return app::Color::fromHsv(std::fmod(hue, 360),
|
return app::Color::fromHsv(std::fmod(hue, 360),
|
||||||
base::clamp(sat, 0.0, 1.0),
|
base::clamp(sat, 0.0, 1.0),
|
||||||
@ -421,51 +532,33 @@ void ColorWheel::onOptions()
|
|||||||
menu.showPopup(gfx::Point(rc.x2(), rc.y), display());
|
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) {
|
if (m_colorModel == ColorModel::RYB) {
|
||||||
|
if (dir == 1) {
|
||||||
case ColorModel::RGB:
|
// rybhue_to_rgbhue() maps:
|
||||||
return hue;
|
// [0,120) -> [0,60)
|
||||||
|
// [120,180) -> [60,120)
|
||||||
case ColorModel::RYB: {
|
// [180,240) -> [120,240)
|
||||||
static std::vector<int> map1;
|
// [240,360] -> [240,360]
|
||||||
static std::vector<int> map2;
|
if (h >= 0 && h < 120) return h / 2; // from red to yellow
|
||||||
|
else if (h < 180) return (h-60); // from yellow to green
|
||||||
if (map2.empty()) {
|
else if (h < 240) return 120 + 2*(h-180); // from green to blue
|
||||||
filters::ColorCurve curve1(filters::ColorCurve::Linear);
|
else return h; // from blue to red (same hue)
|
||||||
curve1.addPoint(gfx::Point(0, 0));
|
}
|
||||||
curve1.addPoint(gfx::Point(60, 35));
|
else {
|
||||||
curve1.addPoint(gfx::Point(122, 60));
|
// rgbhue_to_rybhue()
|
||||||
curve1.addPoint(gfx::Point(165, 120));
|
// [0,60) -> [0,120)
|
||||||
curve1.addPoint(gfx::Point(218, 180));
|
// [60,120) -> [120,180)
|
||||||
curve1.addPoint(gfx::Point(275, 240));
|
// [120,240) -> [180,240)
|
||||||
curve1.addPoint(gfx::Point(330, 300));
|
// [240,360] -> [240,360]
|
||||||
curve1.addPoint(gfx::Point(360, 360));
|
if (h >= 0 && h < 60) return 2 * h; // from red to yellow
|
||||||
|
else if (h < 120) return 60 + h; // from yellow to green
|
||||||
filters::ColorCurve curve2(filters::ColorCurve::Linear);
|
else if (h < 240) return 180 + (h-120)/2; // from green to blue
|
||||||
for (const auto& pt : curve1)
|
else return h; // from blue to red (same hue)
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return hue;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2021 Igara Studio S.A.
|
// Copyright (C) 2021-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -43,9 +43,14 @@ namespace app {
|
|||||||
void setHarmony(Harmony harmony);
|
void setHarmony(Harmony harmony);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const char* getMainAreaShader() override;
|
||||||
|
const char* getBottomBarShader() override;
|
||||||
app::Color getMainAreaColor(const int u, const int umax,
|
app::Color getMainAreaColor(const int u, const int umax,
|
||||||
const int v, const int vmax) override;
|
const int v, const int vmax) override;
|
||||||
app::Color getBottomBarColor(const int u, const int umax) 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 onPaintMainArea(ui::Graphics* g, const gfx::Rect& rc) override;
|
||||||
void onPaintBottomBar(ui::Graphics* g, const gfx::Rect& rc) override;
|
void onPaintBottomBar(ui::Graphics* g, const gfx::Rect& rc) override;
|
||||||
void onPaintSurfaceInBgThread(os::Surface* s,
|
void onPaintSurfaceInBgThread(os::Surface* s,
|
||||||
@ -65,8 +70,10 @@ namespace app {
|
|||||||
// Converts an hue angle from HSV <-> current color model hue.
|
// 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 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.
|
// 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::Rect m_wheelBounds;
|
||||||
gfx::Color m_bgColor;
|
gfx::Color m_bgColor;
|
||||||
double m_wheelRadius;
|
double m_wheelRadius;
|
||||||
|
@ -352,8 +352,8 @@ bool DrawingState::onScrollChange(Editor* editor)
|
|||||||
m_lastPointer = tools::Pointer(editor->screenToEditor(mousePos),
|
m_lastPointer = tools::Pointer(editor->screenToEditor(mousePos),
|
||||||
m_velocity.velocity(),
|
m_velocity.velocity(),
|
||||||
m_lastPointer.button(),
|
m_lastPointer.button(),
|
||||||
tools::Pointer::Type::Unknown,
|
m_lastPointer.type(),
|
||||||
0.0f);
|
m_lastPointer.pressure());
|
||||||
handleMouseMovement();
|
handleMouseMovement();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -227,9 +227,7 @@ bool ToolBar::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
MouseMessage* mouseMsg2 = new MouseMessage(
|
MouseMessage* mouseMsg2 = new MouseMessage(
|
||||||
kMouseDownMessage,
|
kMouseDownMessage,
|
||||||
mouseMsg->pointerType(),
|
*mouseMsg,
|
||||||
mouseMsg->button(),
|
|
||||||
mouseMsg->modifiers(),
|
|
||||||
mouseMsg->positionForDisplay(strip->display()));
|
mouseMsg->positionForDisplay(strip->display()));
|
||||||
mouseMsg2->setRecipient(strip);
|
mouseMsg2->setRecipient(strip);
|
||||||
mouseMsg2->setDisplay(strip->display());
|
mouseMsg2->setDisplay(strip->display());
|
||||||
@ -659,9 +657,7 @@ bool ToolBar::ToolStrip::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
MouseMessage* mouseMsg2 = new MouseMessage(
|
MouseMessage* mouseMsg2 = new MouseMessage(
|
||||||
kMouseDownMessage,
|
kMouseDownMessage,
|
||||||
mouseMsg->pointerType(),
|
*mouseMsg,
|
||||||
mouseMsg->button(),
|
|
||||||
mouseMsg->modifiers(),
|
|
||||||
mouseMsg->positionForDisplay(pick->display()));
|
mouseMsg->positionForDisplay(pick->display()));
|
||||||
mouseMsg2->setRecipient(bar);
|
mouseMsg2->setRecipient(bar);
|
||||||
mouseMsg2->setDisplay(pick->display());
|
mouseMsg2->setDisplay(pick->display());
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
|
|
||||||
#if ENABLE_SENTRY
|
#if ENABLE_SENTRY
|
||||||
#include "app/sentry_wrapper.h"
|
#include "app/sentry_wrapper.h"
|
||||||
|
#if LAF_WINDOWS
|
||||||
|
#define USE_SENTRY_BREADCRUMB_FOR_WINTAB 1
|
||||||
|
#include "os/win/wintab.h"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include "base/memory_dump.h"
|
#include "base/memory_dump.h"
|
||||||
#endif
|
#endif
|
||||||
@ -64,7 +68,31 @@ namespace {
|
|||||||
CoUninitialize();
|
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
|
#if ENABLE_SENTRY
|
||||||
sentry.init();
|
sentry.init();
|
||||||
|
#if USE_SENTRY_BREADCRUMB_FOR_WINTAB
|
||||||
|
WintabApiDelegate wintabDelegate;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
// Change the memory dump filename to save on disk (.dmp
|
// Change the memory dump filename to save on disk (.dmp
|
||||||
// file). Note: Only useful on Windows.
|
// file). Note: Only useful on Windows.
|
||||||
|
@ -536,9 +536,7 @@ bool ComboBoxEntry::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
MouseMessage mouseMsg2(
|
MouseMessage mouseMsg2(
|
||||||
kMouseDownMessage,
|
kMouseDownMessage,
|
||||||
mouseMsg->pointerType(),
|
*mouseMsg,
|
||||||
mouseMsg->button(),
|
|
||||||
mouseMsg->modifiers(),
|
|
||||||
mouseMsg->positionForDisplay(pick->display()));
|
mouseMsg->positionForDisplay(pick->display()));
|
||||||
mouseMsg2.setDisplay(pick->display());
|
mouseMsg2.setDisplay(pick->display());
|
||||||
pick->sendMessage(&mouseMsg2);
|
pick->sendMessage(&mouseMsg2);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// 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
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -97,9 +97,7 @@ bool IntEntry::onProcessMessage(Message* msg)
|
|||||||
releaseMouse();
|
releaseMouse();
|
||||||
|
|
||||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||||
mouseMsg->pointerType(),
|
*mouseMsg,
|
||||||
mouseMsg->button(),
|
|
||||||
mouseMsg->modifiers(),
|
|
||||||
mouseMsg->positionForDisplay(pick->display()));
|
mouseMsg->positionForDisplay(pick->display()));
|
||||||
mouseMsg2.setDisplay(pick->display());
|
mouseMsg2.setDisplay(pick->display());
|
||||||
pick->sendMessage(&mouseMsg2);
|
pick->sendMessage(&mouseMsg2);
|
||||||
|
@ -540,7 +540,8 @@ void Manager::generateMessagesFromOSEvents()
|
|||||||
osEvent.position(),
|
osEvent.position(),
|
||||||
m_mouseButton = mouse_button_from_os_to_ui(osEvent),
|
m_mouseButton = mouse_button_from_os_to_ui(osEvent),
|
||||||
osEvent.modifiers(),
|
osEvent.modifiers(),
|
||||||
osEvent.pointerType());
|
osEvent.pointerType(),
|
||||||
|
osEvent.pressure());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,7 +562,8 @@ void Manager::generateMessagesFromOSEvents()
|
|||||||
osEvent.position(),
|
osEvent.position(),
|
||||||
m_mouseButton = mouse_button_from_os_to_ui(osEvent),
|
m_mouseButton = mouse_button_from_os_to_ui(osEvent),
|
||||||
osEvent.modifiers(),
|
osEvent.modifiers(),
|
||||||
osEvent.pointerType());
|
osEvent.pointerType(),
|
||||||
|
osEvent.pressure());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,7 +636,8 @@ void Manager::handleMouseDown(Display* display,
|
|||||||
const gfx::Point& mousePos,
|
const gfx::Point& mousePos,
|
||||||
MouseButton mouseButton,
|
MouseButton mouseButton,
|
||||||
KeyModifiers modifiers,
|
KeyModifiers modifiers,
|
||||||
PointerType pointerType)
|
PointerType pointerType,
|
||||||
|
const float pressure)
|
||||||
{
|
{
|
||||||
handleWindowZOrder();
|
handleWindowZOrder();
|
||||||
|
|
||||||
@ -646,7 +649,10 @@ void Manager::handleMouseDown(Display* display,
|
|||||||
mousePos,
|
mousePos,
|
||||||
pointerType,
|
pointerType,
|
||||||
mouseButton,
|
mouseButton,
|
||||||
modifiers));
|
modifiers,
|
||||||
|
gfx::Point(0, 0),
|
||||||
|
false,
|
||||||
|
pressure));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::handleMouseUp(Display* display,
|
void Manager::handleMouseUp(Display* display,
|
||||||
@ -670,7 +676,8 @@ void Manager::handleMouseDoubleClick(Display* display,
|
|||||||
const gfx::Point& mousePos,
|
const gfx::Point& mousePos,
|
||||||
MouseButton mouseButton,
|
MouseButton mouseButton,
|
||||||
KeyModifiers modifiers,
|
KeyModifiers modifiers,
|
||||||
PointerType pointerType)
|
PointerType pointerType,
|
||||||
|
const float pressure)
|
||||||
{
|
{
|
||||||
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
|
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
|
||||||
if (dst) {
|
if (dst) {
|
||||||
@ -678,7 +685,9 @@ void Manager::handleMouseDoubleClick(Display* display,
|
|||||||
newMouseMessage(
|
newMouseMessage(
|
||||||
kDoubleClickMessage,
|
kDoubleClickMessage,
|
||||||
display, dst, mousePos, pointerType,
|
display, dst, mousePos, pointerType,
|
||||||
mouseButton, modifiers));
|
mouseButton, modifiers,
|
||||||
|
gfx::Point(0, 0), false,
|
||||||
|
pressure));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,8 @@ namespace ui {
|
|||||||
const gfx::Point& mousePos,
|
const gfx::Point& mousePos,
|
||||||
MouseButton mouseButton,
|
MouseButton mouseButton,
|
||||||
KeyModifiers modifiers,
|
KeyModifiers modifiers,
|
||||||
PointerType pointerType);
|
PointerType pointerType,
|
||||||
|
const float pressure);
|
||||||
void handleMouseUp(Display* display,
|
void handleMouseUp(Display* display,
|
||||||
const gfx::Point& mousePos,
|
const gfx::Point& mousePos,
|
||||||
MouseButton mouseButton,
|
MouseButton mouseButton,
|
||||||
@ -139,7 +140,8 @@ namespace ui {
|
|||||||
const gfx::Point& mousePos,
|
const gfx::Point& mousePos,
|
||||||
MouseButton mouseButton,
|
MouseButton mouseButton,
|
||||||
KeyModifiers modifiers,
|
KeyModifiers modifiers,
|
||||||
PointerType pointerType);
|
PointerType pointerType,
|
||||||
|
const float pressure);
|
||||||
void handleMouseWheel(Display* display,
|
void handleMouseWheel(Display* display,
|
||||||
const gfx::Point& mousePos,
|
const gfx::Point& mousePos,
|
||||||
KeyModifiers modifiers,
|
KeyModifiers modifiers,
|
||||||
|
@ -137,6 +137,19 @@ namespace ui {
|
|||||||
m_pressure(pressure) {
|
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; }
|
PointerType pointerType() const { return m_pointerType; }
|
||||||
MouseButton button() const { return m_button; }
|
MouseButton button() const { return m_button; }
|
||||||
bool left() const { return (m_button == kButtonLeft); }
|
bool left() const { return (m_button == kButtonLeft); }
|
||||||
|
@ -1462,9 +1462,7 @@ bool Widget::offerCapture(ui::MouseMessage* mouseMsg, int widget_type)
|
|||||||
|
|
||||||
MouseMessage* mouseMsg2 = new MouseMessage(
|
MouseMessage* mouseMsg2 = new MouseMessage(
|
||||||
kMouseDownMessage,
|
kMouseDownMessage,
|
||||||
mouseMsg->pointerType(),
|
*mouseMsg,
|
||||||
mouseMsg->button(),
|
|
||||||
mouseMsg->modifiers(),
|
|
||||||
mouseMsg->positionForDisplay(pick->display()));
|
mouseMsg->positionForDisplay(pick->display()));
|
||||||
mouseMsg2->setDisplay(pick->display());
|
mouseMsg2->setDisplay(pick->display());
|
||||||
mouseMsg2->setRecipient(pick);
|
mouseMsg2->setRecipient(pick);
|
||||||
@ -1554,11 +1552,8 @@ bool Widget::onProcessMessage(Message* msg)
|
|||||||
// Convert double clicks into mouse down
|
// Convert double clicks into mouse down
|
||||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||||
mouseMsg->pointerType(),
|
*mouseMsg,
|
||||||
mouseMsg->button(),
|
mouseMsg->position());
|
||||||
mouseMsg->modifiers(),
|
|
||||||
mouseMsg->position(),
|
|
||||||
mouseMsg->wheelDelta());
|
|
||||||
mouseMsg2.setDisplay(mouseMsg->display());
|
mouseMsg2.setDisplay(mouseMsg->display());
|
||||||
sendMessage(&mouseMsg2);
|
sendMessage(&mouseMsg2);
|
||||||
break;
|
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…
x
Reference in New Issue
Block a user