mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 15:32:38 +00:00
Introduce AlphaEntry class and make InkOpacityField extend from it (fix #1544)
This commit is contained in:
parent
dd0e5addc9
commit
b10390625f
@ -336,6 +336,7 @@ if(ENABLE_UI)
|
|||||||
file_selector.cpp
|
file_selector.cpp
|
||||||
modules/gfx.cpp
|
modules/gfx.cpp
|
||||||
modules/gui.cpp
|
modules/gui.cpp
|
||||||
|
ui/alpha_entry.cpp
|
||||||
ui/alpha_slider.cpp
|
ui/alpha_slider.cpp
|
||||||
ui/app_menuitem.cpp
|
ui/app_menuitem.cpp
|
||||||
ui/backup_indicator.cpp
|
ui/backup_indicator.cpp
|
||||||
|
67
src/app/ui/alpha_entry.cpp
Normal file
67
src/app/ui/alpha_entry.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Aseprite UI Library
|
||||||
|
// Copyright (C) 2024 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/ui/alpha_entry.h"
|
||||||
|
#include "base/scoped_value.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
#include "gfx/region.h"
|
||||||
|
#include "os/font.h"
|
||||||
|
#include "ui/fit_bounds.h"
|
||||||
|
#include "ui/manager.h"
|
||||||
|
#include "ui/message.h"
|
||||||
|
#include "ui/popup_window.h"
|
||||||
|
#include "ui/scale.h"
|
||||||
|
#include "ui/size_hint_event.h"
|
||||||
|
#include "ui/slider.h"
|
||||||
|
#include "ui/system.h"
|
||||||
|
#include "ui/theme.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
using namespace gfx;
|
||||||
|
|
||||||
|
AlphaEntry::AlphaEntry(AlphaSlider::Type type)
|
||||||
|
: IntEntry(0, 255)
|
||||||
|
{
|
||||||
|
m_slider = std::make_unique<AlphaSlider>(0, type);
|
||||||
|
m_slider->setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
||||||
|
m_slider->setTransparent(true);
|
||||||
|
m_slider->Change.connect([this] { this->onChangeSlider(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
int AlphaEntry::getValue() const
|
||||||
|
{
|
||||||
|
int value = m_slider->convertTextToValue(text());
|
||||||
|
if (static_cast<AlphaSlider*>(m_slider.get())->getAlphaRange() == app::gen::AlphaRange::PERCENTAGE)
|
||||||
|
value = std::round(((double)m_slider->getMaxValue())*((double)value)/((double)100));
|
||||||
|
|
||||||
|
return std::clamp(value, m_min, m_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlphaEntry::setValue(int value)
|
||||||
|
{
|
||||||
|
value = std::clamp(value, m_min, m_max);
|
||||||
|
|
||||||
|
if (m_popupWindow && !m_changeFromSlider)
|
||||||
|
m_slider->setValue(value);
|
||||||
|
|
||||||
|
if (static_cast<AlphaSlider*>(m_slider.get())->getAlphaRange() == app::gen::AlphaRange::PERCENTAGE)
|
||||||
|
value = std::round(((double)100)*((double)value)/((double)m_slider->getMaxValue()));
|
||||||
|
|
||||||
|
setText(m_slider->convertValueToText(value));
|
||||||
|
|
||||||
|
onValueChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
36
src/app/ui/alpha_entry.h
Normal file
36
src/app/ui/alpha_entry.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Aseprite UI Library
|
||||||
|
// Copyright (C) 2024 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifndef APP_UI_ALPHA_ENTRY_H_INCLUDED
|
||||||
|
#define APP_UI_ALPHA_ENTRY_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/int_entry.h"
|
||||||
|
#include "app/ui/alpha_slider.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace ui;
|
||||||
|
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class CloseEvent;
|
||||||
|
class PopupWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
class AlphaEntry : public IntEntry {
|
||||||
|
public:
|
||||||
|
AlphaEntry(AlphaSlider::Type type);
|
||||||
|
|
||||||
|
int getValue() const override;
|
||||||
|
void setValue(int value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
|
||||||
|
#endif
|
@ -34,6 +34,7 @@
|
|||||||
#include "app/tools/tool.h"
|
#include "app/tools/tool.h"
|
||||||
#include "app/tools/tool_box.h"
|
#include "app/tools/tool_box.h"
|
||||||
#include "app/tools/tool_loop_modifiers.h"
|
#include "app/tools/tool_loop_modifiers.h"
|
||||||
|
#include "app/ui/alpha_entry.h"
|
||||||
#include "app/ui/brush_popup.h"
|
#include "app/ui/brush_popup.h"
|
||||||
#include "app/ui/button_set.h"
|
#include "app/ui/button_set.h"
|
||||||
#include "app/ui/color_button.h"
|
#include "app/ui/color_button.h"
|
||||||
@ -710,9 +711,9 @@ private:
|
|||||||
obs::scoped_connection m_conn;
|
obs::scoped_connection m_conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContextBar::InkOpacityField : public IntEntry {
|
class ContextBar::InkOpacityField : public AlphaEntry {
|
||||||
public:
|
public:
|
||||||
InkOpacityField() : IntEntry(0, 255) {
|
InkOpacityField() : AlphaEntry(AlphaSlider::Type::OPACITY) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -720,7 +721,7 @@ protected:
|
|||||||
if (g_updatingFromCode)
|
if (g_updatingFromCode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IntEntry::onValueChange();
|
AlphaEntry::onValueChange();
|
||||||
base::ScopedValue lockFlag(g_updatingFromCode, true);
|
base::ScopedValue lockFlag(g_updatingFromCode, true);
|
||||||
|
|
||||||
int newValue = getValue();
|
int newValue = getValue();
|
||||||
@ -1914,6 +1915,8 @@ ContextBar::ContextBar(TooltipManager* tooltipManager,
|
|||||||
[this]{ onFgOrBgColorChange(doc::Brush::ImageColor::MainColor); });
|
[this]{ onFgOrBgColorChange(doc::Brush::ImageColor::MainColor); });
|
||||||
m_bgColorConn = pref.colorBar.bgColor.AfterChange.connect(
|
m_bgColorConn = pref.colorBar.bgColor.AfterChange.connect(
|
||||||
[this]{ onFgOrBgColorChange(doc::Brush::ImageColor::BackgroundColor); });
|
[this]{ onFgOrBgColorChange(doc::Brush::ImageColor::BackgroundColor); });
|
||||||
|
m_alphaRangeConn = pref.range.opacity.AfterChange.connect(
|
||||||
|
[this]{ onOpacityRangeChange(); });
|
||||||
m_keysConn = KeyboardShortcuts::instance()->UserChange.connect(
|
m_keysConn = KeyboardShortcuts::instance()->UserChange.connect(
|
||||||
[this, tooltipManager]{ setupTooltips(tooltipManager); });
|
[this, tooltipManager]{ setupTooltips(tooltipManager); });
|
||||||
m_dropPixelsConn = m_dropPixels->DropPixels.connect(&ContextBar::onDropPixels, this);
|
m_dropPixelsConn = m_dropPixels->DropPixels.connect(&ContextBar::onDropPixels, this);
|
||||||
@ -2056,6 +2059,11 @@ void ContextBar::onFgOrBgColorChange(doc::Brush::ImageColor imageColor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContextBar::onOpacityRangeChange()
|
||||||
|
{
|
||||||
|
updateForActiveTool();
|
||||||
|
}
|
||||||
|
|
||||||
void ContextBar::onDropPixels(ContextBarObserver::DropAction action)
|
void ContextBar::onDropPixels(ContextBarObserver::DropAction action)
|
||||||
{
|
{
|
||||||
notify_observers(&ContextBarObserver::onDropPixels, action);
|
notify_observers(&ContextBarObserver::onDropPixels, action);
|
||||||
@ -2143,7 +2151,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
|||||||
m_contiguous->setSelected(toolPref->contiguous());
|
m_contiguous->setSelected(toolPref->contiguous());
|
||||||
|
|
||||||
m_inkType->setInkTypeIcon(toolPref->ink());
|
m_inkType->setInkTypeIcon(toolPref->ink());
|
||||||
m_inkOpacity->setTextf("%d", toolPref->opacity());
|
m_inkOpacity->setValue(toolPref->opacity());
|
||||||
|
|
||||||
hasInkWithOpacity =
|
hasInkWithOpacity =
|
||||||
((isPaint && tools::inkHasOpacity(toolPref->ink())) ||
|
((isPaint && tools::inkHasOpacity(toolPref->ink())) ||
|
||||||
|
@ -123,6 +123,7 @@ namespace app {
|
|||||||
void onBrushAngleChange();
|
void onBrushAngleChange();
|
||||||
void onSymmetryModeChange();
|
void onSymmetryModeChange();
|
||||||
void onFgOrBgColorChange(doc::Brush::ImageColor imageColor);
|
void onFgOrBgColorChange(doc::Brush::ImageColor imageColor);
|
||||||
|
void onOpacityRangeChange();
|
||||||
void onDropPixels(ContextBarObserver::DropAction action);
|
void onDropPixels(ContextBarObserver::DropAction action);
|
||||||
void updateSliceFields(const Site& site);
|
void updateSliceFields(const Site& site);
|
||||||
|
|
||||||
@ -203,6 +204,7 @@ namespace app {
|
|||||||
obs::scoped_connection m_symmModeConn;
|
obs::scoped_connection m_symmModeConn;
|
||||||
obs::scoped_connection m_fgColorConn;
|
obs::scoped_connection m_fgColorConn;
|
||||||
obs::scoped_connection m_bgColorConn;
|
obs::scoped_connection m_bgColorConn;
|
||||||
|
obs::scoped_connection m_alphaRangeConn;
|
||||||
obs::scoped_connection m_keysConn;
|
obs::scoped_connection m_keysConn;
|
||||||
obs::scoped_connection m_dropPixelsConn;
|
obs::scoped_connection m_dropPixelsConn;
|
||||||
obs::scoped_connection m_sizeConn;
|
obs::scoped_connection m_sizeConn;
|
||||||
|
@ -36,13 +36,13 @@ IntEntry::IntEntry(int min, int max, SliderDelegate* sliderDelegate)
|
|||||||
: Entry(int(std::floor(std::log10(double(max))))+1, "")
|
: Entry(int(std::floor(std::log10(double(max))))+1, "")
|
||||||
, m_min(min)
|
, m_min(min)
|
||||||
, m_max(max)
|
, m_max(max)
|
||||||
, m_slider(m_min, m_max, m_min, sliderDelegate)
|
|
||||||
, m_popupWindow(nullptr)
|
, m_popupWindow(nullptr)
|
||||||
, m_changeFromSlider(false)
|
, m_changeFromSlider(false)
|
||||||
{
|
{
|
||||||
m_slider.setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
m_slider = std::make_unique<Slider>(m_min, m_max, m_min, sliderDelegate);
|
||||||
m_slider.setTransparent(true);
|
m_slider->setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
||||||
m_slider.Change.connect(&IntEntry::onChangeSlider, this);
|
m_slider->setTransparent(true);
|
||||||
|
m_slider->Change.connect(&IntEntry::onChangeSlider, this);
|
||||||
initTheme();
|
initTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ IntEntry::~IntEntry()
|
|||||||
|
|
||||||
int IntEntry::getValue() const
|
int IntEntry::getValue() const
|
||||||
{
|
{
|
||||||
int value = m_slider.convertTextToValue(text());
|
int value = m_slider->convertTextToValue(text());
|
||||||
return std::clamp(value, m_min, m_max);
|
return std::clamp(value, m_min, m_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,10 +61,10 @@ void IntEntry::setValue(int value)
|
|||||||
{
|
{
|
||||||
value = std::clamp(value, m_min, m_max);
|
value = std::clamp(value, m_min, m_max);
|
||||||
|
|
||||||
setText(m_slider.convertValueToText(value));
|
setText(m_slider->convertValueToText(value));
|
||||||
|
|
||||||
if (m_popupWindow && !m_changeFromSlider)
|
if (m_popupWindow && !m_changeFromSlider)
|
||||||
m_slider.setValue(value);
|
m_slider->setValue(value);
|
||||||
|
|
||||||
onValueChange();
|
onValueChange();
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ bool IntEntry::onProcessMessage(Message* msg)
|
|||||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||||
Widget* pick = manager()->pickFromScreenPos(
|
Widget* pick = manager()->pickFromScreenPos(
|
||||||
display()->nativeWindow()->pointToScreen(mouseMsg->position()));
|
display()->nativeWindow()->pointToScreen(mouseMsg->position()));
|
||||||
if (pick == &m_slider) {
|
if (pick == m_slider.get()) {
|
||||||
releaseMouse();
|
releaseMouse();
|
||||||
|
|
||||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||||
@ -140,7 +140,7 @@ bool IntEntry::onProcessMessage(Message* msg)
|
|||||||
void IntEntry::onInitTheme(InitThemeEvent& ev)
|
void IntEntry::onInitTheme(InitThemeEvent& ev)
|
||||||
{
|
{
|
||||||
Entry::onInitTheme(ev);
|
Entry::onInitTheme(ev);
|
||||||
m_slider.initTheme(); // The slider might not be in the popup window
|
m_slider->initTheme(); // The slider might not be in the popup window
|
||||||
if (m_popupWindow)
|
if (m_popupWindow)
|
||||||
m_popupWindow->initTheme();
|
m_popupWindow->initTheme();
|
||||||
}
|
}
|
||||||
@ -150,8 +150,8 @@ void IntEntry::onSizeHint(SizeHintEvent& ev)
|
|||||||
int trailing = font()->textLength(getSuffix());
|
int trailing = font()->textLength(getSuffix());
|
||||||
trailing = std::max(trailing, 2*theme()->getEntryCaretSize(this).w);
|
trailing = std::max(trailing, 2*theme()->getEntryCaretSize(this).w);
|
||||||
|
|
||||||
int min_w = font()->textLength(m_slider.convertValueToText(m_min));
|
int min_w = font()->textLength(m_slider->convertValueToText(m_min));
|
||||||
int max_w = font()->textLength(m_slider.convertValueToText(m_max)) + trailing;
|
int max_w = font()->textLength(m_slider->convertValueToText(m_max)) + trailing;
|
||||||
|
|
||||||
int w = std::max(min_w, max_w);
|
int w = std::max(min_w, max_w);
|
||||||
int h = textHeight();
|
int h = textHeight();
|
||||||
@ -175,7 +175,7 @@ void IntEntry::onValueChange()
|
|||||||
|
|
||||||
void IntEntry::openPopup()
|
void IntEntry::openPopup()
|
||||||
{
|
{
|
||||||
m_slider.setValue(getValue());
|
m_slider->setValue(getValue());
|
||||||
|
|
||||||
// We weren't able to reproduce it, but there are crash reports
|
// We weren't able to reproduce it, but there are crash reports
|
||||||
// where this openPopup() function is called and the popup is still
|
// where this openPopup() function is called and the popup is still
|
||||||
@ -186,7 +186,7 @@ void IntEntry::openPopup()
|
|||||||
|
|
||||||
m_popupWindow = std::make_unique<TransparentPopupWindow>(PopupWindow::ClickBehavior::CloseOnClickInOtherWindow);
|
m_popupWindow = std::make_unique<TransparentPopupWindow>(PopupWindow::ClickBehavior::CloseOnClickInOtherWindow);
|
||||||
m_popupWindow->setAutoRemap(false);
|
m_popupWindow->setAutoRemap(false);
|
||||||
m_popupWindow->addChild(&m_slider);
|
m_popupWindow->addChild(m_slider.get());
|
||||||
m_popupWindow->Close.connect(&IntEntry::onPopupClose, this);
|
m_popupWindow->Close.connect(&IntEntry::onPopupClose, this);
|
||||||
|
|
||||||
fit_bounds(
|
fit_bounds(
|
||||||
@ -229,7 +229,7 @@ void IntEntry::closePopup()
|
|||||||
void IntEntry::onChangeSlider()
|
void IntEntry::onChangeSlider()
|
||||||
{
|
{
|
||||||
base::ScopedValue lockFlag(m_changeFromSlider, true);
|
base::ScopedValue lockFlag(m_changeFromSlider, true);
|
||||||
setValue(m_slider.getValue());
|
setValue(m_slider->getValue());
|
||||||
selectAllText();
|
selectAllText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,8 +244,8 @@ void IntEntry::onPopupClose(CloseEvent& ev)
|
|||||||
void IntEntry::removeSlider()
|
void IntEntry::removeSlider()
|
||||||
{
|
{
|
||||||
if (m_popupWindow &&
|
if (m_popupWindow &&
|
||||||
m_slider.parent() == m_popupWindow.get()) {
|
m_slider->parent() == m_popupWindow.get()) {
|
||||||
m_popupWindow->removeChild(&m_slider);
|
m_popupWindow->removeChild(m_slider.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,32 +22,33 @@ namespace ui {
|
|||||||
class IntEntry : public Entry {
|
class IntEntry : public Entry {
|
||||||
public:
|
public:
|
||||||
IntEntry(int min, int max, SliderDelegate* sliderDelegate = nullptr);
|
IntEntry(int min, int max, SliderDelegate* sliderDelegate = nullptr);
|
||||||
~IntEntry();
|
virtual ~IntEntry();
|
||||||
|
|
||||||
int getValue() const;
|
virtual int getValue() const;
|
||||||
void setValue(int value);
|
virtual void setValue(int value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onProcessMessage(Message* msg) override;
|
bool onProcessMessage(Message* msg) override;
|
||||||
void onInitTheme(InitThemeEvent& ev) override;
|
void onInitTheme(InitThemeEvent& ev) override;
|
||||||
void onSizeHint(SizeHintEvent& ev) override;
|
void onSizeHint(SizeHintEvent& ev) override;
|
||||||
void onChange() override;
|
void onChange() override;
|
||||||
|
virtual void onChangeSlider();
|
||||||
|
|
||||||
// New events
|
// New events
|
||||||
virtual void onValueChange();
|
virtual void onValueChange();
|
||||||
|
|
||||||
|
int m_min;
|
||||||
|
int m_max;
|
||||||
|
std::unique_ptr<PopupWindow> m_popupWindow;
|
||||||
|
bool m_changeFromSlider;
|
||||||
|
std::unique_ptr<Slider> m_slider;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void openPopup();
|
void openPopup();
|
||||||
void closePopup();
|
void closePopup();
|
||||||
void onChangeSlider();
|
|
||||||
void onPopupClose(CloseEvent& ev);
|
void onPopupClose(CloseEvent& ev);
|
||||||
void removeSlider();
|
void removeSlider();
|
||||||
|
|
||||||
int m_min;
|
|
||||||
int m_max;
|
|
||||||
Slider m_slider;
|
|
||||||
std::unique_ptr<PopupWindow> m_popupWindow;
|
|
||||||
bool m_changeFromSlider;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
Loading…
x
Reference in New Issue
Block a user