#include "Band_Region.h" #include #include #include #include #include "../Axis/Abs_Axis_p.h" #include "../base/Memory.h" #include "../render/Canvas.h" namespace renderive { struct Band_Region_Render_State : Render_State, Band_Region_Prop {}; struct Band_Region_Private : Typed_Render_Data { void draw(Canvas& canvas, const Plot_Render_Snapshot&) override { Band_Region_Render_State* s = render_state(); auto domain_axis = s->domain_axis.lock(); auto value_axis = s->value_axis.lock(); if (!domain_axis || !value_axis || s->range.length() == 0.0) return; Axis_Mapping_2D mapping = Axis_Render_Access::mapping(domain_axis.get(), value_axis.get()); std::array points{}; if (s->orientation == Band_Axis::Domain) { points = { mapping.map(s->range.origin, mapping.value.coord_range.origin), mapping.map(s->range.target, mapping.value.coord_range.origin), mapping.map(s->range.target, mapping.value.coord_range.target), mapping.map(s->range.origin, mapping.value.coord_range.target)}; } else { points = { mapping.map(mapping.domain.coord_range.origin, s->range.origin), mapping.map(mapping.domain.coord_range.target, s->range.origin), mapping.map(mapping.domain.coord_range.target, s->range.target), mapping.map(mapping.domain.coord_range.origin, s->range.target)}; } canvas.save(); canvas.set_pen(s->pen); canvas.set_brush(s->brush); canvas.draw_polygon(std::span(points.data(), points.size()), true); canvas.restore(); } }; RENDERIVE_DEFINE_RENDERABLE_BINDING(Band_Region, Band_Region_Private, Band_Region_Render_State, Input_Data, "BandRegion") RENDERIVE_DEFINE_WEAK_STATE_PROP(Band_Region, Band_Region_Render_State, Abs_Axis, domain_axis) RENDERIVE_DEFINE_WEAK_STATE_PROP(Band_Region, Band_Region_Render_State, Abs_Axis, value_axis) Range Band_Region::range() { return d()->edit_state_value(&Band_Region_Render_State::range); } void Band_Region::set_range(Range value) { if (value.length() == 0.0) return; d()->set_state_value(&Band_Region_Render_State::range, value); } RENDERIVE_DEFINE_STATE_PROP(Band_Region, Band_Region_Render_State, Band_Axis, orientation) RENDERIVE_DEFINE_STATE_PROP(Band_Region, Band_Region_Render_State, Brush, brush) RENDERIVE_DEFINE_STATE_PROP(Band_Region, Band_Region_Render_State, Pen, pen) Band_Region::Builder::Builder(std::shared_ptr parent, std::shared_ptr domain_axis, std::shared_ptr value_axis) { ASSERT(parent, "Band_Region build error! parent == nullptr"); ASSERT(domain_axis && value_axis, "Band_Region build error! axis == nullptr"); ASSERT(domain_axis->attached_to_plot(), "Band_Region build error! domain_axis->plot == nullptr"); ASSERT(domain_axis->shares_plot_with(*value_axis), "Band_Region build error! domain_axis->plot != value_axis->plot"); ASSERT(parent->shares_plot_with(*domain_axis), "Band_Region build error! parent->plot != axis->plot"); ASSERT(domain_axis->orientation() != value_axis->orientation(), "Band_Region build error! axes must be orthogonal"); this->parent = parent; this->domain_axis = domain_axis; this->value_axis = value_axis; } std::shared_ptr Band_Region::Builder::build() { auto ret = renderive::make_shared(); ret->init(parent); Band_Region_Private* pd = ret->d(); Band_Region_Render_State* sc = reinterpret_cast(pd->state(State_Edit)); PROP_R(std::weak_ptr, domain_axis) PROP_R(std::weak_ptr, value_axis) PROP_R(Range, range) PROP_R(Band_Axis, orientation) PROP_R(Brush, brush) PROP_R(Pen, pen) if (sc->range.length() == 0.0) sc->range = {0.0, 1.0}; return ret; } } // namespace renderive