<mixin>
<mixin> is like <class> but rather than creating something you can instantiate, <mixin> creates a template that can be mixed in (added to) more than one other class. A <mixin> is like an interface, but it is allowed to have state and implementation.

Usage

This page describes an advanced usage of <mixin> . For a more basic usage, see Chapter 33. Extending Classes in the Developers Guide.

<mixin> s are a shorthand for creating intermediate anonymous classes (exactly as we do in our implementation):

<class name="a" extends="d" with="b,c" /> 

is meant to be _exactly_ equivalent to:

							
<class name="cd" extends="d" implements="c">
 ... body of c ...
</class>

<class name="bcd" extends="cd" implements="b">
 ... body of b ...
</class>

<class name="a" extends="bcd">
 ... body of a ...
</class>

Except that the intermediate classes cd and bcd are anonymous. So it is a shorthand for re-using the mixin bodies in multiple classes with potentially different superclasses. The primary difference between trait and mixin is that trait simply disallows any case where you could not simply use textual substitution, whereas mixin appeals to the class inheritance semantics to resolve those cases (including being able to make super calls to overridden mixin methods). In the cases where there are no conflicting attributes, mixins can be optimized to traits and you can eliminate the intermediate classes.

The simple model of how mixin inheritance works is that if you say:

<class name="sundae" extends="icecream" with="sauce,whippedcream,nuts">

methods are looked up first in the class ( sundae ) then in each of the mixins ( sauce , then whippedcream , then nuts ) and then in the super class chain ( icecream and then in any superclasses of icecream ). The mixin s are searched left-to-right, and then the superclass chain is searched. The key point is that mixin s precede the superclass, and mixin s are searched in the order they are listed. This same search order is used when looking for methods, or attributes, or invoking super calls.

The following example demonstrates the use of mixins. See the comments in the code for a description of how it works.

<canvas width="100%" height="400" layout="axis: y; spacing: 25">
    <!--- The base class of all ice cream desserts -->
    <class name="icecream">
      <attribute name="flavor" type="color" value="vanilla"/>
      <method name="toString">
        return this.presentAttribute('flavor', 'color') + " icecream";
      </method>
      <view width="100%" height="100%" bgcolor="${parent.flavor}"/>
    </class>

    <!--- This parlour only offers walnuts -->
    <class name="walnuts" extends="view">
      <attribute name="bgcolor" value="brown"/>
      <attribute name="ground" type="boolean" value="false"/>
      <attribute name="opacity" value="${this.ground?.5:1}"/>
      <method name="grind">
        this.setAttribute('ground', true);
      </method>
      <method name="toString">
        return (this.ground?"ground ":"") + "walnuts";
      </method>
    </class>

    <!--- This is the 'toppings' mixin, which could be added to various desserts -->
    <mixin name="toppings">
      <attribute name="sauce" type="color" value="chocolate"/>
      <attribute name="whippedcream" type="boolean" value="true"/>
      <attribute name="cherry" type="boolean" value="true"/>

      <view name="layers" width="100%" layout="axis: y; spacing: 0" bgcolor="${canvas.bgcolor}">
        <view width="25" height="25" x="${(parent.width - this.width)/2}" visible="${classroot.cherry}" bgcolor="red"/>
        <walnuts name="nuts" width="100%" height="10" visible="${classroot.nuts}" ground="${classroot.ground}"/>
        <view width="100%" height="25" visible="${classroot.whippedcream}" bgcolor="snow"/>
        <view width="100%" height="10" bgcolor="${classroot.sauce}"/>
      </view>

      <attribute name="nuts" type="boolean" value="false"/>
      <attribute name="ground" type="boolean" value="false"/>

      <method name="toString">
        return super.toString() + " with " +
          this.presentAttribute('sauce', 'color') + " sauce" +
          (this.whippedcream?", whipped cream":"") +
          (this.nuts?(", " + this.layers.nuts.toString()):"") +
          (this.cherry?", with a cherry on top":"");
      </method>
    </mixin>

    <!---
      Ok!  Let's build a dessert.  A sundae is based on icecream, and
      we mixin toppings.  The resulting class has the attributes of
      icecream and toppings, without us having to make toppings
      inherit from icecream.
    -->
    <class name="sundae" extends="icecream" with="toppings">
      <method name="toString">
        return super.toString() + " sundae";
      </method>
    </class>

    <class name="sundae2" extends="icecream" with="toppings">
      <method name="toString">
        return super.toString() + " sundae";
      </method>
    </class>
    <sundae2 visible="false"/>

    <attribute name="sauces" value="['chocolate', 'lavender', 'olive', 'orange', 'plum', 'snow', 'thistle', 'violet']"/>
    <attribute name="icecreams" value="['bisque', 'honeydew', 'lemonchiffon', 'lime', 'mintcream', 'papayawhip', 'peachpuff', 'salmon', 'tomato', 'wheat']"/>

    <!--- Here's how you order your sundae -->
    <view name="recipe" x="5%" width="90%" layout="axis: y; spacing: 3">
      <text>
        Build your own sundae:
      </text>
      <checkbox name="cherry">Cherry?</checkbox>
      <view name="nutchoice" layout="axis: x; spacing: 3">
        <checkbox name="nuts">Nuts?</checkbox>
        <checkbox name="ground" enabled="${parent.nuts.getValue()}">Ground?</checkbox>
      </view>
      <checkbox name="whippedcream">Whipped Cream?</checkbox>
      <view name="saucechoice" layout="axis: x; spacing: 3">
        <text>Sauce:</text>
        <combobox name="sauce" editable="false">
          <replicator nodes="$once{canvas.sauces}">
            <textlistitem text="${this.presentValue()}" type="color"/>
          </replicator>
        </combobox>
      </view>
      <view name="icecreamchoice" layout="axis: x; spacing: 3">
        <text>Ice Cream:</text>
        <combobox name="icecream" editable="false">
          <replicator nodes="$once{canvas.icecreams}">
            <textlistitem text="${this.presentValue()}" type="color"/>
          </replicator>
        </combobox>
      </view>
    </view>

    <!--- And here's your WYSIWYG sundae -->
    <sundae id="yoursundae" width="100" height="150" x="${(this.parent.width - this.width)/2}" flavor="${recipe.icecreamchoice.icecream.getValue()}" sauce="${recipe.saucechoice.sauce.getValue()}" nuts="${recipe.nutchoice.nuts.getValue()}" ground="${recipe.nutchoice.ground.getValue()}" whippedcream="${recipe.whippedcream.getValue()}" cherry="${recipe.cherry.getValue()}"/>

    <!--- If you want the recipe for your sundae, push the button -->
    <button x="${(this.parent.width - this.width)/2}" onclick="description.format('You built a %s', yoursundae)">
      Tell me the recipe!
    </button>

    <!--- And the recipe will show up here -->
    <text name="description" x="5%" width="90%" multiline="true"/>
</canvas>