2004年08月18日

C++ビルダでフォーム表示の切り替え

C++ビルダでフォームの同じ位置に異なるダイアログのようなコントロールの固まりを切り替えながら使用する方法を調べる。
ページコントロールを使えば、タブによって切り替えられるが、タブが表示されてしまうのはちょっとかっこわるい。
そこで、同じ位置にパネルを配置し、その各パネルを表示/非表示することで、とりあえずは切り替えられることがわかった。
しかし、フォームの編集が出来ない。
各パネルないにフレームを配置し、そのフレームを編集することで、各コントロールを編集することは出来るが・・・どうもしっくり来ない。
もっと良い方法はない物だろうか?
出来れば、動的に割り当てられるとかなり良いのだが。。。

とりあえず次のようにすればいいようだ。

m_Frame = new TFrame1(this);
m_Frame->Parent = MyPanel;
m_Frame->Align = alClient;
m_Frame->Show();

まず、フレームを生成する時にオーナーをFormにする。
Parentに位置を決めるためのパネルを設定する。
アライメントをクライアント領域に設定する。(アライメントはフレームの方で設定しておけば問題ないようだ)
で、表示する。
後はいらなくなったら非表示にして削除する。
そして、各フレームの各コントロールの状態を保持する構造体でも作ってデータを設定/取得出来れば万事O.K.だ。

投稿者 Takenori : 05:59 | トラックバック

2004年09月26日

KAGに慣れる

まずはKAGを理解するために、一般的なADVのフレームワークを作り中。
でも、仮絵のボタンを作るのは面倒だ。
Excelで適当に作って、それをPrintScreenでとって切り取り。
きれいに3等分出来るサイズになっておらず、2ドット足りない。
まあ、中央のボタンが両脇の線を共有しているので当たり前。
仕方なく、右端を1ドット切る。
右の線がないボタンの絵がいっぱい出来た。
面倒なので右端にボタンをくっつけてごまかす。
仮だからね。
取り合えず、タイトル画面が出来たので、設定画面を作りにかかる。
上のメニューで設定できる項目は、ゲーム中の設定画面でも設定できるようにする。
でも、ラジオボタンがない?
もうちょっと探してみよう。

投稿者 Takenori : 08:56 | トラックバック

2004年09月27日

ラジオボタンは使わない?

ゲームのUIだとラジオボタンはあんまり使わない?
単純な出っ張ったボタンと、へこんだボタンを用意して、選択されているものはへこんだボタンにするとか言う感じか。
で、仮絵をまたExcelで作る。
また、面倒くさい。
つーか、ボタン絵ジェネレーターとか作れそう。
うーん、一考の余地はあるかも。

投稿者 Takenori : 02:30 | トラックバック

2004年09月28日

ボタン絵ジェネレーター

ボタンの絵をパラメタを設定するだけで生成することが出来るツールを作成。
これで、さくさくボタンが作れるが、このツールを作るのにかかった時間を考えると・・・ 普通に絵を作った方が断然速かった。
まあ、今後もっといっぱい作ることになったら、活躍してくれるでしょう。
たぶん。
そのときにはもっと機能追加が必要な気がするけど。

投稿者 Takenori : 03:58 | トラックバック

2004年10月10日

行き当たりばったり

メイン編集画面は上に属性設定画面、下にグリッドで行単位に編集するようなスタイルとし、行き当たりばったりで作っていく。
まずは、コンフィグで設定する項目をダイアログ化しようと作っていくが、数が多く後回しに。
で、次はグリッドと属性設定画面の連携部分を作っていくが・・・ やはり、適当に作っていく限界にぶち当たる。
各画面が同期して変更されて行くスタイルにするには、やはりある程度検討が必要だな。
と言うことで、明日はクラス図でも描こうと思って今日は終了。
現時点でも、そこそこ連携して動いているんだけど、完全とはいかないな。

投稿者 Takenori : 12:20 | トラックバック

2004年10月11日

クラス図を書く

クラス図を書いてみた。
やはり、各ビューを同期させるには、どこかで一元管理した方が作りやすい。
そして、そこへデータの格納や、各ビューへの反映処理を入れることにする。
Doc-Viewアーキテクチャのような感じだ。
でも、Builderはこれをサポートしていないが、確かHPにその回答が書いてあったはず。
見てみると・・・ なるほど、非ビジュアルコンポーネントとして実装するわけね。
これはなかなかよい方法だな。
この方法で実装しよう。
クラス図も書き換えないとな。

投稿者 Takenori : 12:02 | トラックバック

リッチテキストエディットを検討

メッセージ編集部分はリッチテキストエディットで簡単に出来るかなぁと思っていたが、調べるといろいろと面倒な感じがしてきた。
やって出来ないことはないと思うが、同期や操作性のことを考えると、専用のコンポーネントを作ったほうが良い気がしてきた。
TCustomMemo辺りから派生させて作ればいけそうだ。
そして、各文字の属性の管理はフライウェイトパターンかなにかを使えばよいのかな?
デザインパターンの本を参照したいところだが、生憎すでに引越しの梱包済みで、出すのが面倒だ。
ま、この部分はすぐに必要と言うわけではないので、少し後回しにしよう。

投稿者 Takenori : 12:50 | トラックバック

2004年10月27日

BCC Document/Viewの簡単な説明

次の文章を読むよりも、Boarlandのサイトの方が詳しいです。
でも、何回もコードを追うのは面倒なので、簡単な流れを備忘録として以下に記しておくことにします。

Model/ObserverコンポーネントはTModelとTObserverで構成される。
TObserverはビューにTModelはドキュメントに相当する。
データモジュールにTModelを配置し、このデータモジュールでドキュメント(データ)を管理する。
フォームにはTObserverを配置し、TObserverのOnUpdateプロパティに表示更新用のイベントを設定する。
ドキュメントの更新が行われた時は、TModelのNotifyをコールするようにする。
TModelのNotifyは、TModelが管理しているすべてのビュー(TObserver)のDoUpdateをコールし、表示の更新を促す。

至ってシンプルですな。
まあ、表示の更新部分はドキュメントをリロードし、表示を更新。
データ入力を受け付けるところは、逐一ドキュメントへ設定。
回りくどいので、少々重いのではないかという気もしないでもないが、内部の処理に比べて表示の更新は遅いので全然余裕だろう。
表示の更新が頻発するのは気がかりだが、人の入力速度なんてたかだかしれてるしな。
とにかくやってみないことには何とも言えないな。

