85 lines
4.1 KiB
C++
85 lines
4.1 KiB
C++
#include "Band_Region.h"
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <span>
|
|
#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<Band_Region, Band_Region_Render_State, Input_Data> {
|
|
void draw(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) override {
|
|
Band_Region_Render_State* s = render_state(frame_view);
|
|
if (!s)
|
|
return;
|
|
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(), snapshot);
|
|
std::array<PointF, 4> 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<const PointF>(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<Renderable> parent, std::shared_ptr<Abs_Axis> domain_axis, std::shared_ptr<Abs_Axis> 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> Band_Region::Builder::build() {
|
|
auto ret = renderive::make_shared<Band_Region>();
|
|
ret->init(parent);
|
|
Band_Region_Private* pd = ret->d();
|
|
Render_Edit_Lease<Band_Region_Private, Band_Region_Render_State> edit(pd);
|
|
Band_Region_Render_State* sc = edit.operator->();
|
|
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
|
PROP_R(std::weak_ptr<Abs_Axis>, 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
|