本文へジャンプ

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

送信されたすべての情報は安全です。

  • 閉じる [x]

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


送信されたすべての情報は安全です。

  • 閉じる [x]

SVGとXForms: Rendering Custom Content (カスタム・コンテンツの描画)

新しいSVG 1.2でXMLベースの拡張機構を使う

Antoine Quint (antoine.quint@fuchsia-design.com), SVG Consultant and Research Scientist, Fuchsia Design
Antoine Quintは独立のSVGコンサルタント兼研究者で、招聘専門家としてW3CのSVGワーキング・グループに参加しています。SVG関連の講演やセミナー講師も場所さえ良ければ喜んで引き受け、下請け仕事もしています。家はパリにあり、猫のStig Elmerと一緒に住んでいます。古くからの友人Robin Berjonと共著の著作を執筆中ですが、だいぶ遅れ気味です。

概要: 最初のSVG 1.0 (Scalable Vector Graphics仕様)は、XMLで表現されたグラフィックスの標準として、インタラクティブでアニメーション化された2次元グラフィックスの基を築きました。それ以来W3CのSVGワーキング・グループは、さらに進んでSVGをWebやデスクトップ・アプリケーションの開発に使いやすいように機能を高めることに集中してきました。SVG 1.2で導入されたフィーチャのうち最も期待が持てるのは、RCC (Rendering Custom Content) であり、これはSVG文書内で異なったXML名前空間を上手に組み合わせる非常にきれいなXML中心の拡張機構を提供するものです。この記事ではRCCの機構を紹介しながら、単純な押しボタン・ウィジェットを作っていきます。

日付:  2003年 11月 25日
レベル:  中級 この記事の原文:  英語
アクティビティー: 1666 ビュー
お気軽にご意見・ご感想をお寄せください: 


ここ2~3年の間SVGコミュニティでは、SVG文書内の名前空間を上手に組み合わせて使用するために、SVGにおいてXML基盤を活用する新しい方法を調査してきました。その中で、SVG文書内においてインラインで使用されるカスタムXMLマークアップが、ユーザ・インターフェースにとって主要な使用事例として浮かび上がってきました。RCC (Rendering Custom Content) は、SVG 1.2の最新ドラフトでとりあげられた技術で、より洗練された拡張機能として新しいフレームワークを提供するものです。このフレームワークにより、カスタムXML文法をSVG文書内にスムーズに統合できるようになります。このシリーズの入門で説明した通り、RCCは2つのマークアップを使いこなすための基盤となるもので、SVGとXFormsの統合に重要な役割を担っています。この記事ではRCCの基本を紹介しながら、最初のユーザ・インターフェース・ウィジェット(押しボタン)の実装を一通り説明し、より充実したユーザ・インターフェース・アプリケーションのデモをお見せします。

RCCの基本

RCCを使った簡単なボタン・ウィジェットのコーディングに取りかかる前に、RCC要素の基本と、新しく加わった要素について説明しましょう。

XMLとグラフィックスをバインドする

RCCを使うことで、外部名前空間を持つ、ある所定の要素がSVG文書内でどう振る舞うべきかを規定できます。RCCに取り組むにあたって書かなければならないコードとして、最も基本的なものは次のようなものです。


リスト1. RCC環境の設定
                
<extensionsDefs namespace="http://ns.example.org/MyCustomNamespace/">
  <elementDef name="myCustomElement">
    <prototype>
      <!-- SVG markup specifying rendering here -->
    </prototype>
  </elementDef>
</extensionsDefs>

リスト1では、2つの新しいSVG要素が導入されています。<extensionDefs>は、最上位レベルの要素で、所定の名前空間におけるすべての定義された要素はこの中に含まれます。この名前空間は、単に値としてURIを持ったnamespace属性(そのものズバリの名称ですが・・・)で規定されています。今後の混乱を避けるために言っておきますが、この属性はXMLのxmlns属性のようには振る舞いません。ここでの名前空間は常にSVGなのです。このnamespace属性は、単にカスタム要素を記述する名前空間のことを示しています。概念的には、<extensionDefs>でライブラリが定義できるようになりますが、今度はこの名前空間ライブラリの中に何があるのかを定義する必要があります。要素を定義するには<elementDef>要素を使い、その名前をname属性で規定する必要があります。

