15#include <egt/canvas.h>
16#include <egt/detail/alignment.h>
17#include <egt/detail/enum.h>
18#include <egt/detail/math.h>
19#include <egt/detail/meta.h>
20#include <egt/detail/screen/composerscreen.h>
23#include <egt/imagegroup.h>
24#include <egt/painter.h>
25#include <egt/serialize.h>
26#include <egt/textwidget.h>
27#include <egt/valuewidget.h>
28#include <egt/widgetflags.h>
176 const auto diff =
event.pointer().point -
event.pointer().drag_start;
184 const auto diff =
event.pointer().point -
event.pointer().drag_start;
206 bool allow_fallback =
false)
const;
228 T orig = this->
value();
323 return egt::detail::normalize<float>(offset, 0, b.width() -
handle_width(),
326 return egt::detail::normalize<float>(offset, 0, b.height() -
handle_height(),
345 auto label_rect =
label_box(painter, prev_value, text);
383 handle_rect -=
Point(0, b.height() / 2.);
385 handle_rect -=
Point(b.width() / 2., 0);
392 const auto text_size = painter.
text_size(text);
399 if (target.width() <= b.width())
401 if (target.x() < b.x())
404 if (target.x() + target.width() > b.x() + b.width())
405 target.x(b.x() + b.width() - target.width());
408 if (target.height() <= b.height())
410 if (target.y() < b.y())
413 if (target.y() + target.height() > b.y() + b.height())
414 target.y(b.y() + b.height() - target.height());
425 painter.
draw(target.point());
438 return std::to_string(
value);
458 static Size m_default_size;
460 static void register_handler();
461 static void unregister_handler();
479 EGT_NODISCARD std::string
type()
const override
495 EGT_NODISCARD std::string
type()
const override
514 m_default_size.clear();
520void SliderType<T>::unregister_handler()
532 auto ss = egt::Application::instance().
screen()->
size();
543 unregister_handler();
554 this->name(
"Slider" + std::to_string(this->m_widgetid));
556 this->grab_mouse(
true);
557 this->slider_flags().set(SliderFlag::rectangle_handle);
558 this->border_radius(4.0);
568 this->deserialize_leaf(props);
575 auto b = this->content_area();
576 auto yp = b.y() + b.height() / 2.;
577 auto xp = b.x() + b.width() / 2.;
579 if (slider_flags().is_set(SliderFlag::show_labels) ||
580 slider_flags().is_set(SliderFlag::show_label))
583 yp += b.height() / 4.;
585 xp += b.width() / 4.;
587 if (slider_flags().is_set(SliderFlag::show_label))
589 draw_label(painter, this->value());
593 draw_label(painter, this->starting());
594 draw_label(painter, this->starting() + ((this->
ending() - this->starting()) / 2));
595 draw_label(painter, this->
ending());
600 draw_line(painter, xp, yp);
603 draw_handle(painter);
609 const auto b = this->content_area();
610 auto width = b.width();
611 auto height = b.height();
613 if (slider_flags().is_set(SliderFlag::show_labels) ||
614 slider_flags().is_set(SliderFlag::show_label))
622 if (slider_flags().is_set(SliderFlag::square_handle) ||
623 slider_flags().is_set(SliderFlag::round_handle))
626 return std::min<DefaultDim>(width / 6, height);
628 return std::min<DefaultDim>(height / 6, width);
633 return std::min<DefaultDim>(width / 6, height) * 2;
635 return std::min<DefaultDim>(height / 6, width);
642 const auto b = this->content_area();
643 auto width = b.width();
644 auto height = b.height();
646 if (slider_flags().is_set(SliderFlag::show_labels) ||
647 slider_flags().is_set(SliderFlag::show_label))
655 if (slider_flags().is_set(SliderFlag::square_handle) ||
656 slider_flags().is_set(SliderFlag::round_handle))
659 return std::min<DefaultDim>(width / 6, height);
661 return std::min<DefaultDim>(height / 6, width);
666 return std::min<DefaultDim>(width / 6, height);
668 return std::min<DefaultDim>(height / 6, width) * 2;
675 const auto b = this->content_area();
676 const auto dimw = handle_width();
677 const auto dimh = handle_height();
681 auto xv = b.x() + to_offset(value);
682 if (slider_flags().is_set(SliderFlag::inverted))
683 xv = b.x() + b.width() - to_offset(value) - dimw;
685 if (slider_flags().is_set(SliderFlag::show_labels) ||
686 slider_flags().is_set(SliderFlag::show_label))
689 b.y() + b.height() / 4 - dimh / 2 + b.height() / 2,
696 b.y() + b.height() / 2 - dimh / 2,
703 auto yv = b.y() + b.height() - to_offset(value) - dimh;
704 if (slider_flags().is_set(SliderFlag::inverted))
705 yv = b.y() + to_offset(value);
707 if (slider_flags().is_set(SliderFlag::show_labels) ||
708 slider_flags().is_set(SliderFlag::show_label))
710 return {b.x() + b.width() / 4 - dimw / 2 + b.width() / 2,
717 return {b.x() + b.width() / 2 - dimw / 2,
728 const auto handle_rect = handle_box();
730 auto* image = handle_image(this->group(),
true);
733 this->theme().draw_box(painter,
741 else if (slider_flags().is_set(SliderFlag::round_handle))
743 this->theme().draw_circle(painter,
752 this->theme().draw_box(painter,
759 this->border_radius());
766 const auto b = this->content_area();
767 const auto handle_rect = handle_box();
776 a1 =
Point(b.x(), yp);
777 a2 =
Point(handle_rect.x(), yp);
778 b1 =
Point(handle_rect.x(), yp);
779 b2 =
Point(b.x() + b.width(), yp);
781 painter.
line_width(handle_rect.height() / 5.0);
785 a1 =
Point(xp, b.y() + b.height());
786 a2 =
Point(xp, handle_rect.y());
787 b1 =
Point(xp, handle_rect.y());
788 b2 =
Point(xp, b.y());
790 painter.
line_width(handle_rect.width() / 5.0);
793 if (slider_flags().is_set(SliderFlag::inverted))
796 if (slider_flags().is_set(SliderFlag::consistent_line))
800 painter.
draw(a1, b2);
806 painter.
draw(a1, a2);
810 painter.
draw(b1, b2);
828 serializer.
add_property(
"sliderflags", m_slider_flags.to_string());
830 m_handles.serialize(serializer);
836 props.erase(std::remove_if(props.begin(), props.end(), [&](
auto & p)
838 if (std::get<0>(p) ==
"sliderflags")
840 m_slider_flags.from_string(std::get<1>(p));
843 else if (std::get<0>(p) ==
"orient")
845 orient(detail::enum_from_string<Orientation>(std::get<1>(p)));
848 else if (m_handles.deserialize(std::get<0>(p), std::get<1>(p)))
859 return m_handles.get(group, allow_fallback);
865 m_handles.set(group, image);
866 if (group == this->group())
867 this->damage(handle_box());
873 auto changed = m_handles.reset(group);
874 if (changed && group == this->group())
875 this->damage(handle_box());
static constexpr HVBitField center
Definition widgetflags.h:297
EGT_NODISCARD Screen * screen() const
Get a pointer to the Screen instance.
Definition app.h:119
Manages a unique drawing surface and context.
Definition canvas.h:41
EGT_NODISCARD shared_cairo_t context() const
Get the context for the Canvas.
Definition canvas.h:89
Utility class for managing a set of flags with the ability to observe changes to the flags.
Definition flags.h:40
A Frame is a Widget that has children widgets.
Definition frame.h:45
Definition imagegroup.h:25
Raster image resource used for drawing or displaying.
Definition image.h:39
Drawing interface for 2D graphics.
Definition painter.h:45
Painter & set(const Pattern &pattern)
Set the current color.
Painter & line_width(float width)
Set the current line width.
Painter & draw(const PointType< T, detail::Compatible::normal > &point)
Move to a point.
Definition painter.h:182
Size text_size(const std::string &text)
GroupId
Used to define a category of patterns that usually relate to the state of a widget.
Definition palette.h:219
@ disabled
Color group usually associated with the Widget::Flag::disabled flag.
@ normal
Default color group associated with a normal Widget state.
@ button_bg
Button background color.
@ button_fg
Button foreground color.
@ label_text
Label text color.
static constexpr RectType merge(const RectType &lhs, const RectType &rhs) noexcept
Merge two rectangles together into one super rectangle that contains them both.
Definition geometry.h:858
EGT_NODISCARD Size size() const
Size of the screen.
Definition screen.h:75
Abstract base serializer class.
Definition serialize.h:34
virtual void add_property(const std::string &name, const std::string &value, const Attributes &attrs={})=0
Add a property.
std::list< std::tuple< std::string, std::string, Serializer::Attributes > > Properties
Definition serialize.h:47
Signal class used for defining a signal and dispatching events.
Definition signal.h:30
@ INVALID_HANDLE
Definition signal.h:35
void invoke(Args... args)
Invoke all handlers with the specified args.
Definition signal.h:85
uint32_t RegisterHandle
Handle type.
Definition signal.h:46
EGT_NODISCARD constexpr bool empty() const noexcept
Returns true if the size has no width or height.
Definition geometry.h:372
This is a slider that can be used to select floating value from a range.
Definition slider.h:491
EGT_NODISCARD std::string type() const override
Returns a string representation of the type of this widget.
Definition slider.h:495
This is a slider that can be used to select value from a range.
Definition slider.h:86
void orient(Orientation orient)
Set the Orientation.
Definition slider.h:269
EGT_NODISCARD Size min_size_hint() const override
Get a minimum size hint for the Widget.
Definition slider.h:288
SliderFlags & slider_flags()
Get the current slider flags.
Definition slider.h:279
SliderType(Frame &parent, T start=0, T end=100, T value=0, Orientation orient=Orientation::horizontal) noexcept
Definition slider.h:136
void live_update(bool enable)
Enable or disable the live update feature.
Definition slider.h:249
void update_value(T value)
Update the value without notifying the handlers.
Definition slider.h:331
static Size default_size()
Default Slider size.
Definition slider.h:527
void draw(Painter &painter, const Rect &rect) override
Draw the widget.
Definition slider.h:573
EGT_NODISCARD int handle_width() const
Get the calculated handle width.
Definition slider.h:607
void draw_handle(Painter &painter)
Draw the handle.
Definition slider.h:726
EGT_NODISCARD bool live_update() const
get live update value.
Definition slider.h:257
static void default_size(const Size &size)
Change default Slider size.
Definition slider.h:540
void handle_image(const Image &image, Palette::GroupId group=Palette::GroupId::normal)
Set the image used to draw the slider's handle.
Definition slider.h:863
void reset_handle_image(Palette::GroupId group=Palette::GroupId::normal)
Remove the image, if any, used to draw the slider's handle.
Definition slider.h:871
EGT_NODISCARD Image * handle_image(Palette::GroupId group, bool allow_fallback=false) const
Get the image, if any, to draw the slider's handle for the given group.
Definition slider.h:857
EGT_NODISCARD Orientation orient() const
Get the Orientation.
Definition slider.h:262
void draw_label(Painter &painter, T value)
Draw the value label.
Definition slider.h:421
SliderType(Serializer::Properties &props, bool is_derived) noexcept
Definition slider.h:562
EGT_NODISCARD Rect handle_box() const
Get the handle box for the current value.
Definition slider.h:368
EGT_NODISCARD Rect handle_box(T value) const
Get the handle box for the specified value.
Definition slider.h:673
Orientation m_orient
Orientation of the slider.
Definition slider.h:442
SliderType(T start=0, T end=100, T value=0, Orientation orient=Orientation::horizontal) noexcept
Definition slider.h:108
EGT_NODISCARD int handle_height() const
Get the calculated handle height.
Definition slider.h:640
T value(T value) override
Set value.
Definition slider.h:226
void draw_line(Painter &painter, float xp, float yp)
Draw the line.
Definition slider.h:764
static std::string format_label(T value)
Format the label text.
Definition slider.h:436
SliderType(const Rect &rect, T start=0, T end=100, T value=0, Orientation orient=Orientation::horizontal) noexcept
Definition slider.h:549
int m_start_offset
When dragging, the offset at the drag start.
Definition slider.h:454
bool internal_drag() const override
Definition slider.h:300
void serialize(Serializer &serializer) const override
Serialize the widget to the specified serializer.
Definition slider.h:824
SliderType(Serializer::Properties &props) noexcept
Definition slider.h:146
bool internal_track_drag() const override
Definition slider.h:301
EGT_NODISCARD T to_value(int offset) const
Convert an offset to value.
Definition slider.h:319
EGT_NODISCARD int to_offset(T value) const
Convert a value to an offset.
Definition slider.h:304
void handle(Event &event) override
Handle an event.
Definition slider.h:157
bool m_live_update
When true, notify handlers even during drag.
Definition slider.h:448
EGT_NODISCARD Rect label_box(Painter &painter, T value, std::string &text) const
Get the label box and text for the specified value.
Definition slider.h:377
SliderType(Frame &parent, const Rect &rect, T start=0, T end=100, T value=0, Orientation orient=Orientation::horizontal) noexcept
Definition slider.h:122
EGT_NODISCARD const SliderFlags & slider_flags() const
Get the current slider flags.
Definition slider.h:276
SliderFlags m_slider_flags
Slider flags.
Definition slider.h:451
bool m_invoke_pending
When true, an invoke of events has been queued to occur.
Definition slider.h:445
This is a slider that can be used to select integer value from a range.
Definition slider.h:475
EGT_NODISCARD std::string type() const override
Returns a string representation of the type of this widget.
Definition slider.h:479
static Signal ::RegisterHandle register_screen_resize_hook(const Signal<>::EventCallback &handler)
Register a handler to manage screen size changes.
static void unregister_screen_resize_hook(Signal<>::RegisterHandle handle)
Unregister a handler that managed screen size changes.
@ raw_pointer_up
Raw pointer event.
@ pointer_drag
Pointer event.
@ pointer_drag_start
Pointer event.
SizeType< DefaultDim, detail::Compatible::normal > Size
Helper type alias.
Definition geometry.h:573
RectType< DefaultDim, detail::Compatible::normal > Rect
Helper type alias.
Definition geometry.h:1023
PointType< DefaultDim, detail::Compatible::normal > Point
Helper type alias.
Definition geometry.h:314
static constexpr Color transparent
Predefined color.
Definition palette.h:59
constexpr T bit(T n)
Utility to create a bit mask for the specified bit.
Definition meta.h:306
constexpr bool float_equal(const float f1, const float f2)
Safe equal comparison of float values.
Definition math.h:107
constexpr const char * enum_to_string(T const &e)
Convert an enum to a string.
Definition enum.h:55
EGT_API Rect align_algorithm(const Rect &orig, const Rect &bounding, const AlignFlags &align, DefaultDim padding=0, DefaultDim horizontal_ratio=0, DefaultDim vertical_ratio=0, DefaultDim xratio=0, DefaultDim yratio=0)
Given an item size, and a bounding box, and an alignment parameter, return the rectangle the item box...
Orientation
Generic orientation flags.
Definition widgetflags.h:652
EGT framework namespace.
Definition animation.h:24
A single event that has information about the event and state for the event.
Definition event.h:255
EGT_NODISCARD const EventId & id() const noexcept
Get the id of the event.
Definition event.h:284
Base class for SliderType.
Definition slider.h:39
SliderFlag
Slider flags.
Definition slider.h:42
@ inverted
Horizontal slider origin (value start()), is to the left.
@ round_handle
Draw a round handle.
@ consistent_line
Solid color line.
@ square_handle
Draw a square handle.
@ show_labels
Show range labels.
@ rectangle_handle
Draw a rectangle handle.
@ show_label
Show value label.
When using enum_to_string() and enum_from_string(), this type needs to be defined and specialized to ...
Definition enum.h:48