次はデータ管理部分の構造を考えよう。

投稿者 Takenori : 05:23 | トラックバック

ドキュメント管理部の状態

ドキュメント管理部分は状態を持つかどうか。
ドキュメントは逐一更新されるので、必然的に状態を持っていることになるが、その状態ではなく、アクティブなタグ(以下、コマンドと呼ぶ)を認識するかどうかだ。
UIは、エクセルのようなセルとタブを持っている。
各行は一つのコマンドと対応し、タグはシーンごとに作ることにする。
その関係上、アクティブなシーンとコマンドが存在することになる。
当然、ドキュメント管理部は状態を持たない方がスッキリする。
UI側が更新時に毎回位置を指定すれば事足りる。
気になるのは、やはり処理速度だ。
ドキュメント管理部分は挿入や削除などに備え、リストで管理することにしようと思っている。
リストの場合ノードが多くなればなるほど、後ろになればなるほどアクセスが遅くなる。
つまり、コマンドが多くなった時、処理が重くなることになる。
うーん、ま、いっか。
シーンを分ければ何とかなるし、重くなった時はリスト自体が前回アクセスされたノードを保持するようにすれば、解決できそうだ。
よし、ドキュメント管理部分は状態を持たない方向にしよう。
その方がスッキリする。

リストは初めstd::listで行く予定だったが、TListは配列アクセスが出来て楽そうだ。
そこで、TListに気持ちが傾いたのだが、前回アクセスされたノードを保持する機能を持たせることを考えると、よくわからないTListよりも、std::listの方が良い気がしてきた。
やはり、std::listでやってみるかな。

投稿者 Takenori : 05:24 | トラックバック

2004年10月28日

ドキュメント管理部

とりあえず、昨日決めた通りstd::listをラップしたようなクラスを作成。
前回アクセスしたイテレーターを保持しておくのと、要素を位置で取得できるようにした。

各コマンドはどのように保持しよう?
各コマンドごとにクラスを作り、保持するのではも良いが、スクリプトをそのまま保持し、毎回動的にパースするほうがいいかな?
ダイアログでの入力も、スクリプトでの直接入力も受け付けるようにしたいので、パーサーはどのみち必要になる。
毎回解釈するようにしよう。

パーサーはflexのみで十分かな?
TJSのを作るとなると、bison(yacc)を使った方が良い気もするが・・・
とりあえず、flexのみで予約語どべーって並べて、力業で作ることにしよう。

でも、表示の更新はどうしよう?
グリッドをすべて書き換えるのはさすがに厳しい気もするが・・・
更新したウィンドウを覚えておき、それによって振り分けるか?
挿入処理があった時はどうする?
全部書き換えてしまうのが楽で、間違いも少ないが・・・
いいや、全部書き換えでやってみよう。
ダメならダメで考えよう。

投稿者 Takenori : 11:54 | トラックバック

2004年10月29日

構文解析

flexはやめよう。
動的解析をするのならインテリセンスが欲しい。
出来れば、状態依存型のほうがいい。
簡単な説明が付与されれば最高だ。
だが、確定済みのスクリプトと入力中のスクリプトは性質が異なる。
flexでの実装もあった方が良いか。
この問題は入力中スクリプトの解析器をもっと詰めてから検討しよう。

リストの全アクセスはどうしよう。
インデックスで順番に見ていくのは遅い。
イテレーターが欲しくなる。
追加しよう。
基本的に読むだけだから、コンストイテレーターだけにしておくか。

現在アクティブになっているシーンはどこが押さえるべきか?
前にドキュメントの方で状態は持たないことにしたが・・・

投稿者 Takenori : 11:49 | トラックバック

2004年10月30日

Model/Observerの実装

Model/Observerを実装した。
各タグの属性設定用ダイアログを作る。
数が多いので大変だ。
まだ、5個ぐらいしかできていない。

グリッドのOnRowMovedイベントが来ない?
optionのgoRowMovingをtrueにしているのに。
他に何かしないといけないことがあるのだろうか?
よくわからなかったので、OnSelectCellで代用することにした。
ARowとプロパティのRowが異なっていたら処理するようにした。
これで、現在の行のタグに応じてダイアログ表示が切り替わるようになった。

最終行のコマンドを設定したら行が増加するようにした。
command列の時、Enter orダブルクリックでコマンド選択メニューを表示するようにした。

ドキュメントの方で状態を持った方がスッキリする気がしてきた。
Boarlandのサイトにあるコンポーネントは、ドキュメントを変更した時に、表示を更新するようになっている。
Modelはデータモジュールに置くように説明されている。
で、その通りにした。
このような構造にすると言うことは、データモジュールにドキュメント変更用のメソッドを持たせ、そのメソッド経由でデータを変更し、それと同時に表示更新を行うことだと考えられる。
つまり、データの変更は必ず、データモジュールのメソッド経由で行われることになる。
しかし、現在はフォームの方でカレントコマンドの参照を持ち、それを直接変更している。
そうした方が都合がよいことが多いと考えたためだ。
あー・・・うーん。
フォームでカレントコマンドへの参照を持つのは、別に問題なさそうだ。
列が移動するなどのコマンド確定動作が行われた時に、データモジュール側に通知すればいいだけか。
シーンはどうする?
シーンの切り替わりも一元管理したい。
もう一組Model/Observerを追加すればいいのか!
一度、同期して変更を加えたいものをリストアップした方が良いかもしれないなぁ。
でも、今のところは上記の2つだけかな。

投稿者 Takenori : 11:50 | トラックバック

2004年10月31日

属性設定用UI

コマンドメニューで残っていた分を追加。メニューだけでも面倒なのに、UIとなると・・・
UIはいくつかは使い回せたり、属性なしも結構あるからだいぶマシかもしれないけど。

