Skip to content

Commit

Permalink
Merge branch 'skia_2024'
Browse files Browse the repository at this point in the history
  • Loading branch information
djowel committed Aug 17, 2024
2 parents dd1593f + dd03b64 commit 6e4e9e9
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 211 deletions.
2 changes: 0 additions & 2 deletions lib/include/elements/element/dial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ namespace cycfi::elements

basic_dial(double init_value = 0.0);

void prepare_subject(context& ctx) override;
element* hit_test(context const& ctx, point p, bool leaf, bool control) override;

bool scroll(context const& ctx, point dir, point p) override;
void keep_tracking(context const& ctx, tracker_info& track_info) override;

Expand Down
103 changes: 27 additions & 76 deletions lib/include/elements/element/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define ELEMENTS_IMAGE_APRIL_24_2016

#include <elements/element/element.hpp>
#include <elements/element/proxy.hpp>
#include <elements/support/canvas.hpp>
#include <elements/support/pixmap.hpp>
#include <infra/filesystem.hpp>
Expand Down Expand Up @@ -116,28 +117,6 @@ namespace cycfi::elements
void draw(context const& ctx) override;
};

/**
* \class sprite_as_double
*
* \brief
* A template structure to handle sprite images used as 'double'
* receivers.
*
* Receives a 'double' value in the range of 0.0 to 1.0, which
* indicates which frame of the sprite image should be displayed. The
* double value essentially represents the frame number, scaled down to
* fit within the 0.0 to 1.0 range.
*
* \tparam Derived
* The derived class type.
*/
template <typename Derived>
struct sprite_as_double : receiver<double>
{
void value(double val) override;
double value() const override;
};

/**
* \class basic_sprite
*
Expand Down Expand Up @@ -168,24 +147,33 @@ namespace cycfi::elements
float _height;
};

/**
* \class sprite
*
* \brief
* A class representing a sprite image that can be used as controls.
*
* `sprite` extends `basic_sprite` to utilize both `sprite_as_int` and
* `sprite_as_double`, making it usable as both an 'int' and a 'double'
* receiver.
*
* Sprites are images used as controls. Various frames are laid out in
* a single (big) image but only one frame is drawn at any single time.
* Useful for switches, knobs and basic (sprite) animation.
*/
struct sprite : basic_sprite, sprite_as_double<sprite>
using sprite = basic_sprite;

namespace detail
{
using basic_sprite::basic_sprite;
};
template <typename T>
constexpr auto is_sprite()
{
if constexpr (std::is_base_of_v<proxy_base, T>)
return is_sprite<typename T::subject_type>();
else
return std::false_type{};
}

template <>
constexpr auto is_sprite<sprite>()
{
return std::true_type{};
}
}

namespace concepts
{
template <typename T>
concept SpriteSubject
= concepts::Element<T> &&
decltype(detail::is_sprite<std::decay_t<T>>())::value;
}

//--------------------------------------------------------------------------
// Inlines
Expand All @@ -202,43 +190,6 @@ namespace cycfi::elements
{
return _index;
}

/**
* \brief
* Returns the index of the currently displayed frame in
* sprite_as_double as a fraction of the total frames.
*
* \tparam Derived
* The derived class type.
*
* \returns
* The index of the currently displayed frame as a fraction of the
* total frames (between 0.0 to 1.0).
*/
template <typename Derived>
double sprite_as_double<Derived>::value() const
{
auto this_ = static_cast<Derived const*>(this);
return this_->index() / this_->num_frames()-1;
}

/**
* \brief
* Sets the index of the sprite_as_double to the provided value.
*
* \tparam Derived
* The derived class type.
*
* \param val
* The value to set the index to. It's a value between 0.0 and 1.0
* representing the relative position in the sequence of frames.
*/
template <typename Derived>
void sprite_as_double<Derived>::value(double val)
{
auto this_ = static_cast<Derived*>(this);
this_->index(val * (this_->num_frames()-1));
}
}