基本的にRCCは、非SVGのXML要素をSVGツリーに組み合わせるバインド機構です。ところがRCCはすべてのバインドを考慮して作られているわけではありません。RCCの機構は、何らかの対話型の表現を持つカスタムXMLマークアップをバインドできるようにし、それによってSVG断片にマッピングすることを主眼に置いているのです。(第1回の)入門でお話ししたように、RCCの世界におけるこのSVG断片は、実際にはシャドウ・ツリーなのです。シャドウ・ツリーがもたらす魔法の数々についてはいくら強調してもしきれず、とは言え十分に理解しておく必要があるので、これについては後でまた触れたいと思います。カスタム要素を予め設定されたシャドウ・ツリーにリンクするには、新しい<prototype>要素を使う必要があります。この要素の内容は、バインド時に定義される要素の各インスタンスのシャドウ・ツリーに自動的にコピーされます。

バインドはドキュメントの生涯において2回、異なった時点に発生します。最初はロード時です。SVGの実装が最初に、そのドキュメントに既存の<extensionDefs>要素がないかをチェックし、どんな外部要素が既知であるかを調べます。次にツリーの残りの部分を構文解析しながら、既知の要素を検出する度にSVGの実装がRCCバインド機構を始動します。既知の要素がツリーに追加された時(例えばDOMコールのinsertChild() など)にもバインドが起こります。これによってバインド機構全体が存続していることになります。これは、XSLTがXML要素を他のXML出力とバインドするのにテンプレートを使う方法とは大きく違う重要な点です(XSLTによる方法は本質的に一度だけ実行する、バッチ処理操作です)。

シャドウ・ツリー

バインド機構がより明確になったので、RCCにおいてシャドウ・ツリーがいかに重要か、またそれをどのように利用するかを完全に理解することが非常に重要です。前回の記事で説明した通り、カスタム要素をシャドウ・ツリーを使って表現する大きな利点の一つは、ドキュメント・ツリーが乱されることなく、健全なまま保てるという点です。RCCを使ってユーザ・インターフェース・ウィジェットのようなコンポーネントを書くには、抽象的なマークアップに対してSVG表現におけるスクリプトとの連携を必要とするでしょう。シャドウ・ツリーではこのコード・ロジックは、(必要あれば使えるのですが)外部コードには容易に使えないSVGサブ・ツリーに依存します。先ほどとりあげた、RCCサポートのために追加された要素と並んで、SVG 1.2ではカスタム要素の全インスタンスにDOMインターフェースSVGShadowable が追加されています。このインターフェースを使えば、myCustomElement.shadowTreeのようなコールでカスタム要素のシャドウ・ツリーにアクセスすることができるのです。

RCCとDOMイベント

カスタム要素のシャドウ・ツリーにはいつでもDOMでアクセスできるので、コンポーネントを操作する場合にはliveバインドを使うことができます。カスタム要素において、トリガとなる適切なDOMイベントを監視(リスン)すれば、そのカスタム要素に何が起きているのか常に通知を受けることができます。RCCバインド機構では、2つの新しいバインド固有のイベントが提供されています。

  • SVGBindBegin: 初期バインド・フェーズ(カスタム要素は構文解析されたが、シャドウ・ツリーはまだ生成されておらず描画も行われていない状態)に対応します。
  • SVGBindEnd: バインド・フェーズが完了した(要素がバインドされ、描画が行われた状態)ことを通知します。

このカスタム要素を存続させたい場合には、DOM変更イベント(例えば属性修正のためのDOMAttrModifiedや、内部サブツリーの変化に対応するカスタム・コンテナを扱う際に使用するDOMSubTreeModifiedなど)に依存しなければなりません。

モジュール性

<extensionDefs>を使ってライブラリ定義の概念について簡単に言及しました。この概念は極めて妥当なもので、インラインの拡張を、その拡張を使う全てのドキュメント毎に毎回再定義する必要はありません。実際のところ、ライブラリが定義された場所の指定にxlink:href属性を使い、ライブラリをインポートすることができるのです。ですから例えば、RCCベースのXForms実装における拡張を次のように定義して使うことができるのです。


リスト2. 複数ファイルにまたがるRCC拡張アーキテクチャ
                