属性設定用のUIを作っていく。やっと10個分だ。
このUIとグリッド部、ドキュメント部とのハンドリングについて考える。
以前も何か考えていたなぁと思い、クラス図を見るとやっぱり考えていた。
しかし、そのときはModel/Observerを知らなかったので、単なるクラスとして考えていた。
なので、再考中。
基本的なやりとりは、スクリプトを介すことで汎用的なインターフェイスにしようと思ったが、UIのいくつかは共通化している。
共通化しているUIは単なる有効/無効、ファイル選択だけを属性に持つものだ。
共通化しているUIで異なるスクリプトになるのもある。
クラスを受け渡し!この文章を書いていて気付いた。
文書化は告知や報告など以外に思考の整理としてなかなか役立つ。
誰かに何かを説明しようとしたら当然理路整然としていなければならない。頭の中では筋が通っていると思いこんでいるものは意外と多い。
文章化すればこのような矛盾に気付く。
また、なぜか新しいアイデアなどが思い付くこともある。
人に説明しようとすることはいろいろと役立つことが多い。
話がそれてしまったので元に戻そう。
グリッドと属性設定UIとのやりとりはクラスを受け渡す方法にしよう。
パラメタを持つクラスは1つのクラスから派生させれば、インターフェイスは共通化できる。
ドキュメントの方とはどうするか?
同じような方法をとっても良いが・・・ バケツリレーのような方法でやろう。
つまり、属性設定UI→グリッド→ドキュメントといった具合に受け渡していく。
属性設定UI、グリッド間はクラスでやりとり、グリッド、ドキュメント間はスクリプトとしよう。
グリッドは直接スクリプトを編集することも出来るようにするのでその方が都合がよい。
構造を考えていくと、グリッドがドキュメントへのアクセスを一手に引き受ける形になりそうだな。
I/Oは限定されている方がやりやすい。

投稿者 Takenori : 11:50 | トラックバック

2004年11月12日

スクリプトで保存することの意味は?

スクリプトによって変更された状態を、任意の位置で取得できるようにする予定だが、この場合、スクリプトで書くコマンドを保存した場合、毎回解析しなければならない。
少ない内はよいが、長くなってくるとこの解析の時間は無視できなくなる。
やはり、スクリプトではなく、構造体などで保存した方が良いだろうか?
そもそもなぜスクリプトを使おうとしたのか?
まず1つは吉里吉里/KAGで制作する場合にスクリプトが使われているから、そのままの流れで使用することにした。
たぶん、これが一番大きいのではないだろうか?
潜在的にそれしかないと思ってしまっていた。
もう1つは、スクリプトでの入力になれた人は、スクリプトで入力した方が速いと考えたからだ。
プログラマはスクリプトを直接書いていく方が断然速いと考えていた。
そして、いくつかの入力支援などを加えることで、単なるテキストエディタよりも速く制作できることを目指していた。
しかし、果たしてそれは真実だろうか?
確かにスクリプトでの入力は、一般的なGUIなどを使って、マウスで入力していくスタイルと比べれば速い。
でも、キーボートとマウスに適切に役割を分担させた場合は?
キーボートとマウスはそれぞれ特性が異なる。
片方で実現しやすいことがもう片方では手間がかかることもある。
つまり、インターフェイスを工夫することでスクリプトでの入力よりも高速に制作できるようになる可能性がある。

スクリプトは最終出力段階のみとし、途中ではなくそう。

投稿者 Takenori : 01:09 | トラックバック

2004年11月15日

全体的な見直し

スクリプト非依存としたため、幅が広がった。
スクリプトが頭にあった時は、ほとんどスクリプトに従ってメニュー構成などを考えていたわけだが、それに依存しないとなると、より制作者側に立ったわかりやすい構成にすることも出来る。
また、同時にいくつかの制約を課すことも考え始めた。
ただし、制約と言っても表現力をそぐようなものではなく、単に設定できる箇所などを決めてわかりやすくするのが目的だ。
まあ、まずはオブジェクト指向的な分析か機能的な分類をしなければならないな。

投稿者 Takenori : 01:10 | トラックバック

2004年11月21日

イベントと状態の継続

昨日無理とか書いておきながら、やっぱり何とかなるかもしれないと思い始める。

初期のExcelのような形態のもので、少し進めていたのだが、やはりわかりづらい。
プログラマからすればなんでもないことだが、他の人にはわかりづらいだろう。
そこで、縦方向の並びを単なるグループ分けのように扱い、選んだセルの行によって選択できるコマンドを制限することで、わかりやすくすることを思い付いた。
とりあえず、画面を作ってみた。

2004112101seq.png

基本的に初期のUIと同じだが、だいぶわかりやすくなったように思う。
ちなみに、初期のUIは次のような感じ。
基本的に下部のグリッドでテキストエディタのように行単位で編集することになっていた。

20041030LineEditor.png

そして、新しいUIだが、各セルにイベント(コマンド)を割り当てるわけことになるが、それだけでは混乱する気がする。
理由は、macromedia Directorと違うから。
Directorをさわったことがないのならいいかもしれないが、あるのならとまどうかもしれない。Directorはイベントではなく、状態を表示しているからだ。
つまり、画像が表示されている間は、ずっとセルが塗られているようなことになる。
これを解消するためにイベントと状態の継続を表示することにした。
イベントは濃い色でセルを塗りつぶし、状態は薄い色で塗る。
これで、少しわかりやすくなるだろう。
ただし、横が時間という単位ではなく、コマンド(タグ)単位と言うことになるが。
後、同時に表示させられないこともとまどうかもしれない。
ま、少し操作すればそう言うものだと感じるようになるだろう。また、ガイドメッセージを表示すれば、何とかなるかな。

投稿者 Takenori : 04:51 | トラックバック

無理がある

完全に別物、いわゆるオーサリングツールのような形態を考えていたが、いろいろと無理がある。
編集画面としてmacromedia Directorのスコアをイメージしていたが、いろんなところで厳しい。
そこで、やはり元に戻してしまう。
基本編集画面はExcelのようなグリッド。
macromedia Directorのスコアのような部分も取り入れたいが・・・ やはり厳しいか。
何かうまいインターフェイスはないか考えないと。

投稿者 Takenori : 12:41 | トラックバック

2004年11月23日

データ構造はどうする?

DirectorのスコアライクなUIにすることは決めた。
では、内部のデータ構造はどうする?
見た目通りに2次元配列で持つことも可能だが、現在のまま単なる1つのリストとして持つことも可能だ。
リストの場合は、コマンドによって分類され、適切な場所のセルが塗られる。
リストにするか?
でも、その場合セル状のUIからの操作を反映する場合、前方向、もしくは後方向にリストを検索しなければならない。
検索と言っても、マッチする条件は明確なわけだから、それほど問題にならないか。
2次元配列も1次元配列の各位置への参照を持っているようなものだ。
とりあえず、リストで作ってみよう。
2次元配列の方が何かと問題発生しそうだし。