#endif
3 changes: 3 additions & 0 deletions lib/include/elements/element/proxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ namespace cycfi::elements
class proxy : public Base
{
public:

using subject_type = Subject;

template <typename... T>
proxy(Subject subject_, T&&... args);

Expand Down
1 change: 1 addition & 0 deletions lib/include/elements/element/style.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <elements/element/style/slide_switch.hpp>
#include <elements/element/style/slider.hpp>
#include <elements/element/style/sprite_button.hpp>
#include <elements/element/style/sprite_dial.hpp>
#include <elements/element/style/tab.hpp>
#include <elements/element/style/text_entry.hpp>
#include <elements/element/style/thumbwheel.hpp>
Expand Down
161 changes: 90 additions & 71 deletions lib/include/elements/element/style/dial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,78 +14,128 @@ namespace cycfi::elements
// Basic Knob (You can use this as the subject of dial)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size>
class basic_knob_styler : public element, public receiver<double>
class basic_knob_styler : public element
{
public:

static std::size_t const size = _size;

basic_knob_styler(color c = colors::black)
: _color(c), _value(0)
{}
basic_knob_styler(color c = colors::black);

view_limits limits(basic_context const& ctx) const override;
void draw(context const& ctx) override;

double value() const override { return _value; }
void value(double val) override;

private:

color _color;
float _value;
};

template <std::size_t size>
inline basic_knob_styler<size> basic_knob(color c = colors::black);

////////////////////////////////////////////////////////////////////////////
// Radial Element Base (common base class for radial elements)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size, concepts::Element Subject>
class radial_styler_base : public proxy<Subject>
{
public:

static std::size_t const size = _size;

using base_type = proxy<Subject>;

radial_styler_base(Subject subject);

view_limits limits(basic_context const& ctx) const override;
void prepare_subject(context& ctx) override;
};

////////////////////////////////////////////////////////////////////////////
// Radial Marks (You can use this to place dial tick marks around dials)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size, concepts::Element Subject>
class radial_marks_styler : public radial_styler_base<_size, Subject>
{
public:

static std::size_t const size = _size;
using base_type = radial_styler_base<_size, Subject>;
using base_type::base_type;

void draw(context const& ctx) override;
};

template <std::size_t size, concepts::Element Subject>
inline radial_marks_styler<size, remove_cvref_t<Subject>>
radial_marks(Subject&& subject);

////////////////////////////////////////////////////////////////////////////
// Radial Labels (You can use this to place dial labels around dials)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size, concepts::Element Subject, std::size_t num_labels>
class radial_labels_styler : public radial_styler_base<_size, Subject>
{
public:

static std::size_t const size = _size;
using base_type = radial_styler_base<_size, Subject>;
using string_array = std::array<std::string, num_labels>;

radial_labels_styler(Subject subject, float font_size);

void draw(context const& ctx) override;

string_array _labels;
float _font_size;
};

template <std::size_t size, concepts::Element Subject, typename... S>
inline radial_labels_styler<size, remove_cvref_t<Subject>, sizeof...(S)>
radial_labels(Subject&& subject, float font_size, S&&... s);

//--------------------------------------------------------------------------
// Inlines
//--------------------------------------------------------------------------

template <std::size_t size>
inline basic_knob_styler<size>::basic_knob_styler(color c)
: _color(c)
{}

template <std::size_t size>
inline view_limits basic_knob_styler<size>::limits(basic_context const& /*ctx*/) const
{
auto pt = point{float(size), float(size)};
auto pt = point{float(size), float(size)};
return view_limits{pt, pt};
}

template <std::size_t size>
inline void basic_knob_styler<size>::draw(context const& ctx)
{
auto dial = find_parent<basic_dial*>(ctx);
if (!dial)
return;

auto& thm = get_theme();
auto& cnv = ctx.canvas;
auto indicator_color = thm.indicator_color.level(1.5);
auto cp = circle{center_point(ctx.bounds), ctx.bounds.width()/2};

draw_knob(cnv, cp, _color);
draw_radial_indicator(cnv, cp, _value, indicator_color);
draw_radial_indicator(cnv, cp, dial->value(), indicator_color);
}

template <std::size_t size>
inline void basic_knob_styler<size>::value(double val)
{
_value = val;
}

template <std::size_t size>
inline basic_knob_styler<size> basic_knob(color c = colors::black)
inline basic_knob_styler<size> basic_knob(color c)
{
return {c};
}

////////////////////////////////////////////////////////////////////////////
// Radial Element Base (common base class for radial elements)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size, concepts::Element Subject>
class radial_styler_base : public proxy<Subject>
{
public:

static std::size_t const size = _size;

using base_type = proxy<Subject>;

radial_styler_base(Subject subject)
: base_type(std::move(subject))
{}

view_limits limits(basic_context const& ctx) const override;
void prepare_subject(context& ctx) override;
};
inline radial_styler_base<_size, Subject>::radial_styler_base(Subject subject)
: base_type(std::move(subject))
{}

template <std::size_t size, concepts::Element Subject>
inline view_limits
Expand Down Expand Up @@ -114,21 +164,6 @@ namespace cycfi::elements
ctx.bounds.right -= size_div2;
}

////////////////////////////////////////////////////////////////////////////
// Radial Marks (You can use this to place dial tick marks around dials)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size, concepts::Element Subject>
class radial_marks_styler : public radial_styler_base<_size, Subject>
{
public:

static std::size_t const size = _size;
using base_type = radial_styler_base<_size, Subject>;
using base_type::base_type;

void draw(context const& ctx) override;
};

template <std::size_t size, concepts::Element Subject>
inline void
radial_marks_styler<size, Subject>::draw(context const& ctx)
Expand All @@ -148,28 +183,12 @@ namespace cycfi::elements
return {std::forward<Subject>(subject)};
}

////////////////////////////////////////////////////////////////////////////
// Radial Labels (You can use this to place dial labels around dials)
////////////////////////////////////////////////////////////////////////////
template <std::size_t _size, concepts::Element Subject, std::size_t num_labels>
class radial_labels_styler : public radial_styler_base<_size, Subject>
{
public:

static std::size_t const size = _size;
using base_type = radial_styler_base<_size, Subject>;
using string_array = std::array<std::string, num_labels>;

radial_labels_styler(Subject subject, float font_size)
: base_type(std::move(subject))
, _font_size(font_size)
{}

void draw(context const& ctx) override;

string_array _labels;
float _font_size;
};
inline radial_labels_styler<_size, Subject, num_labels>
::radial_labels_styler(Subject subject, float font_size)
: base_type(std::move(subject))
, _font_size(font_size)
{}

template <std::size_t size, concepts::Element Subject, std::size_t num_labels>
inline void
Expand Down
Loading

0 comments on commit 6e4e9e9

Please sign in to comment.