XFormsImplementation.svg
<svg version="1.2">
  <extensionDefs id="xforms" namespace="http://www.w3.org/2002/xforms">
    <!-- implementation -->
  </extensionDefs>
</svg>
SomeFileUsingSVGandXFormsWithYourSpiffyRCCImplementation.svg
<svg version="1.2">
  <extensionDefs xlink:href="XFormsImplementation.svg#xforms" />
  <!-- some code that can use both XForms and SVG elements -->
</svg>

単純でありながら洗練されたライブラリ・アーキテクチャのおかげで、ほとんどどんな人でもRCCライブラリを作り、オンライン上に置き、そしてWeb上の誰もが使えるようにすることができるのです。これによりRCCを使ったSVGアプリケーションの開発が容易となり、近い将来フリー・ライブラリの提供を狙ったコミュニティ主導の作業を活発化させることにもつながります。もう一つ、<prototype>要素のコンテンツは、おなじみのSVGグラフィックス要素に限定されてはおらず、RCC定義のカスタム要素も含み得るということも言っておきたいと思います。ですからRCCは再入可能でもあるのです。他のコンポーネントを再利用したり、その上に構築されるコンポーネントを作ったりする上で、この再帰的な面が非常に好都合なのです。これをすべて組み合わせれば素晴らしいフレームワークができるのです。では先に進んで、少し作業をしてみましょう。


RCCを使って開発する: <ui:button>

導入部で示したように、RCCの普通の使い方はUIウィジェットを作ることです。簡単なものであっても、良いUIウィジェットを作るには複雑な作業が必要です。ここでは、(グラフィック的にもプログラム的にも)非常に簡単な押しボタンを作る方法を説明しましょう。

マークアップ

RCCアーキテクチャにおいてマークアップは、実装すべき機能の設計図としての役割を持っています。SVGとRCC機構を使って設計したいコンポーネントが頭の中にある場合、おそらく最初にすることは、頭の中にあることを紙の上に書き出して、マークアップがどう見えるべきか把握することでしょう。ここでは、テキスト・ラベルを持った、簡単な押しボタンを設計しています。簡単に・・・と言う方針を貫くことにして、形状と位置の属性を持ち、子ノードとしてテキスト・ラベルを持った単純な要素を作ります。

<ui:button x="10" y="40" width="150">ui:button</ui:button>

そして、これが次のように見えるのです。


図1. 描画された<ui:button>要素
図1. 描画された<ui:button>要素

これで<button>要素ができました。もし私が善良な市民であれば、これに合致するスキーマの一片を用意してこの要素を文書化するところでしょう。でもここではそれよりも、読者が自分のコンポーネントを設計する時に正しい判断ができるようにSVGの側に集中することにします。この<button>要素は、SVG要素ではないのでSVGとは違った名前空間にある必要があります。読者はおそらく、私が先ほどの例でui接頭辞を使ったことに気がついたでしょう。そして、この接頭辞は、SVGファイルのルート要素<svg>で定義されているのです。


リスト3. この文書での名前空間の宣言
                
<svg  xmlns="http://www.w3.org/2000/svg"
      xmlns:ui="http://xmlns.fuchsia-design.com/ui/"
      xmlns:ev="http://www.w3.org/2001/xml-events"
      version="1.2">

私独自のui名前空間がこれで定義できたので、これ以降(このボタンの異なるインスタンスを実際に配置する際に)このSVGファイルでは、安全に<ui:button>を使うことができます。私の名前空間のURIにアクセスしようなどと思わないでください・・・そこには何もないのです。ここでも改めて読者にお勧めしますが、自身に差し迫ったより複雑な作業に取り組む際には、もっと良い方法を使うようにしてください。またコンポーネントに関する情報を提供するには、RDDLファイルかそれに似たものを使うようにして欲しいと思います。私はあといくつか、別の名前空間と接頭辞を定義しましたが、当然ながら(デフォルトと判断される)SVG名前空間と、(ev接頭辞を持つ)XML Events名前空間を特徴付けるものです。因みに、XML Events勧告は、今やSVG 1.2の一部として義務化されているので、設計および、名前空間付けされた環境の両方が持てることになります。これで次のフェーズに進むことができますが、そこでもまたマークアップが関係してきます。今度はマークアップがコンポーネント定義の本質になります。


リスト4. 私の外部要素を実装するための最初のステップ
                