投稿者 Takenori : 01:20 | トラックバック

分類に悩む

各タグの分類にかなり悩む。
KAGのドキュメントでは、すでに分類がなされているが、今回のツールの性質からしてそのまま適用するのは少し違う気がした。
そこで、違う分類項目を考えたわけだが、すごく悩んだ。
結局、制作者が操作する対象物に着目して分類することにした。
たぶん、これがわかりやすいのではないかと思う。
で、項目は次のようにすることにした。

・ 画像レイヤー
・ メッセージレイヤー
・ オーバーレイ (ムービー/Flash)
・ システムグラフィック (Windowなど)
・ 効果音
・ BGM
・ プログレス/ウェイト
・ レスポンシビリティ
・ セーブ/ロード
・ スクリプト/変数
・ システム

さて、これは吉と出るか凶と出るか。

投稿者 Takenori : 09:20 | トラックバック

2004年11月25日

分類した後また悩む

すべてのタグを分類したのだが、その後インターフェイスをどのようにするかかなり悩んだ。
わかりやすくするためには、1列に1コマンドでは限界がある。
しかし、わかりやすいインターフェイスにするには分類したタグをさらに分類したり、インターフェイスを考えていかなければならない。
本来ならここでじっくり検討して行くべきなのかもしれないが、ちょっと疲れてきた。
とにかく一通り実装したい。
なんで、面倒なことは考えずに、選択したグループによって違うメニューが出るだけのものを作ろうと考えた。
とにかく完成させてからインターフェイスを再考する。
それで行こう。

前は、ポップアップメニューをちまちまGUIで作っていたが、今回は動的に作ってしまおう。前回はちょっと無謀だった。
コマンドの多さをあんまり考慮していなかった。
さくっと行こう。

投稿者 Takenori : 11:35 | トラックバック

C++ Builderでメニューハンドラを共通化

メニューがクリックされた時のイベントハンドラは共通にしたい。
しかし、前回はどのメニューが押されたのか判別する手段がわからずに、似たようなメソッドを大量に作ってしまっていた。
メソッドの中身は、
SetActiveTag(TAGTYPE_cancelautomode);
をコールするのみで、引数の定数値が違うだけだった。
面倒だから置換でコードを生成するというアホさだった。明らかにメンテナンス性が悪い。
で、今回は注意深くヘルプを読んだ。
するとint Tagプロパティがあった。
ヘルプには"Tag は,あらかじめ定義された意味のあるプロパティではありません。Tag プロパティは,開発時の利便性のために提供されます。追加の整数値を格納したり,コンポーネント参照またはポインタなどの 32 ビット値に型キャストできます。"と書かれている。
たぶん、今回のような用途に使うんだろう。
これを使えばすべてのメソッドを共通に出来、中身は、
SetActiveTag(reinterpret_cast(Sender)->Tag);
とすればいいはずだ。
タグのグループ分けはマスクにして、配列を作り、その配列の全要素とorをとって真となった要素をメニューに追加。
同時に、メニュー文字列も配列にしておけばいい。
って言うか、そう言う作り方が当たり前だろう。
前のはどう考えてもアホだった。まあ、この文章の方法のようにしたいと思っていたが出来なかったので、苦渋の選択をしたのだが。
ま、なんにせよ、これでメニューはさっくり出来る。

投稿者 Takenori : 11:58 | トラックバック

2004年11月27日

グリッドクリック時の振る舞い

任意のセルがダブルクリックされた時に、メニューを表示するようにする予定なのだが、どのようにして、グループ分けするか考えてみた。
前に書いたように、フラグを持った配列を持たすのはよいが、グループの分類と、左端に表示している分類項は少し異なる。
グループはグラフィックレイヤーなどと、すべてのレイヤーをひとまとめに扱うが、グリッド上ではグラフィックレイヤー 0、グラフィックレイヤー 1、などと言うように分類される。
さて、どうした物か?
すぐにクラス化することを思い付いた。
クラスには、グリッドに表示する文字、自分のグループに属するコマンドかどうかの判定、ポップアップメニューの表示を持たせることにした。
で、ベースとなるクラスを作り、他はそれから派生させた。
これで、いいと思っていたが、この文章を書いていて、各グループの継承関係をもう少し見直した方が良い気がした。
例えば、背景レイヤーとグラフィックレイヤーのメニューは同じになる。でも、現在は完全に別クラスだ。
これは、共通の基底クラスを作って、そこから派生させた方が良いだろう。
こういった物は他にもあるかもしれない。
少し考えよう。

投稿者 Takenori : 10:57 | トラックバック

Excelから生成した方がいい

メニューの文字列配列を作った後、フラグを決めて、フラグの配列を作りかけて気付く。
Excelの表見ながらちまちま作るのはすげー面倒くせー。文字列はコピペ&置換だから何とも思わなかったが。
で、Excelから自動生成することにした。
後、無効なメニューアイテムは配列を作る時に一緒に考えようと思っていたが、Excelの方で整理しておくことにした。
整理した後、perlでさくっとスクリプト組もう。

投稿者 Takenori : 12:25 | トラックバック

2004年11月29日

perlからExcelを使う

use Cwd;
use Win32::OLE;
use Win32::OLE::Variant;

Win32::OLE->Initialize();
$XL = Win32::OLE->new('Excel.Application', \&OleQuit) or die "oops\n"; #Excelのインスタンスを得る 2番目の引数の関数が終了時に呼ばれる
$XL->{Visible} = 0; #Excelを非表示で起動
$Books = $XL->Workbooks; #ExcelからWorkbooksを得る
$Books->Open( cwd . '/' . 'ModuleTest.xls'); #オープン時フルパスで指定しないと開けない
if( Win32::OLE->LastError() ) {
print "ファイルオープン時にエラーが発生しました。\n";
exit(1);
}
$Sheet = $XL->Worksheets->Item('Sheet1'); #指定した名前のシートを得る
$cellVal = $Sheet->Cells( 1, 2 )->{Value}; #指定したセルの値を得る
print $cellVal."\n";
Win32::OLE->Uninitialize();

