/*
fixme: default should be no callback.
*/
- set_extent_callback (molecule_extent, X_AXIS);
- set_extent_callback (molecule_extent, Y_AXIS);
pscore_l_=0;
lookup_l_ =0;
mutable_property_alist_ = SCM_EOL;
smobify_self ();
- set_elt_property ("dependencies", SCM_EOL);
- if (get_elt_property ("interfaces") == SCM_UNDEFINED)
- set_elt_property ("interfaces", SCM_EOL);
+ char const*onames[] = {"X-offset-callbacks", "Y-offset-callbacks"};
+ char const*enames[] = {"X-extent-callback", "Y-extent-callback"};
+
+ for (int a = X_AXIS; a <= Y_AXIS; a++){
+ SCM l = get_elt_property (onames[a]);
+
+ if (scm_ilength (l) >=0)
+ {
+ dim_cache_[a].offset_callbacks_ = l;
+ dim_cache_[a].offsets_left_ = scm_ilength (l);
+ }
+ else
+ {
+ programming_error ("[XY]-offset-callbacks must be a list");
+ }
+
+ SCM cb = get_elt_property (enames[a]);
+
+ /*
+ Should change default to be empty?
+ */
+ if (!gh_procedure_p (cb) && !gh_pair_p (cb))
+ cb = molecule_extent_proc;
+
+ dim_cache_[a].dimension_ = cb;
+ }
+
+ SCM meta = get_elt_property ("meta");
+ SCM ifs = scm_assoc (ly_symbol2scm ("interfaces"), meta);
+
+ set_elt_property ("interfaces",gh_cdr (ifs));
}
}
-Interval
-Score_element::molecule_extent (Score_element *s, Axis a)
+MAKE_SCHEME_CALLBACK(Score_element,molecule_extent,2);
+SCM
+Score_element::molecule_extent (SCM element_smob, SCM scm_axis)
{
+ Score_element *s = unsmob_element (element_smob);
+ Axis a = (Axis) gh_scm2int (scm_axis);
+
Molecule m = s->get_molecule ();
- return m.extent(a);
+ return ly_interval2scm ( m.extent(a));
}
-Interval
-Score_element::preset_extent (Score_element *s , Axis a)
+MAKE_SCHEME_CALLBACK(Score_element,preset_extent,2);
+
+SCM
+Score_element::preset_extent (SCM element_smob, SCM scm_axis)
{
+ Score_element *s = unsmob_element (element_smob);
+ Axis a = (Axis) gh_scm2int (scm_axis);
+
SCM ext = s->get_elt_property ((a == X_AXIS)
? "extent-X"
: "extent-Y");
Real r = gh_scm2double (gh_cdr (ext));
l *= s->paper_l ()->get_var ("staffspace");
r *= s->paper_l ()->get_var ("staffspace");
- return Interval (l, r);
+ return ly_interval2scm (Interval (l, r));
}
- return Interval ();
+ return ly_interval2scm ( Interval ());
}
return lookup_l_;
}
-void
-Score_element::add_processing()
-{
- assert (status_i_ >=0);
- if (status_i_)
- return;
- status_i_ ++;
-
- do_add_processing();
-}
-
void
Score_element::calculate_dependencies (int final, int busy, SCM funcname)
{
if (gh_procedure_p (proc))
mol = gh_apply (proc, gh_list (this->self_scm (), SCM_UNDEFINED));
-
+
SCM origin =get_elt_property ("origin");
if (!unsmob_input (origin))
origin =ly_symbol2scm ("no-origin");
mol = gh_cons (gh_list (origin, gh_car (mol), SCM_UNDEFINED), gh_cdr (mol));
}
-
- return create_molecule (mol);
+
+ Molecule m (create_molecule (mol));
+
+ /*
+ This is almost the same as setting molecule-callback to #f, but
+ this retains the dimensions of this element, which means that you
+ can erase elements individually. */
+ if (to_boolean (get_elt_property ("transparent")))
+ m = Molecule (m.extent_box (), SCM_EOL);
+
+ return m;
}
}
-void
-Score_element::do_add_processing()
-{
-}
-MAKE_SCHEME_CALLBACK(Score_element,brew_molecule)
+
+MAKE_SCHEME_CALLBACK(Score_element,brew_molecule,1)
/*
ugh.
{
if (e)
{
- Pointer_group_interface gi (this, "dependencies");
- gi.add_element (e);
+ Pointer_group_interface ::add_element (this, "dependencies",e);
+
}
else
programming_error ("Null dependency added");
{
mutable_property_alist_ = SCM_EOL;
immutable_property_alist_ = SCM_EOL;
- set_extent_callback (0, Y_AXIS);
- set_extent_callback (0, X_AXIS);
+
+ set_extent_callback (SCM_EOL, Y_AXIS);
+ set_extent_callback (SCM_EOL, X_AXIS);
for (int a= X_AXIS; a <= Y_AXIS; a++)
{
- dim_cache_[a].off_callbacks_.clear ();
+ dim_cache_[a].offset_callbacks_ = SCM_EOL;
+ dim_cache_[a].offsets_left_ = 0;
}
}
Score_element::get_offset (Axis a) const
{
Score_element *me = (Score_element*) this;
- while (dim_cache_[a].off_callbacks_.size ())
+ while (dim_cache_[a].offsets_left_)
{
- Offset_callback c = dim_cache_[a].off_callbacks_[0];
- me->dim_cache_[a].off_callbacks_.del (0);
- Real r = (*c) (me,a );
+ int l = --me->dim_cache_[a].offsets_left_;
+ SCM cb = scm_list_ref (dim_cache_[a].offset_callbacks_, gh_int2scm (l));
+ SCM retval = gh_call2 (cb, self_scm (), gh_int2scm (a));
+
+ Real r = gh_scm2double (retval);
if (isinf (r) || isnan (r))
{
programming_error (INFINITY_MSG);
}
-Interval
-Score_element::point_dimension_callback (Score_element* , Axis)
+MAKE_SCHEME_CALLBACK(Score_element,point_dimension_callback,2);
+SCM
+Score_element::point_dimension_callback (SCM , SCM )
{
- return Interval (0,0);
+ return ly_interval2scm ( Interval (0,0));
}
bool
Score_element::empty_b (Axis a)const
{
- return !dim_cache_[a].extent_callback_l_;
+ return ! (gh_pair_p (dim_cache_[a].dimension_ ) ||
+ gh_procedure_p (dim_cache_[a].dimension_ ));
}
+/*
+ TODO: add
+
+ Score_element *refpoint
+
+ to arguments?
+ */
Interval
-Score_element::extent (Axis a) const
+Score_element::extent (Score_element * refp, Axis a) const
{
+ Real x = relative_coordinate (refp, a);
+
+
Dimension_cache * d = (Dimension_cache *)&dim_cache_[a];
- if (!d->extent_callback_l_)
- {
- d->dim_.set_empty ();
- }
- else if (!d->valid_b_)
+ Interval ext ;
+ if (gh_pair_p (d->dimension_))
+ ;
+ else if (gh_procedure_p (d->dimension_))
{
- d->dim_= (*d->extent_callback_l_ ) ((Score_element*)this, a);
- d->valid_b_ = true;
+ /*
+ FIXME: add doco on types, and should typecheck maybe?
+ */
+ d->dimension_= gh_call2 (d->dimension_, self_scm(), gh_int2scm (a));
}
+ else
+ return ext;
- Interval ext = d->dim_;
-
- if (empty_b (a))
+ if (!gh_pair_p (d->dimension_))
return ext;
+
+ ext = ly_scm2interval (d->dimension_);
SCM extra = get_elt_property (a == X_AXIS
? "extra-extent-X"
ext.unite (Interval (s * gh_scm2double (gh_car (extra)),
s * gh_scm2double (gh_cdr (extra))));
}
+
+ ext.translate (x);
return ext;
}
String
Score_element::name () const
{
- SCM nm = get_elt_property ("name");
-
- return nm == SCM_EOL ? classname (this) :ly_scm2string (nm) ;
+ SCM meta = get_elt_property ("meta");
+ SCM nm = scm_assoc (ly_symbol2scm ("name"), meta);
+ nm = (gh_pair_p (nm)) ? gh_cdr (nm) : SCM_EOL;
+ return gh_string_p (nm) ?ly_scm2string (nm) : classname (this);
}
void
-Score_element::add_offset_callback (Offset_callback cb, Axis a)
+Score_element::add_offset_callback (SCM cb, Axis a)
{
- dim_cache_[a].off_callbacks_.push (cb);
+ if (!has_offset_callback_b (cb, a))
+ {
+ dim_cache_[a].offset_callbacks_ = gh_cons (cb, dim_cache_[a].offset_callbacks_ );
+ dim_cache_[a].offsets_left_ ++;
+ }
}
bool
-Score_element::has_extent_callback_b (Extent_callback cb, Axis a)const
+Score_element::has_extent_callback_b (SCM cb, Axis a)const
{
- return cb == dim_cache_[a].extent_callback_l_;
+ return scm_equal_p (cb, dim_cache_[a].dimension_);
}
bool
Score_element::has_extent_callback_b (Axis a) const
{
- return dim_cache_[a].extent_callback_l_;
+ return gh_procedure_p (dim_cache_[a].dimension_);
}
bool
-Score_element::has_offset_callback_b (Offset_callback cb, Axis a)const
+Score_element::has_offset_callback_b (SCM cb, Axis a)const
{
- for (int i= dim_cache_[a].off_callbacks_.size (); i--;)
- {
- if (dim_cache_[a].off_callbacks_[i] == cb)
- return true;
- }
- return false;
+ return scm_memq (cb, dim_cache_[a].offset_callbacks_) != SCM_BOOL_F;
}
void
-Score_element::set_extent_callback (Dim_cache_callback dc, Axis a)
+Score_element::set_extent_callback (SCM dc, Axis a)
{
- dim_cache_[a].extent_callback_l_ = dc ;
+ dim_cache_[a].dimension_ =dc;
}
-
void
Score_element::set_parent (Score_element *g, Axis a)
{
dim_cache_[a].parent_l_ = g;
}
-MAKE_SCHEME_CALLBACK(Score_element,fixup_refpoint);
+MAKE_SCHEME_CALLBACK(Score_element,fixup_refpoint,1);
SCM
Score_element::fixup_refpoint (SCM smob)
{
Score_element * s = (Score_element*) SCM_CELL_WORD_1(ses);
scm_gc_mark (s->immutable_property_alist_);
scm_gc_mark (s->mutable_property_alist_);
+
+ for (int a =0 ; a < 2; a++)
+ {
+ scm_gc_mark (s->dim_cache_[a].offset_callbacks_);
+ scm_gc_mark (s->dim_cache_[a].dimension_);
+ }
if (s->parent_l (Y_AXIS))
scm_gc_mark (s->parent_l (Y_AXIS)->self_scm ());
static SCM interfaces_sym;
-
static void
init_functions ()
{
interfaces_sym = scm_permanent_object (ly_symbol2scm ("interfaces"));
-
- scm_make_gsubr ("ly-get-elt-property", 2, 0, 0, (SCM(*)(...))ly_get_elt_property);
- scm_make_gsubr ("ly-set-elt-property", 3, 0, 0, (SCM(*)(...))ly_set_elt_property);
- scm_make_gsubr ("ly-get-spanner-bound", 2 , 0, 0, (SCM(*)(...)) spanner_get_bound);
+
+ scm_make_gsubr ("ly-get-elt-property", 2, 0, 0, (Scheme_function_unknown)ly_get_elt_property);
+ scm_make_gsubr ("ly-set-elt-property", 3, 0, 0, (Scheme_function_unknown)ly_set_elt_property);
+ scm_make_gsubr ("ly-get-spanner-bound", 2 , 0, 0, (Scheme_function_unknown) spanner_get_bound);
}
bool
Score_element::has_interface (SCM k)
{
- // if (mutable_property_alist_ == SCM_EOL)
- // return false;
-
SCM ifs = get_elt_property (interfaces_sym);
return scm_memq (k, ifs) != SCM_BOOL_F;
ADD_SCM_INIT_FUNC(scoreelt, init_functions);
-
+IMPLEMENT_TYPE_P(Score_element, "ly-element?");