<extensionDefs namespace="http://xmlns.fuchsia-design.com/ui/">
  <elementDef name="button">
    <prototype>
      <svg id="root" width="0" height="26">
        <rect id="rect" style="stroke: black; fill: lightgray;"
              x=".5" y=".5" rx="5" ry="5" width="0" height="25" />
        <text x="50%" y="65%" style="pointer-events: none; text-anchor: middle;">
          <refContent />
        </text>
      </svg>
    </prototype>
    <script ev:event="SVGBindEnd" type="text/ecmascript">
      new SimpleRCCButton(evt.target);
    </script>
    <script type="text/ecmascript">
      <!-- SimpleRCCButton class -->
    </script>
  </elementDef>
</extensionDefs>

私のライブラリ定義の開始を通知するのは、<extensionDefs>要素で囲まれた部分から始まります。これは、ルート要素<svg>で定義されているように、ui接頭辞がついた名前空間に記述されているものです。その次は、私の<ui:button>要素の定義を開始する<elementDef>要素です。これでSVGの実装に新しいカスタム要素を通知できたので、それがどのように見えるかを<prototype>要素で定義します。先に述べた通り、各カスタム要素のインスタンスからシャドウ・ツリーにコピーされる全てのSVGを置くところがここです。図1で見た通り、私のお粗末なボタンは、中央にテキストがある角の丸い矩形ですが、SVGの持つ強力なグラフィック要素とテキスト機能のおかげで、このSVGプロトタイプが簡単に書けるのです。

<rect>要素のrx属性とry属性を使えば、角を丸めることができます。style属性は、CSSプロパティ(ここでは明るい灰色で塗りつぶし、黒線で枠どり)を指定します。height(高さ)は固定で25、width(幅)は0、・・・ゼロを指定します!?・・・そう、矩形の幅は<ui:button>自体の幅と関係しているのです。後ほどこのプログラムで、適切な時点になったら幅を更新することが分かるでしょう。枠線は親の<svg>要素でクリッピングされないように、x属性とy属性は、どちらも0.5という値になっています。次に<text>要素です。文字列は、text-anchorによって中央揃えで配置されており、マウス・イベントは受け取りません(矩形で全てのマウス・イベントを十分受け取れるし、こうしておくことでユーザが文字の上でボタンをクリックすると変なものが見えてしまうのも避けられます)。文字列は親の<svg>要素で設定される現在のビューポートの中央に置かれます。

読者はおかしなことにも気がついたかも知れません。<svg><rect>も共にid属性を持っているのです。生成された各シャドウ・ツリーにidが複製されてしまうなら、idはどうやってそのユニークさを保てるのでしょう・・・。RCCは、この問題をローカル・スコープのidで解決しています。こうしたidをあちこちに持つ理由は、コードの説明を始めればもっと明確になるでしょう。他にもおかしな所があることに気がついたでしょうか・・・<refContent/>要素です。これもRCCサポートのためにSVG 1.2で導入された新しい要素ですが、このおまじないで、要素のインスタンスを示すDOMツリーが直接参照できるようになるのです。そして、この<refContent/>要素は、シャドウ・ツリーにテキスト・ラベルを貼り付け、そのラベルと常に同期しているのです。

これでグラフィックスのテンプレートは定義できたので、<script>要素にてXML Eventsのevent属性を使って、(ECMAScriptにおける)SVGBindEndイベント用のハンドラを定義します。要素のインスタンスのバインドが完了すると、この囲まれた一行のスクリプトが呼ばれ、単にSimpleRCCButtonクラスの新しいインスタンスを生成します。そしてそのコンストラクタに対し、唯一のパラメータとして要素のインスタンス(イベントのターゲット)へのポインタが渡されます。生成されたECMAScriptオブジェクトは、マークアップで宣言的に行うことができない全てに対して責任を持つことになります。そのためにECMAScriptオブジェクトは、基本的にコントローラとして動作します。その次の<script>要素は、先ほどのサンプルからは切り取られていますが、SimpleRCCButtonクラスの全コードを含むことになります。そのプロセスについては次で説明することにします。マークアップ部分ができたので、今度は本業に戻って少しコードを書く番です!

コード