#############################################################################
#終了時に呼ばれるっぽい
sub OleQuit {
my $self = shift;
$self->Quit; # $XL->Quit;が呼ばれている。これを呼ばないとExcelのプロセスが残ったままになってしまう。非表示で使っているときはタスクマネージャで終了させないといけない。。。
}

------
ってな感じで使う。
でも、perlを実行する環境にExcelがインストールされていないと使えない。
C++からの場合も似たような方法で出来るが、いろいろと面倒臭い。
C++からは、今後使わなさそうなので、備忘録としてここに書いて置かなくてもいいかな。
また、気が向いたらメモっておこう。

投稿者 Takenori : 02:24 | トラックバック

フォームの切り替え

ポップアップメニューで、コマンドが選択された時、どのようにして上部のフォームを切り替えるか?
クリックされた時のハンドラで、切り替えてしまってもかまわないが、そうはせずに、指定されたコマンドクラスを初期化して、ドキュメントに設定。
ドキュメントから再描画を促された時に、上部のフォームを切り替えると共に、グリッド部のフィルも行う。
と言うのが、良いだろうか?
重いかな?
いいや、やってみよう。
でも、その前にタグごとのクラスを大量に作らないと。

投稿者 Takenori : 02:32 | トラックバック

2004年11月30日

perlからExcelファイルへアクセスする場合の注意メモ

パスにスペースや日本語が含まれているとうまくいかないことがあるようです。ダブルクオーテンションで囲んでもうまくいかなかった。
たぶん、何かやるといくんだと思いますが、面倒なのでほったらかしです。

後、セルへ
$Sheet->Cells( 1, 1 )->{Value}
でアクセスする際、1,1始まりです。
$Sheet->Cells( 0, 0 )->{Value}
ってやると、エラーになります。

投稿者 Takenori : 07:22 | トラックバック

メニュー項目の動的追加

Excelからコードを吐くようにして、それによってメニューの文字列や属するグループを判別し、メニューを動的に追加するようにした。
メニューは、表示前に前回の物を全部消してから、新たに追加するようにした。
速度を少し懸念していたが、全然余裕だった。
まあ、最近のPCがその程度で重いわけないか。
せいぜい150個とかだし。

少し操作してみたが、なんかイマイチ。
メニューの並び順も工夫した方が良い気がする。というか、しないと使い勝手悪そう。
そこで、ダブルクリックでメニューを表示するのではなく、シングルクリックで表示するようにした。
うざいかなと思っていたが、意外と軽快でいい感じ。
よし、シングルクリックで表示にしよう。
メニューの並び順は、今後Excel表で調整することにする。
コード自動生成で、enum値が変わることになるが、そのことには依存していないはず。
今後も依存しないように記述しないと。
って、依存することなんてないかな?

投稿者 Takenori : 11:55 | トラックバック

2004年12月01日

C++Builderのイベント

Builderでイベントを実行中に割り当てようとして、ふと疑問に思った。
サンプルでは何気なく、クラスのメンバ関数を代入しているが、C++でそんなことは出来ないんじゃなかったっけ?
つまり、次のような文だが、
Event1 = Class1->fun;
このようには出来なかった気がする。この場合は、
Event1 = Class1::fun;
としなければならず、Event1の定義を見ると関数ポインタのようなので、Class1::funはstaticなメンバ関数でなければならないはず。
でも、不思議なことにBuilderでは普通に出来ている。
変だなぁと思ってよく見ると、__closureというキーワードが間に入っている。
ヘルプを見ると、これはBuilder独自の拡張のようで、クロージャと呼ばれる物らしい。
で、いい感じにthisポインタを取得して、そのメンバ関数をコールしてくれるようだ。
なるほどね。
独自拡張だったのか。

投稿者 Takenori : 01:14 | トラックバック

イベントを割り当ててみる

イベントを割り当ててみて、動作を見た。
すごい、ちゃんとメンバ変数にもアクセスできる。
これは便利だ。
でも、移植性は下がるな。

投稿者 Takenori : 01:30 | トラックバック

TStringGrid のOnClick

TStringGridのOnClickでポップアップメニューを出すようにして、快適に使えるようになったかと思いきや、カーソルキーで移動した時にも、メニューが出てきてかなりうざい。
カーソルキーの移動でも、OnClickが呼ばれるとは・・・
これは使いづらいのでOnMouseUpでポップアップメニューを出すように変更した。

投稿者 Takenori : 11:29 | トラックバック

なぜか消えてる・・・

内部ではコマンドをリストで管理している。
そして、リストをラップして、インデックスで要素を取得できるようにもしている。
で、コマンドを設定する際に、要素の数が指定したインデックスより少ない場合、push_backで空要素を追加する。

現在の要素の数より大きいインデックスよなる位置にコマンドを追加し、さらに大きいインデックスへコマンドを設定すると、なぜか前に設定したコマンドが消えていた。
おかしい。
デバッグしやすいように、リストの中身をダンプするようにするため、コマンド番号から、コマンド文字列へ変換するためのテーブルを作ろうと思ったが、面倒臭かったので、まずはOutputDebugStringで要素数などを吐かせてみることにした。
すると、要素の数が少ない。
どうやら、要素数が不足した際に追加ループの判定式が間違っていて、常に1個少なくなってしまっていたようだ。
でも、インデックスでリストから要素を取り出す時に、要素の数が少ない場合、例外を投げるようにしていたはず。
なぜ? と思ってよく見てみると、ここも間違っていた。
コードは次のような感じ。
int idx = 0;
typename std::list::iterator i = m_Items.begin();
for( ; i != m_Items.end() && idx < index; i++, idx++ );
if( idx != index )
{
throw L"Bad index.";
}
return i;
indexは、取得したい要素のインデックス番号。
idx != index の時例外としているのがまずい。
つまり、1個少ない時、i == list.end()の時は、正常だと判断してしまっていたわけだ。
これはまずいので、i == list.end()の時も例外を投げるようにした。
って、よく考えたら、idx != indexは必要ないんじゃないのか?

この部分を直したら、消えてしまう問題も解決した。ありがちだけど、アホなことをしていた。
にしても、C++Builderのデバッガは使いにくい。
何とかならないものかなぁ。

投稿者 Takenori : 11:55 | トラックバック

2004年12月02日

状態を調べなければならない?

