1 #include <../../nrnconf.h>
8 #include <InterViews/display.h>
9 #include <InterViews/session.h>
10 #include <InterViews/background.h>
11 #include <InterViews/style.h>
12 #include <InterViews/window.h>
13 #include <InterViews/tformsetter.h>
14 #include <InterViews/brush.h>
15 #include <InterViews/action.h>
16 #include <InterViews/color.h>
17 #include <InterViews/hit.h>
18 #include <InterViews/handler.h>
19 #include <InterViews/event.h>
20 #include <InterViews/telltale.h>
21 #include <InterViews/layout.h>
22 #include <IV-look/kit.h>
42 #define Shape_Section_ "Section PlotShape"
43 #define Shape_Rotate_ "Rotate3D PlotShape"
44 #define Shape_Style_ "ShapeStyle PlotShape"
53 static long beveljoin_ = 0;
58 class ShapeChangeObserver:
public Observer {
61 virtual ~ShapeChangeObserver();
74 static const Color* sec_sel_color() {
78 Display* dis = Session::instance()->default_display();
79 if (!dis->style()->find_attribute(
"section_select_color",
c) ||
88 static const Color* sec_adjacent_color() {
92 Display* dis = Session::instance()->default_display();
93 if (!dis->style()->find_attribute(
"section_adjacent_color",
c) ||
102 inline float norm(
float x,
float y) {
103 return (x * x + y * y);
110 PointMark(OcShape*,
Object*,
const Color*,
const char style =
'O',
float size = 8.);
111 virtual ~PointMark();
118 virtual void set_loc(
Section*,
float x);
119 bool everything_ok();
130 class OcShapeHandler;
135 virtual void select_section(
Section*);
136 virtual void handle_picked();
143 virtual void set_select_action(
const char*);
144 virtual void set_select_action(
Object*);
146 virtual PointMark* point_mark(
Object*,
148 const char style =
'O',
149 const float size = 8.);
150 virtual PointMark* point_mark(
Section*,
float x,
const Color*);
151 virtual void point_mark_remove(
Object* pp =
NULL);
159 OcShapeHandler* osh_;
161 bool show_adjacent_selection_;
166 OcShapeHandler(OcShape*);
167 virtual ~OcShapeHandler();
173 OcShapeHandler::OcShapeHandler(OcShape*
s) {
176 OcShapeHandler::~OcShapeHandler() {}
177 bool OcShapeHandler::event(
Event&) {
188 OcShape* sh = (OcShape*)
v;
192 for (
i = 0;
i < 8; ++
i) {
232 ((OcShape*)
v)->select_section(
sec);
244 ((OcShape*)
v)->set_select_action(
gargstr(1));
280 if (
s &&
s->good()) {
300 obj = (*nrnpy_seg_from_sec_x)(ssec->
section(), d);
318 obj = (*nrnpy_seg_from_sec_x)(ssec->
section(), d);
387 s->colorseg(
sec, x,
c);
426 OcShape*
s = (OcShape*)
v;
434 style = char(
chkarg(3, 0, 127));
438 size = float(
chkarg(4, 1e-9, 1e9));
454 OcShape*
s = (OcShape*)
v;
458 s->point_mark_remove(o);
480 s->shape_type(
int(
chkarg(1, 0., 2.)));
585 sh =
new OcShape(sl);
616 point_mark_list_ =
NULL;
617 osh_ =
new OcShapeHandler(
this);
619 section_handler(osh_);
621 Display* dis = Session::instance()->default_display();
622 show_adjacent_selection_ = dis->style()->value_is_on(
"show_adjacent_selection");
624 OcShape::~OcShape() {
632 void OcShape::erase_all() {
634 point_mark_list_ =
NULL;
638 PointMark* OcShape::point_mark(
Object* ob,
const Color*
c,
const char style,
const float size) {
639 if (!point_mark_list_) {
642 PointMark* g =
new PointMark(
this, ob,
c, style, size);
643 point_mark_list_->append(g);
645 if (!g->everything_ok()) {
646 point_mark_list_->remove(point_mark_list_->count() - 1);
654 if (!point_mark_list_) {
657 PointMark* g =
new PointMark(
this,
NULL,
c);
659 point_mark_list_->append(g);
661 if (!g->everything_ok()) {
662 point_mark_list_->remove(point_mark_list_->count() - 1);
668 void OcShape::point_mark_remove(
Object* o) {
669 if (point_mark_list_) {
672 for (
i =
cnt - 1;
i >= 0; --
i) {
673 PointMark* g = (PointMark*) point_mark_list_->component(
i);
674 if (g->object() == o) {
676 point_mark_list_->remove(
i);
681 while (point_mark_list_->count()) {
682 remove(glyph_index(point_mark_list_->component(0)));
683 point_mark_list_->remove(0);
689 void OcShape::set_select_action(
const char*
s) {
696 void OcShape::set_select_action(
Object* pobj) {
711 if (show_adjacent_selection_) {
712 ss = shape_section(
s->parentsec);
716 for (
s =
s->child;
s;
s =
s->sibling) {
717 ss = shape_section(
s);
727 c = sec_adjacent_color();
729 if (show_adjacent_selection_) {
730 ss = shape_section(
s->parentsec);
734 for (
s =
s->child;
s;
s =
s->sibling) {
735 ss = shape_section(
s);
748 ss = shape_section(
sec);
757 void OcShape::handle_picked() {
759 if (!s1 || !s1->
good()) {
762 sel_color(sold_, s1);
777 void OcShape::save_phase1(std::ostream& o) {
778 o <<
"{" << std::endl;
779 save_class(o,
"Shape");
786 :
View((
s->x1() +
s->x2()) / 2,
787 (
s->y1() +
s->y2()) / 2,
788 std::max(
s->x2() -
s->x1(),
s->y2() -
s->y1()) * 1.1,
795 :
View(x[0], x[1], x[2], x[3],
s, x[6], x[7]) {
796 Coord x1, y1, x2, y2;
797 zout(x1, y1, x2, y2);
798 size(x1, y1, x2, y2);
805 class ShapeType:
public Action {
808 virtual ~ShapeType();
809 virtual void execute();
814 ShapeType::ShapeType(
int st) {
817 ShapeType::~ShapeType() {}
818 void ShapeType::execute() {
836 while (
sg_->count()) {
840 sg_->remove(
sg_->count() - 1);
861 volatile_ptr_ref =
NULL;
876 new_size(-100, -100, 100, 100);
881 shape_changed_ =
NULL;
885 wk.style()->find_attribute(
"shape_beveljoin", beveljoin_);
891 section_handler_ =
NULL;
895 picker()->remove_item(
"Crosshair");
896 picker()->remove_item(
"Plot what?");
897 picker()->remove_item(
"Pick Vector");
898 picker()->remove_item(
"Color/Brush");
899 picker()->remove_item(
"Keep Lines");
900 picker()->remove_item(
"Family Label?");
901 picker()->remove_item(
"Erase");
902 picker()->remove_item(
"Remove");
906 m2->state()->set(TelltaleState::is_chosen,
true);
907 picker()->add_radio_menu(
"3D Rotate", r3b_, 0, ROTATE);
911 mi = wk.menu_item(
"Show Diam");
913 picker()->add_menu(
"Show Diam", mi, m);
914 mi = wk.menu_item(
"Centroid");
916 picker()->add_menu(
"Centroid", mi, m);
917 mi = wk.menu_item(
"Schematic");
919 picker()->add_menu(
"Schematic", mi, m);
920 mi = wk.menu_item(
"Shape Style");
922 picker()->add_menu(mi);
925 Coord x1, y1, x2, y2;
926 Coord xt1 = 0, yt1 = 0, xt2 = 0, yt2 = 0;
928 for (
i = 0;
i <
cnt; ++
i) {
931 xt1 = std::min(x1, xt1);
932 yt1 = std::min(y1, yt1);
933 xt2 = std::max(x2, xt2);
934 yt2 = std::max(y2, yt2);
937 color_value_ =
new ColorValue();
939 shape_changed_ =
new ShapeChangeObserver(
this);
961 volatile_ptr_ref =
NULL;
973 volatile_ptr_ref =
NULL;
1005 for (
i = 0;
i <
n; ++
i) {
1019 long i,
j,
n =
sg_->count();
1023 for (
i = 0;
i <
n; ++
i) {
1025 x1 = std::min(
x1, l);
1026 x2 = std::max(
x2, r);
1027 y1 = std::min(
y1, b);
1028 y2 = std::max(
y2,
t);
1049 o <<
var_name_ <<
"append(save_window_)" << std::endl;
1051 o <<
var_name_ <<
" = save_window_" << std::endl;
1053 o <<
"save_window_.save_name(\"" <<
var_name_ <<
"\")" << std::endl;
1064 double d1, d2;
int ntic;
1081 w->place(l + e.pointer_root_x() - e.pointer_x(), b + e.pointer_root_y() - e.pointer_y());
1109 for (
i = 0;
i <
cnt; ++
i) {
1125 if (
this != volatile_ptr_ref) {
1126 volatile_ptr_ref =
this;
1130 for (
i = 0;
i <
cnt; ++
i) {
1148 for (csec =
sec->child; csec; csec = csec->
sibling) {
1174 for (
i = 0;
i <
cnt; ++
i) {
1182 if (par_helper(ss->
section())) {
1193 if (ss && ss->
color() !=
c) {
1200 if (ss && ss->
color() !=
c) {
1207 for (
i = 0;
i <
cnt; ++
i) {
1222 for (
i = 0;
i <
cnt; ++
i) {
1240 w->
xplace(
int(x[4]),
int(x[5]));
1306 Coord x0, y0, xp, yp;
1334 logic_con =
sec->logical_connection;
1341 r[0] = logic_con->
x;
1342 r[1] = logic_con->
y;
1343 r[2] = logic_con->
z;
1351 for (
i = 0;
i <
n_; ++
i) {
1368 for (
i = 1;
i <
n_;
i++) {
1386 }
else if (a >= .999) {
1399 if (a <= sec_->pt3d[
i].arc) {
1403 float t1 = (a - a1) / (a2 - a1);
1404 x =
x_[
i] * t1 +
x_[
i - 1] * (1. - t1);
1405 y =
y_[
i] * t1 +
y_[
i - 1] * (1. - t1);
1423 if (
t->test(TelltaleState::is_enabled_active)) {
1426 }
else if (
t->test(TelltaleState::is_enabled)) {
1427 if (
color_ == sec_sel_color()) {
1496 auto const n =
sec->nnode - 1;
1502 for (
int i = 0;
i <
n; ++
i) {
1533 printf(
"xmin_=%g a.left=%g ymin_=%g a.bottom=%g xmax_=%g a.right=%g\n",
1547 if (!
pvar_.empty()) {
1550 if (
sec->nnode == 2) {
1557 color = cv->no_value();
1569 }
else if (
sec->npt3d > 2) {
1595 for (iseg = 0; iseg <
sec->nnode - 1; ++iseg) {
1602 color = cv->no_value();
1609 xend = double(iseg + 1) * dseg;
1610 for (; i3d <
sec->npt3d; ++i3d) {
1613 if (a3dnew > xend) {
1614 frac = (a3dnew - xend) / dseg;
1639 for (
int iseg = 0; iseg <
sec->nnode - 1; ++iseg) {
1646 color = cv->no_value();
1671 float len, f1, f2, d, x1, x2, y1, y2, a, aa;
1678 if ((aa - a) < 1e-5) {
1681 f1 = (a1 - a) / (aa - a);
1682 f2 = (a2 - a) / (aa - a);
1684 x1 = f1 * d +
x_[
i];
1685 x2 = f2 * d +
x_[
i];
1687 y1 = f1 * d +
y_[
i];
1688 y2 = f2 * d +
y_[
i];
1691 float d1, d2, t1, t2;
1694 d1 = f1 * (t2 - t1) + t1;
1695 d2 = f2 * (t2 - t1) + t1;
1721 float perp1[2], perp2[2], x, y;
1727 if (b && (perp1[0] != perp2[0] || perp1[1] != perp2[1])) {
1729 xt[0] = x + d * perp1[0];
1730 yt[0] = y + d * perp1[1];
1731 xt[1] = x - d * perp2[0];
1732 yt[1] = y - d * perp2[1];
1733 xt[2] = x - d * perp1[0];
1734 yt[2] = y - d * perp1[1];
1735 xt[3] = x + d * perp2[0];
1736 yt[3] = y + d * perp2[1];
1739 c->move_to(xt[0], yt[0]);
1740 for (
i = 1;
i < 4; ++
i) {
1741 c->line_to(xt[
i], yt[
i]);
1755 float darc = 1. / float(
sec_->
nnode - 1);
1757 float x = ds * iseg;
1764 float x1, x2, y1, y2;
1765 x1 = darc * iseg * (
x_[1] -
x_[0]) +
x_[0];
1766 x2 = darc * (iseg + 1) * (
x_[1] -
x_[0]) +
x_[0];
1767 y1 = darc * iseg * (
y_[1] -
y_[0]) +
y_[0];
1768 y2 = darc * (iseg + 1) * (
y_[1] -
y_[0]) +
y_[0];
1771 float d1, d2, t1, t2;
1774 d1 = darc * iseg * (t2 - t1) + t1;
1775 d2 = darc * (iseg + 1) * (t2 - t1) + t1;
1852 float x, y, rx, ry, d,
norm;
1866 c->move_to(x1 + rx * d, y1 + ry * d);
1867 c->line_to(x1 - rx * d, y1 - ry * d);
1869 c->line_to(x2 - rx * d, y2 - ry * d);
1870 c->line_to(x2 + rx * d, y2 + ry * d);
1876 xt[0] = x1 + rx * d;
1877 yt[0] = y1 + ry * d;
1878 xt[1] = x1 - rx * d;
1879 yt[1] = y1 - ry * d;
1881 xt[2] = x2 - rx * d;
1882 yt[2] = y2 - ry * d;
1883 xt[3] = x2 + rx * d;
1884 yt[3] = y2 + ry * d;
1890 if (x <= 0.0 || x >= 1.0) {
1920 if (!
good() || !h.event() || h.event()->type() != Event::down)
1923 Coord y = h.bottom();
1926 if (h.event()->pointer_button() == Event::left) {
1931 if (
s->selected()) {
1932 Coord x1 =
s->selected()->how_near(x, y);
1940 s->selected(
this, x, y);
1941 if (
s->section_handler()) {
1942 h.target(depth,
this, 0, (
s->section_handler(
this)));
1957 for (
int i = 1;
i <
n; ++
i) {
1964 std::max(
float(std::abs(
sec_->
pt3d[
i - 1].
d) / 2.),
1975 for (
int i = 1;
i <
n; ++
i) {
1987 float darc, len, dlen1;
1988 for (
int i = 1;
i <
n; ++
i) {
1999 if (dlen1 <= d + 1e-2) {
2001 }
else if (len <= d + 1e-2) {
2004 darc =
sqrt(dlen1 - d);
2009 d = (d < 0.) ? 0. : d;
2010 d = (d > 1.) ? 1. : d;
2016 }
else if (d > 1. - dx / 4.) {
2019 d = (int(d * (
sec_->
nnode - 1)) + .5) * dx;
2028 for (
i = 0;
i <
n; ++
i) {
2029 if (arc < sec_->pt3d[
i].arc) {
2039 x =
x_[
i - 1] * (1 - frac) +
x_[
i] * frac;
2040 y =
y_[
i - 1] * (1 - frac) +
y_[
i] * frac;
2041 i = (
i > 0 && frac < .5) ?
i - 1 :
i;
2069 PointMark::PointMark(OcShape* sh,
Object* ob,
const Color*
c,
const char style,
const float size)
2081 PointMark::~PointMark() {
2096 sh_->point_mark_remove(ob);
2107 tv.inverse_transform(
x_,
y_, x, y);
2108 a.x_allotment().origin(x);
2109 a.y_allotment().origin(y);
2110 MonoGlyph::draw(
c, a);
2113 void PointMark::set_loc(
Section*
sec,
float x) {
2118 bool PointMark::everything_ok() {
2122 if (pnt && pnt->
sec) {
2127 if (!sec_ || !sec_->prop) {
2135 if (i_ >= sh_->count() || sh_->component(i_) != (
Glyph*)
this) {
2136 i_ = sh_->glyph_index(
this);
2140 sh_->move(i_,
x_,
y_);
2147 if (point_mark_list_) {
2149 for (
i = 0;
i <
cnt; ++
i) {
2150 ((PointMark*) point_mark_list_->component(
i))->
update(
NULL);
2155 ShapeChangeObserver::ShapeChangeObserver(
ShapeScene*
s) {
2162 ShapeChangeObserver::~ShapeChangeObserver() {
2172 volatile_ptr_ref =
NULL;
2176 if (s_->view_all()) {
double nrn_section_orientation(Section *sec)
const char * secname(Section *sec)
name of section (for use in error messages)
void nrn_pushsec(Section *sec)
double nrn_arc_position(Section *sec, Node *node)
Section * nrn_trueparent(Section *sec)
double section_length(Section *sec)
double nrn_connection_position(Section *sec)
int nrn_exists(Symbol *s, Node *node)
int arc0at0(Section *sec)
neuron::container::data_handle< double > nrn_rangepointer(Section *sec, Symbol *s, double d)
const Brush * brush(int) const
const Color * color(int) const
void set(Canvas *, const Allocation &)
const Color * color() const
virtual GlyphIndex glyph_index(const Glyph *)
virtual void save_phase2(std::ostream &)
virtual void save_phase1(std::ostream &)
static HocMark * instance(char style, float size, const Color *, const Brush *)
static bool near_line_segment(Coord x, Coord y, Coord x1, Coord y1, Coord x2, Coord y2, float epsilon)
static float distance_to_line_segment(Coord x, Coord y, Coord x1, Coord y1, Coord x2, Coord y2)
static bool unit_normal(Coord x, Coord y, Coord *perp)
static bool eq(T x, T y, T e)
static void round_range(Coord x1, Coord x2, double &y1, double &y2, int &ntic)
static void box(Requisition &, Coord &x1, Coord &y1, Coord &x2, Coord &y2)
static float norm2(Coord x, Coord y)
static void Detach(Object *, Observer *)
static void Attach(Object *, Observer *)
virtual void update(Observable *)
virtual void disconnect(Observable *)
static void help(const char *)
void notify_detach(Observer *)
void notify_attach(Observer *)
static void polygon(Canvas *, int count, const Coord *x, const Coord *y, const Color *c=NULL, const Brush *b=NULL, bool fill=false)
static std::ostream * idraw_stream
void xplace(int left, int top)
void require(DimensionName, const Requirement &)
virtual void unref() const
void origin(float x, float y, float z)
void rotate(float x, float y, float z, float *tr) const
void rotate_x(float radians)
void rotate_z(float radians)
void rotate_y(float radians)
virtual bool event(Event &)
virtual void damage_all()
virtual void append(Glyph *)
virtual void new_size(Coord x1, Coord y1, Coord x2, Coord y2)
static const Color * default_foreground()
virtual void wholeplot(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
virtual GlyphIndex count() const
virtual void remove(GlyphIndex)
virtual void modified(GlyphIndex)
virtual ~SectionHandler()
ShapeSection * shape_section()
virtual bool event(Event &)
void shape_section(ShapeSection *)
virtual void observe(SectionList *=NULL)
void colorseg(Section *, double, const Color *)
virtual float arc_selected()
ColorValue * color_value_
virtual SectionHandler * section_handler()
virtual float nearest(Coord, Coord)
SectionHandler * section_handler_
virtual ShapeSection * selected()
virtual void name(const char *)
virtual ShapeSection * shape_section(Section *)
virtual void wholeplot(Coord &x1, Coord &y1, Coord &x2, Coord &y2) const
static ShapeScene * current_pick_scene()
virtual void save_phase2(std::ostream &)
virtual void transform3d(Rubberband *rb=NULL)
ShapeChangeObserver * shape_changed_
static ShapeScene * current_draw_scene()
ShapeScene(SectionList *=NULL)
ColorValue * color_value()
PolyGlyph * shape_section_list()
virtual void draw(Canvas *, const Allocation &) const
virtual void draw_seg(Canvas *, const Color *, int iseg) const
virtual void transform3d(Rotation3d *)
virtual void pick(Canvas *, const Allocation &, int depth, Hit &)
int get_coord(double arc, Coord &, Coord &) const
std::vector< Color const * > old_
virtual void size(Coord &l, Coord &b, Coord &r, Coord &t) const
void bevel_join(Canvas *, const Color *, int, float) const
float arc_position(Coord, Coord) const
virtual void request(Requisition &) const
void fastidious_draw(Canvas *, const Color *, int, float, float) const
float how_near(Coord, Coord) const
std::vector< neuron::container::data_handle< double > > pvar_
virtual void selectMenu()
virtual void clear_variable()
virtual void damage(ShapeScene *)
virtual bool near_section(Coord, Coord, Coord mineps) const
Section * section() const
virtual void allocate(Canvas *, const Allocation &, Extension &)
virtual void fast_draw(Canvas *, Coord x, Coord y, bool) const
virtual void setColorseg(const Color *, double, ShapeScene *)
virtual void draw_points(Canvas *, const Color *, int, int) const
void loc(double, Coord &, Coord &)
virtual void setColor(const Color *, ShapeScene *)
virtual void set_range_variable(Symbol *)
void trapezoid(Canvas *, const Color *, int i) const
virtual Scene * scene() const
static XYView * current_draw_view()
static XYView * current_pick_view()
const Transformer & s2o() const
void class2oc(const char *, ctor_f *cons, dtor_f *destruct, Member_func *, Member_ret_obj_func *, Member_ret_str_func *)
#define y_(arg)
Crout matrix decomposition : Forward/Backward substitution.
double chkarg(int, double low, double high)
int hoc_is_object_arg(int narg)
int hoc_is_str_arg(int narg)
void check_obj_type(Object *obj, const char *type_name)
#define TRY_GUI_REDIRECT_ACTUAL_DOUBLE(name, obj)
#define TRY_GUI_REDIRECT_NO_RETURN(name, obj)
#define TRY_GUI_REDIRECT_OBJ(name, obj)
#define TRY_GUI_REDIRECT_ACTUAL_OBJ(name, obj)
Point_process * ob2pntproc_0(Object *ob)
Object ** hoc_objgetarg(int)
#define ITERATE(itm, lst)
Symbol * lookup(const char *)
double norm(const Point3D &p1)
void update(NrnThread *_nt)
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
void nrn_clear_mark(void)
short nrn_value_mark(Section *)
void section_ref(Section *)
void section_unref(Section *)
void nrn_seg_or_x_arg(int iarg, Section **psec, double *px)
short nrn_increment_mark(Section *)
Object *(* nrnpy_seg_from_sec_x)(Section *, double)
int const size_t const size_t n
static HocReturnType component(PyHocObject *po)
void hoc_ivbutton(CChar *name, CChar *action, Object *pyact=0)
void hoc_ivmenu(CChar *, bool add2menubar=false)
void hoc_ivpanel(CChar *, bool h=false)
static double remove(void *v)
#define implementRubberCallback(T)
#define RubberCallback(T)
#define declareRubberCallback(T)
static double sh_begin(void *v)
double nrniv_sh_color_list(void *v)
static double sh_select(void *v)
double nrniv_sh_color(void *v)
double ivoc_gr_menu_action(void *v)
double nrniv_sh_color_all(void *v)
static void sh_destruct(void *v)
static double sh_flush(void *v)
static double sh_view_count(void *v)
static double sh_select_action(void *v)
static double sh_save_name(void *v)
static double exec_menu(void *v)
double ivoc_gr_gif(void *)
static double sh_point_mark(void *v)
double ivoc_gr_mark(void *)
double ivoc_gr_menu_tool(void *)
double ivoc_gr_label(void *)
Object ** nrniv_sh_nearest_seg(void *v)
static double sh_printfile(void *v)
double nrniv_sh_nearest(void *v)
double nrniv_sh_rotate(void *v)
Object ** nrniv_sh_selected_seg(void *v)
static double sh_view(void *v)
double ivoc_erase_all(void *)
double ivoc_gr_line(void *)
double ivoc_gr_erase(void *)
static double sh_unmap(void *v)
double ivoc_gr_size(void *)
double nrniv_sh_observe(void *v)
static Member_ret_obj_func retobj_members[]
static void * sh_cons(Object *ho)
static Member_func sh_members[]
static double sh_point_mark_remove(void *v)
double nrniv_sh_push(void *v)
double nrniv_len_scale(void *v)
static double sh_show(void *v)
double ivoc_gr_begin_line(void *)
Object ** hoc_temp_objptr(Object *)
static int equal(const char *c1, const char *c2)
A point process is computed just like regular mechanisms.