SimpleRCCButtonクラスがすることは単純です。変更イベント、ユーザ・インターフェース・イベントのどちらにも対応することで、ボタンを存続させるために必要なことをするのです。最初の課題はこのクラスのコンストラクタを書くことで、後で必要になるいくつかの要素からの参照が容易に保てるようにします。


リスト5. SimpleRCCButtonクラスのコンストラクタ
                
function SimpleRCCButton (element) {
  // keep pointers to useful bits
  this.element = element;
  var shadow = this.element.shadowTree;
  this.root = shadow.getElementById('root');
  this.rect = shadow.getElementById('rect');
  // initialize the shadow tree
  this.init();
};

<ui:button>のインスタンスは、コンストラクタ関数のパラメータとして渡されます。そしてこれへの参照をthis.elementに保持します。次にこの要素のインスタンスのシャドウ・ツリーへのポインタ(shadowTree)を変数shadowに登録します。shadowTreeは、SVGShadowableインターフェースのメンバであり、これはRCCによって定義されたカスタム要素の全インスタンスが継承しているものです。さらに、シャドウ・ツリーには追跡が必要な2つのSVG要素が含まれています。先ほどの<prototype>で意味ありげに設定したidを使い、親の<svg>要素はthis.rootとして保存され、一方、角の丸い矩形はthis.rectとして保存されます。ここまでで有用な参照が確立されたので、init()メソッドをコールしてこの要素のシャドウ・ツリーを初期化することができます。


リスト6. SimpleRCCButtonの初期化メソッド
                
SimpleRCCButton.prototype.init = function () {
  // register mutation events on the element instance
  this.element.addEventListener('DOMAttrModified', this, false);
  // register UI events on the shadow tree's rectangle
  this.rect.addEventListener('mousedown', this, false);
  this.rect.addEventListener('mouseup', this, false);
  this.rect.addEventListener('click', this, false);
  // update the position and width of the button
  this.fixButtonPosition();
  this.fixButtonWidth();
};

最初の課題は、要素のインスタンスで起きる(属性値の変化に対応する)DOMAttrModified変更イベントにイベント・リスナーを登録し、ボタンに対してDOMから行われたれた変更を追跡できるようにすることです。次はシャドウ・ツリー上の矩形で生じる各種のマウス・イベント(mousedownmouseupclick)をリスン(監視)することを要求する番です(これらへの反応については後ほど説明しましょう)。これまでの間ずっと、DOMイベントのEventTargetインターフェースにある、一番重要なaddEventListener()メソッドを使ってきていました。今度は、ボタンの位置と大きさに対して最初の手直しをする必要があります。このためにはfixButtonPositionメソッドとfixButtonWidthメソッドを使って、シャドウ・ツリーに少し手を加える必要があります。


リスト7. SimpleRCCButtonクラスの更新メソッド
                
SimpleRCCButton.prototype.fixButtonPosition = function () {
  this.root.setAttribute('x', this.element.getAttribute('x'));
  this.root.setAttribute('y', this.element.getAttribute('y'));
};
SimpleRCCButton.prototype.fixButtonWidth = function () {
  var width = parseInt(this.element.getAttribute('width'));
  this.root.setAttribute('width', width + 1);
  this.rect.setAttribute('width', width);
};

どちらのメソッドにも非常に単純なDOMのコーディングしかありません。基本的に属性値は要素のインスタンスから読みとられ、シャドウ・ツリーの適切な場所にコピーされます。ボタンの位置に関しては、シャドウ・ツリー上の<svg>要素に対してx属性とy属性を設定することで更新します。ボタンの幅を更新するのはもう少し複雑です。幅は、この矩形の幅として指定された値でコピーされるのですが、矩形の枠線のための空間が残るように、<svg>要素に対しては、1単位(unit)だけ増加しています。

イベント・リスナーにイベントを登録したときに、(2番目のパラメータとして渡した)thisがDOMイベントのEventListenerインターフェースのインスタンスであることに読者は気がついたでしょう。こうしたのは、EventListenerインターフェースが、単一のhandleEvent()メソッドをもつ機構であり、イベント・リスナーであるどのオブジェクトからでも実行されるようにしたかったからです。この場合では、登録されたイベントの何れかが発生する毎にコントロール・オブジェクトがhandleEvent()を呼び出します。ではこのメソッドがどんな風なものなのか、このボタンをインタラクティブなものにするためにイベントがどのように操作されているかを見てみましょう。