どのレイヤーに対する操作かわかりやすいように、セルに色を塗る機能を追加した。
現段階では細かい判定はしておらず、単純にそのコマンドがどのグループに属するかだけを見ている。
しかし、最終的にはどのレイヤーに対する操作かなども判定する予定だ。
そこで、問題に気付いた。
ビデオは再生したいレイヤーを事前に指定するが、それはつまり、過去のコマンドを検索しなければならいなことを意味する。
しまった。
再描画が発生するたびに、コマンドによっては各列で状態を判定しなければならない。
重いか?
そんなことはないか。
PCでメモリ上にある物に対して操作するのなら余裕だろう。
組込用の数十とか数百MHzで動いているCPUじゃないし。
ま、重かったら、重かった時に考えよう。
それに、状態の判定などは、プレビューウィンドウを付けようと思ったらどのみち必要になる。

で、次は・・・ 各コマンドの属性を保持するためのクラスを量産かぁ。
各コマンドのUIとこのクラス、そして、それぞれを結びつける作業。
数が多いだけにここはしんどいな。

投稿者 Takenori : 02:59 | トラックバック

ノーマルモードとエキスパートモード

このツールにはノーマルモードとエキスパートモードを作ろうと考えている。
エキスパートモードは、今作っているインターフェイスで、細かく動作を設定できるというか、KAGスクリプトに近い形で細かい動作がわかる。
ノーマルモードはmacromedia Directorに近い形で、内部的なスクリプトの呼び出し順序などは自動的に決定され、UIで見た形に近い表示になるようになる。

一番初めは、単にExcelで書いた物をコンバートするような形を考えていたが、途中でそれをExcelから独立したツールにすることにした。
で、作っていたのだが、なんか見た目にわかりづらいと感じて、いろいろと考えた末、macromedia Directorのようなインターフェイスにすることにした。
で、上述のノーマルモードのみで行こうと考えていたわけだが、どのようにするかすごく悩んだ。
後、グループ分けなどいろいろと面倒なので、保留とした。
で、エキスパートモードが生まれた。
エキスパートモードはほとんどスクリプトそのままに近いけど、タグがカテゴライズされて、視覚的にもわかりやいので、これでいいと言うことにした。

と、ここまで書いたけど、そんなのはどうでも良くて、ノーマルモードを実現するために必要な要素を思い付いたから、メモしておこうと思ってこのログを書いた。
つまり、上の文章は要らない。
じゃ、書くなよって感じだが、まあ・・・ いいじゃん。
で、その要素だが、単にタグの中には時間を経過させるものとそうでないものがある。ってだけのこと。
Directorの場合、横軸はフレームで、何fpsにするかを指定して、アニメーションを作る。
でも、KAGの場合はそうではない。時間を進めるタグがなければ、時間は進まない。(ムービーやアニメーションなどは勝手に進むけど、言いたいのはそう言うことではない。)
つまり、横軸のコマが進むのは、時間を経過させるタグが出現した時だ。
言い換えれば、同一の時間軸に存在するのは、時間を経過させるタグに囲まれた間と言うことになる。
これは、いいひらめきだ! と思ったけど、そんなでもないか。
後、悩んでいるのは横軸をなんと呼ぶか。
どうでもいいと言えば、いいけど、名前によってわかりやすさが違ってくるし、場合によっては誤解を生じてしまう。
うーん・・・
フレームとかでいいかな?
意味的には大丈夫だと思うけど、一般的にどうとらえられるかは・・・ 大丈夫かな。
・・・ ヘルプなどで上述したような概念の説明を最初に持ってくれば、問題ないでしょう。
とりあえず、横軸はフレームと呼ぶことにしよう。

投稿者 Takenori : 03:27 | トラックバック

プレビューウィンドウ

プレビューウィンドウを作ろうと、フォームにTImageだけをのせたものを追加した。
そして、フォームのOnPaintでTImageのキャンパスのFillRectを呼び出すようにしたら、すごく重い。
こうやったらまずかったんだっけ?
"TImage に含まれているグラフィックのペイントと更新は自動的に処理されます。・・・TImage 上で描画すると,永続的なイメージが作成されます。したがって,その中のイメージを再描画するための操作は何も必要ありません。"
再描画は勝手にやってくれるんですね。
だから、FillRectを呼ぶと、OnPaintが呼ばれて、またFillRect・・・と無限ループ。CPU負荷100%状態なわけか。
じゃあ、イメージのアップデートは別メソッドにしておかないと。
で、続きを作ろうと思ったけど、コマンドの処理などをやらないといけないので、各タグの属性のクラスが必要になるため、まだ出来ないことに気付いた。
なんでプレビューウィンドウは後回し。

描画はコマンドのクラスに任せる?
でも、状態によって変わるものがあるのでそれはどうする?
コマンドは状態にだけ変化を与えるようにして、描画はその状態を元に行えばいいのか。って、コマンドごとにクラスを持っているわけじゃなかった。
コマンドごとにクラスを持たせてもいいけど、それはちょっと・・・ でも、その方が柔軟になるか。
さて、どうするか。

投稿者 Takenori : 10:44 | トラックバック

2004年12月03日

属性クラスの量産

ひたすらエディタで同じようなことを書いていたが、これもExcelで書いてから、コードを吐かせた方が良さそうだ。
管理も楽になるし、同じようなことを何度も書かなくて済む。
ってか、コマンドに関連するものは全部Excelからやったほうが楽でいいかも。

投稿者 Takenori : 10:11 | トラックバック

2004年12月08日

拡張性

ノーマルモードの時、吉里吉里2/KAG3の拡張性を活かせないのではないか? と思った。
そして、吉里吉里にする意味は? 独自のシステムでもかまわないんじゃ・・・ と考えた。
しかし、自由に記述できる項をもうければ、事足りることに気付いた。
時間を進めるものの概念さえ守って書いてもらえば、どのようなことを書いてもらっても問題ない。
いやー、一件落着。って、何も問題発生していたわけじゃなくて、一人悩んでいただけだけど。

でも、考えれば考えるほど、ノーマルとエキスパートのデータの行き来が難しい。
うーん、どうしよう。
Ver.1はエキスパート、Ver.2はノーマルにするか。
まず、Ver.1を完成させて問題点を出す。
Ver.1にアニメーションをエディットする機能を付ける。
問題点を改善すると共に、インターフェイスを改良したVer.2を作る。
Ver.2のインターフェイスのベースはアニメーションのエディット画面。
Ver.2は吉里吉里のみでなく、スプライトアニメーションをスクリプトとして吐き出せる機能、ムービー出力機能を付ける。って感じがいいだろうか?
後、C++Builderから離れて、VC++にし、ウィンドウ系はwxWindowsにしたい。
ま、当分先だけどね。
でも、Ver.1を作りながら、Ver.2の仕様とか考えるのって・・・
さらに、Ver.3とかも考えていたり。
気が早すぎですな。

