mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 21:33:12 +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
|
||||
modules/gfx.cpp
|
||||
modules/gui.cpp
|
||||
ui/alpha_entry.cpp
|
||||
ui/alpha_slider.cpp
|
||||
ui/app_menuitem.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_box.h"
|
||||
#include "app/tools/tool_loop_modifiers.h"
|
||||
#include "app/ui/alpha_entry.h"
|
||||
#include "app/ui/brush_popup.h"
|
||||
#include "app/ui/button_set.h"
|
||||
#include "app/ui/color_button.h"
|
||||
@ -710,9 +711,9 @@ private:
|
||||
obs::scoped_connection m_conn;
|
||||
};
|
||||
|
||||
class ContextBar::InkOpacityField : public IntEntry {
|
||||
class ContextBar::InkOpacityField : public AlphaEntry {
|
||||
public:
|
||||
InkOpacityField() : IntEntry(0, 255) {
|
||||
InkOpacityField() : AlphaEntry(AlphaSlider::Type::OPACITY) {
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -720,7 +721,7 @@ protected:
|
||||
if (g_updatingFromCode)
|
||||
return;
|
||||
|
||||
IntEntry::onValueChange();
|
||||
AlphaEntry::onValueChange();
|
||||
base::ScopedValue lockFlag(g_updatingFromCode, true);
|
||||
|
||||
int newValue = getValue();
|
||||
@ -1914,6 +1915,8 @@ ContextBar::ContextBar(TooltipManager* tooltipManager,
|
||||
[this]{ onFgOrBgColorChange(doc::Brush::ImageColor::MainColor); });
|
||||
m_bgColorConn = pref.colorBar.bgColor.AfterChange.connect(
|
||||
[this]{ onFgOrBgColorChange(doc::Brush::ImageColor::BackgroundColor); });
|
||||
m_alphaRangeConn = pref.range.opacity.AfterChange.connect(
|
||||
[this]{ onOpacityRangeChange(); });
|
||||
m_keysConn = KeyboardShortcuts::instance()->UserChange.connect(
|
||||
[this, tooltipManager]{ setupTooltips(tooltipManager); });
|
||||
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)
|
||||
{
|
||||
notify_observers(&ContextBarObserver::onDropPixels, action);
|
||||
@ -2143,7 +2151,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
||||
m_contiguous->setSelected(toolPref->contiguous());
|
||||
|
||||
m_inkType->setInkTypeIcon(toolPref->ink());
|
||||
m_inkOpacity->setTextf("%d", toolPref->opacity());
|
||||
m_inkOpacity->setValue(toolPref->opacity());
|
||||
|
||||
hasInkWithOpacity =
|
||||
((isPaint && tools::inkHasOpacity(toolPref->ink())) ||
|
||||
|
@ -123,6 +123,7 @@ namespace app {
|
||||
void onBrushAngleChange();
|
||||
void onSymmetryModeChange();
|
||||
void onFgOrBgColorChange(doc::Brush::ImageColor imageColor);
|
||||
void onOpacityRangeChange();
|
||||
void onDropPixels(ContextBarObserver::DropAction action);
|
||||
void updateSliceFields(const Site& site);
|
||||
|
||||
@ -203,6 +204,7 @@ namespace app {
|
||||
obs::scoped_connection m_symmModeConn;
|
||||
obs::scoped_connection m_fgColorConn;
|
||||
obs::scoped_connection m_bgColorConn;
|
||||
obs::scoped_connection m_alphaRangeConn;
|
||||
obs::scoped_connection m_keysConn;
|
||||
obs::scoped_connection m_dropPixelsConn;
|
||||
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, "")
|
||||
, m_min(min)
|
||||
, m_max(max)
|
||||
, m_slider(m_min, m_max, m_min, sliderDelegate)
|
||||
, m_popupWindow(nullptr)
|
||||
, m_changeFromSlider(false)
|
||||
{
|
||||
m_slider.setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
||||
m_slider.setTransparent(true);
|
||||
m_slider.Change.connect(&IntEntry::onChangeSlider, this);
|
||||
m_slider = std::make_unique<Slider>(m_min, m_max, m_min, sliderDelegate);
|
||||
m_slider->setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
||||
m_slider->setTransparent(true);
|
||||
m_slider->Change.connect(&IntEntry::onChangeSlider, this);
|
||||
initTheme();
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ IntEntry::~IntEntry()
|
||||
|
||||
int IntEntry::getValue() const
|
||||
{
|
||||
int value = m_slider.convertTextToValue(text());
|
||||
int value = m_slider->convertTextToValue(text());
|
||||
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);
|
||||
|
||||
setText(m_slider.convertValueToText(value));
|
||||
setText(m_slider->convertValueToText(value));
|
||||
|
||||
if (m_popupWindow && !m_changeFromSlider)
|
||||
m_slider.setValue(value);
|
||||
m_slider->setValue(value);
|
||||
|
||||
onValueChange();
|
||||
}
|
||||
@ -92,7 +92,7 @@ bool IntEntry::onProcessMessage(Message* msg)
|
||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||
Widget* pick = manager()->pickFromScreenPos(
|
||||
display()->nativeWindow()->pointToScreen(mouseMsg->position()));
|
||||
if (pick == &m_slider) {
|
||||
if (pick == m_slider.get()) {
|
||||
releaseMouse();
|
||||
|
||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||
@ -140,7 +140,7 @@ bool IntEntry::onProcessMessage(Message* msg)
|
||||
void IntEntry::onInitTheme(InitThemeEvent& 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)
|
||||
m_popupWindow->initTheme();
|
||||
}
|
||||
@ -150,8 +150,8 @@ void IntEntry::onSizeHint(SizeHintEvent& ev)
|
||||
int trailing = font()->textLength(getSuffix());
|
||||
trailing = std::max(trailing, 2*theme()->getEntryCaretSize(this).w);
|
||||
|
||||
int min_w = font()->textLength(m_slider.convertValueToText(m_min));
|
||||
int max_w = font()->textLength(m_slider.convertValueToText(m_max)) + trailing;
|
||||
int min_w = font()->textLength(m_slider->convertValueToText(m_min));
|
||||
int max_w = font()->textLength(m_slider->convertValueToText(m_max)) + trailing;
|
||||
|
||||
int w = std::max(min_w, max_w);
|
||||
int h = textHeight();
|
||||
@ -175,7 +175,7 @@ void IntEntry::onValueChange()
|
||||
|
||||
void IntEntry::openPopup()
|
||||
{
|
||||
m_slider.setValue(getValue());
|
||||
m_slider->setValue(getValue());
|
||||
|
||||
// We weren't able to reproduce it, but there are crash reports
|
||||
// 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->setAutoRemap(false);
|
||||
m_popupWindow->addChild(&m_slider);
|
||||
m_popupWindow->addChild(m_slider.get());
|
||||
m_popupWindow->Close.connect(&IntEntry::onPopupClose, this);
|
||||
|
||||
fit_bounds(
|
||||
@ -229,7 +229,7 @@ void IntEntry::closePopup()
|
||||
void IntEntry::onChangeSlider()
|
||||
{
|
||||
base::ScopedValue lockFlag(m_changeFromSlider, true);
|
||||
setValue(m_slider.getValue());
|
||||
setValue(m_slider->getValue());
|
||||
selectAllText();
|
||||
}
|
||||
|
||||
@ -244,8 +244,8 @@ void IntEntry::onPopupClose(CloseEvent& ev)
|
||||
void IntEntry::removeSlider()
|
||||
{
|
||||
if (m_popupWindow &&
|
||||
m_slider.parent() == m_popupWindow.get()) {
|
||||
m_popupWindow->removeChild(&m_slider);
|
||||
m_slider->parent() == m_popupWindow.get()) {
|
||||
m_popupWindow->removeChild(m_slider.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,32 +22,33 @@ namespace ui {
|
||||
class IntEntry : public Entry {
|
||||
public:
|
||||
IntEntry(int min, int max, SliderDelegate* sliderDelegate = nullptr);
|
||||
~IntEntry();
|
||||
virtual ~IntEntry();
|
||||
|
||||
int getValue() const;
|
||||
void setValue(int value);
|
||||
virtual int getValue() const;
|
||||
virtual void setValue(int value);
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(Message* msg) override;
|
||||
void onInitTheme(InitThemeEvent& ev) override;
|
||||
void onSizeHint(SizeHintEvent& ev) override;
|
||||
void onChange() override;
|
||||
virtual void onChangeSlider();
|
||||
|
||||
// New events
|
||||
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:
|
||||
void openPopup();
|
||||
void closePopup();
|
||||
void onChangeSlider();
|
||||
void onPopupClose(CloseEvent& ev);
|
||||
void removeSlider();
|
||||
|
||||
int m_min;
|
||||
int m_max;
|
||||
Slider m_slider;
|
||||
std::unique_ptr<PopupWindow> m_popupWindow;
|
||||
bool m_changeFromSlider;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
Loading…
x
Reference in New Issue
Block a user