リスト8. SimpleRCCButtonクラスのイベント処理
                
SimpleRCCButton.prototype.handleEvent = function (evt) {
  var type = evt.type;
  if (type == 'DOMAttrModified') {
    this.fixButtonPosition();
    this.fixButtonWidth();
  } else if (type == 'mousedown') {
    this.rect.style.setProperty('fill', 'pink');
    window.captureMouse(evt, this.rect);
  } else if (type == 'mouseup') {
    this.rect.style.setProperty('fill', 'lightgray');
  } else if (type == 'click') {
    var event = document.createEvent('ButtonPush');
    this.element.dispatchEvent(event);
  }
};

この関数は、言うまでもなく唯一のパラメータとしてイベントのみを受け取ります。それでは、最も重要なことから順を追って説明して行きましょう。先ずどのようなタイプのイベントを受け取ったかを判断する必要があります。もしそれが、要素のインスタンスにおける属性の一つで発生した変更イベントであれば、ボタンの概観を更新するために2つのメソッドを呼び出します。両方のメソッドを毎回呼ぶのはちょっと面倒ですが、単純にするという目的でこうしました。本当は全ての更新メソッドを呼ぶ前に、どの属性が変更されたかチェックする時間をかけることもできたのですが・・・。読者が自分でコードを書く時にはもっときちんとしてくれることを信ずることにします。次はマウス・イベントの処理です。

押しボタンとして実装しているので、マウスがクリックされた時にボタンのグラフィックスで、ボタンが押されたことが視覚的に分かるようにした方が良いようです。そこで、シャドウ・ツリー上の矩形がmousedownイベントを受け取ったときにCSSのfillプロパティを少し派手なもの・・・例えばピンクに変えましょう。次に、これ以降に発生する全てのイベントをこの矩形で取得できるように、マウスをキャプチャーします。これは典型的なUIの実装方法で、ユーザがこのボタンをアクティブにしている間は、他へのインタラクティブなマウス動作を禁止するものです。ですからマウス・ボタンが押下された後で、マウス・ボタンが(mouseupによって)解放された時には、必ず矩形の塗りつぶしを元の値に戻す必要があります。

ここまでで、このボタンにおいて、マウス操作を視覚的に見せる処理方法を説明しました。ただし、押しボタンで重要なのは、ボタンが作動したときにアクションを起こすということです。私は押しボタンが作動したときに、このカスタム要素がカスタム・イベントを発行するように決めました。これはこのカスタム要素が、マウス・イベントやDOMの変更に対応するためにSVG要素のように振る舞うだけでなく、それ自体でもイベントを発行できるようにするためです。カスタム・イベントの生成とディスパッチは、2つのDOMコールだけで実現することができます。最初に私のDOMdocumentcreateEvent()メソッドを呼び出してイベントを生成します。そしてそのイベントは、カスタム・タイプの「ButtonPush」イベントとなります。次に残るのは、このカスタム要素から(信じられないほど便利なDOMイベントのインターフェースEventTargetで定義されている)dispatchEventメソッドを呼び出すことで、実際にイベントを発行することだけです。


その結果

これで押しボタンの実装が完成したので、非常に単純なアプリケーションを作ることができます。その中身は(RCC定義やその他必要なSVGマークアップを除くと)こんな風に見えます。


リスト9. 私の拡張要素の使い方
                
<ui:button x="10" y="10" width="300">
  &lt;ui:button&gt;
  <script ev:event="ButtonPush">
    var button = evt.target;
    var width = parseInt(button.getAttribute('width'));
    button.setAttribute('width', width - 10);
  </script>
</ui:button>
<ui:button x="10" y="40" width="150">
  Another &lt;ui:button&gt;
  <script ev:event="ButtonPush">
    var button = evt.target;
    var width = parseInt(button.getAttribute('width'));
    button.setAttribute('width', width + 10);
  </script>
</ui:button>