投稿者 Takenori : 08:04 | トラックバック

2004年12月24日

属性をひたすらExcelで

属性クラスをExcelから生成するために、Excelでひたすら属性を書いた。
perlでExcelからソースを吐くのを作って、属性クラスのコードを吐かせた。
いい感じ。

投稿者 Takenori : 03:12 | トラックバック

2004年12月29日

メイクが通るようにしてそれから・・・

属性に使っていた構造体や列挙型を作り、全属性クラスのメイクが通るようにした。
で、次何するんだったっけ?
間が空いてしまったので、忘れてしまった。
ログを読み返さないと。
こういう時は、ブログにいろいろと残していると便利だ。

投稿者 Takenori : 10:52 | トラックバック

2005年01月12日

XMLも

RDBではなく、値と変数が1対1で対応するデータも保存したいので、XMLの利用を検討する。
初めに思い付いたのは。
Xerces C++libxml
libxmlはCなのかー。
Xerces C++はそれなりにでかい。
今回の用途に近いxmliniと言うのがあったが、COMなのが難点。LGPLなのでソースをいじってもいいが、面倒くさい。
後、tinyxmlも軽量なようだが、資料探したりするのが面倒臭いなぁ。
やはり、手軽にMSXMLとかか?
気持ち的には、Xerces C++を使いたいがDLLは2.3MBか。
スタティックな方は2.9MBだが、実際にリンクするとだいぶ減ってくれるだろうか? 使う機能はそう多くないので、そうなって欲しいが・・・
とりあえず、MSXMLとXerces C++を試してみよう。

投稿者 Takenori : 03:29 | トラックバック

データはSQLiteで

データ保存はSQLiteでやろうと思い、DL。
quick startのコードを見てみるが、コールバック!?
API Referenceを見てみると、1行ずつ取得する方法も出来そうだが、どうもピンとこない。
で、SQLitePlusをDL。
ソースコードを見てみる。
ああ、なるほど。
そういうことか。
やはり、ソースコードを見たほうが理解が早い。

で、肝心のデータ保存方法だが、SQLite 3 からBLOBがきちんとサポートされたので、やはりBLOBかな。
一度スクリプトにして保存してもいいけど、パーサーが面倒臭い。
BLOBでも、ある程度クラスからの変換が必要だが、明確な変換が必要なのはstringぐらいだろう。
クラスファクトリとローダーを作ればいい感じになるかな?
読み込みと書き出しは各クラスに任せて。
少しクラス図を書いてみよう。

投稿者 Takenori : 12:55 | トラックバック

2005年01月23日

Frameとのデータの受け渡し

パラメータを設定する箇所はFrameを使用しているが、そのFrameとのデータの受け渡しに初めは多重継承によって実現しようと考えていた。
そのFrameを切り替える元となるフォームは、各Frameを保持している。
そして、そのFrameのメソッドを介してデータを渡すようにしようとしていた。
そのため、単純に多重継承したのでは、そのインターフェイスとなるクラスのポインタも保持しなければならなくなる。
それを回避するために、Frame の派生クラスではなく、その親となるクラスで多重継承することにした。
次のような感じ。
class ITagProp
class TPropFrame : public TFrame, public ITagProp
class TUserFrame : TPropFrame
こうすれば、TPropFrame を保持しておくだけで良い。
これでメイクも通りうまくいったかと思ったが、Frameのレイアウトなどを変更しようとしたら問題が発生した。
プロパティが取得できないとかなんとかエラーが出てしまった。
それでも、そのまま無視を選択したらフォームが表示されたのだが、メイクして動かそうとしたらエクセプション。
どうやら、この方法ではダメのようだ。
そこで、Tagプロパティを使って受け渡しをしようと思ったが、FrameにはOnShowなどがないので、Tagプロパティに値を設定しても、それを拾うタイミングがわからない。
良いメソッドがないかヘルプのTFrameを見る。
Dispatch!
そうだ、普通にメッセージでやり取りすればいい。
Frameの切り替えを行う際、Dispatchをコールすることにした。
そして、独自のメッセージを作り、各Frameで受ける。
この方法でうまくいくかどうか実装してみた。
いい感じだ。
初めからこうするべきだったな。
なお、実際のDispatch 部分は、次のようにマクロで定義するようにした。

void __fastcall SetElement( TElementMessage &mes );
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SET_ELEMENT,TElementMessage, SetElement);
END_MESSAGE_MAP(TFrame);

投稿者 Takenori : 02:30 | トラックバック

コマンド表示部を追加

ウィンドウ上部にコマンドを表示するようにした。
今までは表示していなかったので、各フレームにどのようなコマンドが設定されているか全然わからなかった。
このことに限らず、実際に使用する時にいろいろと足りないと思うことがありそうだ。

投稿者 Takenori : 03:59 | トラックバック

2005年01月25日

ひたすらコマンドパラメタ用フレーム作成

imageタグはパラメタが多いのですごいことになってしまった。
グループ化したり、有効/無効で表示/非表示にしたりして、もう少し見やすくしたほうがよさそう。
タブとかにしたほうがいいかなぁ・・・

でも、2時間で6個ぐらい。
あんまり進まないなぁと思ったけど、imageタグに1時間以上とられてる。
パラメタがそんなに多くなければ1時間で5個ぐらい?
まずまずかな?

投稿者 Takenori : 05:25 | トラックバック

2005年01月26日

コマンドパラメタ用フレーム作成一通り終了

コマンドパラメタ用フレーム作成が一通り終わった。
改良の余地のあるものもあるが、とりあえずは良しとしよう。
後、シーンタブの切り替えにも対応した。

画像、音、動画はプロジェクトにいったん追加して、そこから選ぶようにした方が良さそうだな。(とりあえず、メディアパレットと呼ぼう)
なら、プロジェクト周りを作る必要があるな。