私のカスタム要素<ui:button>に2つのインスタンスがあり、それぞれが独立したシャドウ・ツリー、コントローラ・オブジェクト、対話型処理、状態・・・、その他もろもろを持っているのです。各々に共有しているのは、どちらも同じプロトタイプ・ベースのRCC定義に基づいているという点だけです。このデモは非常に単純です。大きなボタンが一つあり、クリックするとその幅が狭まります。また小さいボタンも一つあり、クリックするとその幅が広がります。見て分かると思いますが、RCC定義のところでSVGイベントをリスンするために使ったのと同じXML Eventsの機構を使うことで、このボタンのカスタム・イベントをリスンすることができます。参考文献にある、デモの .zipアーカイブに含まれているファイルを開けばこれが分かるはずです。


図2. 2つの独立した押しボタン
図2. 2つの独立した押しボタン

同じアーカイブにはRCCに基づいた、もっと高度なサンプル・アプリケーションもあります。このアプリケーションは、RCCカスタム要素のより高度な使用法を示すためのものです。外観が変更できる(skinnable)より強力な押しボタンと、スタイルが変更できる(stylable)コンボ・ボックスもあります。このコンボ・ボックスは、上で定義した押しボタンを利用して、RCCが再入可能であることをより分かりやすく示したものです。この記事では、カスタム要素のスキン対応やCSSスタイルへの対応の詳細については説明しませんでしたが、各種のファイルを見て回り、実装のこつを学び取るだけの素地はできたはずです。図3はこのアプリケーションのスナップショットです。プロシージャ的なGDIコールの代わりに、100% SVGを使っているにもかかわらず、ルック・アンド・フィールをWindows XPのウィジェットに似せています。


図3. スタイルが変更できるコンボ・ボックスを使ったアプリケーション
図3. スタイルが変更できるコンボ・ボックスを使ったアプリケーション

この記事では、RCCの内部動作の詳細を説明し、簡単なウィジェットの実装を説明しながら、より複雑なアプリケーションを理解するための基礎を提供しました。次の記事では、XFormsとSVGの組み合わせについて説明するつもりですが、そのために必要となるSVGに関連する部分はここで説明しました。このシリーズの最後では、既存のRCCベースのUIウィジェットをより高度なXFormsコントロールでラップするにはどうするかを説明し、スタイルが変更できるコンボ・ボックスのデモをXForms用に書き直してみます。では次回をお楽しみに。


参考文献

  • この記事のサンプルコードをthis archiveからダウンロードしてください。

  • 原典に直行・・W3CでXForms 1.0SVG 1.2の仕様を読んでください。.

  • SVGの背景について、developerWorksのチュートリアル「Introduction to Scalable Vector Graphics」(2002年2月)と「Interactive, dynamic Scalable Vector Graphics」(2003年6月)で説明していますので、読んでみてください。

  • カスタム・タイプで、ある目的に特定なイベントをDOM Level 3 Eventsで作ってみてください。

  • Review another related W3C specification,XML Events, the declarative companion to the DOM Events.

  • 最新のpre-release version of Adobe SVG Viewer 6をダウンロードしてサンプルを見てください。またRCC他SVG 1.2の良いところをいろいろ試してみてください。

  • developerWorks のXMLゾーンにはXML関連の資料が豊富に用意されています。

  • XMLおよび関連技術においてIBM認証開発者になる方法についてはこちらを参照してください。

著者について

Antoine Quintは独立のSVGコンサルタント兼研究者で、招聘専門家としてW3CのSVGワーキング・グループに参加しています。SVG関連の講演やセミナー講師も場所さえ良ければ喜んで引き受け、下請け仕事もしています。家はパリにあり、猫のStig Elmerと一緒に住んでいます。古くからの友人Robin Berjonと共著の著作を執筆中ですが、だいぶ遅れ気味です。

不正使用の報告のヘルプ

不正使用の報告

ありがとうございます。 このエントリーは、モデレーターの注目フラグが設定されました。


不正使用の報告のヘルプ

不正使用の報告

不正使用の報告の送信に失敗しました。


developerWorks: サイン・イン


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。 プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。 お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

表示名をお選びください

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

(半角英数字で3文字以上31文字以下にする必要があります)


「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


この記事を評価する

コメント

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=241345
ArticleTitle=SVGとXForms: Rendering Custom Content (カスタム・コンテンツの描画)
publish-date=11252003
author1-email=antoine.quint@fuchsia-design.com
author1-email-cc=dwxed@us.ibm.com

タグ

Help
このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。

スライダーバーを使用することで、より多く(少なく)タグを表示します。

人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。

マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。

このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。