他に最低限必要なものは、
・シーンの追加と削除
・プロジェクトプロパティの設定
・プロジェクトの新規作成/保存
・スクリプトの生成
・メディアパレット
これだけあれば、とりあえず作ることは可能なはず。
たぶん、まだまだ使いにくいだろうけど。

次は、プロジェクトの新規作成/保存だな。

そういえば、エレメントの生成も途中までしか作ってなかった。

投稿者 Takenori : 01:14 | トラックバック

2005年01月27日

XML データバインドウィザード

少し前に、XMLを扱うライブラリは何を使おうかと悩んでいたが、C++Builderのものを使うことにした。
そして、ヘルプを見てみるとXML データバインドウィザードなるものがある。
どうやらこれは、XML の構造を表したクラスを作ってくれる機能のようだ。
で、使おうとしたのだが・・・ ない!
ないぞそんなの。
C++Builderのページを見てみるとEnterpriseでのみ使えるようだ。
持っているのはProfessional。
使えないのか。
で、仕方なくTXMLDocumentを直接使おうとコンポーネントのInternetタブを見るが・・・ない! あれ?
コンポーネントもないのか?
XMLDoc.hpp をインクルードし、自分でnewすると使えるが、newするときにファイル名を指定しないといけない。
で、ファイルがないとエラー。
新しく作るときにはどうするのだろう?
面倒なのでMSXMLを少し調べてみる。
やはり、OSとIEのバージョン依存だな。
となると、やっぱりXerces C++か?
Xerces C++はApacheライセンスだったな。
日本語訳を読むことにする。

どうやら、Xerces C++はライセンスのテキストファイルを添付し、著作権表示を入れれば使用できるようだ。

投稿者 Takenori : 02:33 | トラックバック

2005年01月28日

コマンド属性生成部完成

各コマンド属性の生成部分を一通り作成
シーンの追加、削除、プロパティのメニューだけ作成
シーンの追加を実装するためにシーン周りを少し見直し中。
左クリックのみでメニューを表示していたのを、Ctrl+左クリックで表示するように変更。

投稿者 Takenori : 02:08 | トラックバック

2005年01月29日

EAccessViolation例外

起動時にEAccessViolation例外が突然発生するようになった。
メンバを直接アクセスしていたのをプロパティ経由にして、参照を使うようにしたのか、ダイアログを追加したぐらいしかやっていないはず。
なんだ?
バージョン管理しているので、戻そうかと思ったけど、また変更を加えるのは面倒なのでとりあえず、ダイアログを自動生成しないようにしてみる。
変わらず例外発生。
プロパティ経由を、メンバ直接アクセスに戻す。
例外が発生しなくなった。
プロパティ経由とメンバ直接アクセスは何か違うのだろうか?
読み出しの場合、プロパティは単にメソッドを呼び出し、その結果を使っていると思っていたのだが・・・
その読み出し用メソッドは単純に参照を返しているだけ。
よくわからないなぁ。
デバッガで追うと、初期化が完了していない値が返ってきているか、変なアドレスを参照しているみたい。
よくわからんな。

投稿者 Takenori : 01:16 | トラックバック

シーン周りを整備

シーンの追加/削除/名前の変更が行えるようにした。
Enterキーでメニューを表示できるようにしようとしたら、メニュー項目決定のEnterで再びメニューが表示されてしまい、かなり使いづらい。なんか、前も同じ事やったような・・・。で、諦めた気がする。
でも、今回はいい方法を思い付いた。単に、Enterではなくスペースキーでメニューを表示させると言うだけのことだが。
で、そのように実装。
いい感じ。

直近でやることをメモ。
プロジェクトプロパティに基づき、レイヤー数を変更する。
コマンド属性のメモリ上での保存とフォームへの反映。
現在固定になっているグリッドの横の数をコマンド数に応じて追加する。
プロジェクトの生成/保存部分を作る。

投稿者 Takenori : 03:04 | トラックバック

こまごまとした事

プロジェクトプロパティに基づき、グリッドのレイヤー数とサウンドバッファ数を決定するようにした。
グリッドの横の数をコマンド数+100になるようにした。
変更付加セルでクリックされた場合、その前に有効になっていた位置でメニューが表示されていたのを、表示されないようにした。
シーケンサーが閉じようとされた時、実際には閉じずに、非表示にするだけにした。
メインフォームのボタンからシーケンサーを表示できるようにした。
メインフォームも現在のシーンを保持していたので、そのプロパティを削除。
そのプロパティを参照していたDocModuleのメソッドも削除。
使われていないソースファイルがあったので削除。
シーケンサーが表示される時、ドキュメント(DocModule)に基づきシーンタブとグリッドの左端の項目が設定されるようにした。

これで、プロジェクト生成/保存部分までにやることは、少し大変なコマンド属性のメモリ上での保存とフォームへの反映のみになった。

ちょっとメモ。
コマンド属性を生成する時、レイヤー番号などもきちんと設定すること。

こういった細々とした事はここに書かずに、こまめにコミットしてそこにコメントとして書いたほうが良いかも。
それと、早めにWebSVNの設定をしてブラウザでコメントなどを見やすくしたほうが良さそう。

投稿者 Takenori : 03:31 | トラックバック

2005年01月30日

レイヤー番号の設定など

コマンド属性を生成する時、レイヤー番号やサウンドのバッファ番号を設定するようにした。
また、セルを塗るかどうか判断するところで、レイヤー番号などを参照して、適切なセルのみ塗りつぶされるようにした。

やることメモ
セルを塗るかどうか判断するところで、ムービー関連の判定はまだ。
ムービー関連は、前方のコマンドを参照して、レイヤーモードかオーバーレイかを判断する必要があるのと、レイヤー番号も途中で設定されるため、対象となるコマンドを見ただけでは判断できない。
これは、イメージが表示されているかどうかわかりやすく表示する時に対応することにする。
まあ、対応していなくてもそれほど問題ではないはず。少しわかりづらいけど。

投稿者 Takenori : 01:51 | トラックバック

2005年03月03日

とりあえずINIで

XMLにしようと思っていたけど、とにかく一通り動くようにしようと思い、INIファイルにプロパティなどを保存することにした。
現状1階層しか必要ないので、INIで十分。
データ部分にはSQLiteを使う予定なので、階層はそちらに保存すると言う手もあるし。
でも、必要になったらXMLにしたいところ。

投稿者 Takenori : 03:04 | トラックバック

 
Total : Today : Yesterday :