MozillaZine.jp フォーラム
https://forums.mozillazine.jp/

prefwindowのtype属性について
https://forums.mozillazine.jp/viewtopic.php?f=26&t=8017
ページ 11

作成者:  ma2ten [ 2008年12月08日(月) 18:07 ]
記事の件名:  prefwindowのtype属性について

自作のFirefox拡張用オプションダイアログにprefwindowを用いています。
MDCのprefwindowの説明ページを見てみると、type属性について次のように書いてあります。
引用:
type
"prefwindow" または "child" のどちらかでなくてはいけません。
type="child" は、トップレベルの設定ウィンドウから開かれるサブダイアログ(それは通常モーダルダイアログです)であることを示します。(MacOS XやGNOMEのように)設定を即座に適用する環境では、このサブダイアログは、それらの設定を書き込んでもよいかどうか確認されます。(Windows のように)設定を即座に適用しない環境でサブダイアログが確認された時(OKボタンが押された時)は、なされた変更は親ウィンドウの<preferences>のセットに保持され、親ウィンドウが確認された時に保存されます。子ウィンドウとなる設定ウィンドウは、複数のペインを持つことはできません。

Windows環境ではこの値によらず(省略しても)ダイアログのルックスも動作も変わりありません(OK、キャンセルボタン付き)。

ところがLinux(Ubuntu)環境で確認してみたところ、type属性を省略するか"prefwindow"にすると、ダイアログには「閉じる」ボタンしかなく、OKボタンもキャンセルボタンも付きません。
試しに「buttons="accept,cancel"」を追加してみても変わりませんでした。

それで今度は「type="child"」にしてみたところ、OKボタンとキャンセルボタンが付き、代わりに閉じるボタンが無くなりました。

一応「type="child"」にすれば、Windows/Linux(Ubuntu)両環境ともで望んだ動作をしてくれるようなのですが、上記説明によるとtype属性がchildの時は「複数のペインをもつことはできません。」となっているのが気になります。
実際試してみると複数ペインを持つダイアログでも前述のように正しく動作しているように見えますが、説明が間違っているのか、それとも私の解釈が間違っているのか、もしかして拡張のオプションダイアログはトップレベルのウィンドウではないということか・・・混乱しています。

ということで、どなたか正しい仕様について教えていただけないでしょうか。
よろしくお願いします。

作成者:  Piro [ 2008年12月09日(火) 01:01 ]
記事の件名:  Re: prefwindowのtype属性について

Linux(のGNOME)やMac OS Xでは、その環境用のアプリケーションの標準的なインターフェースデザインのガイドラインで、
・設定ダイアログに類する物は基本的に「チェックボックスなどの状態を変えたら即座に変更を反映」「OK/キャンセルのボタンは存在しない(すぐに変更が反映されるので意味がない)」
・ただし、フォント設定などのサブダイアログは特例的に「チェックボックスなどの状態の変更は即座には反映しない」「OKボタンを押したら初めて反映」
という風に決まっていたと思います。これが、それぞれtype="prefwindow"とtype="child"に対応しています。

Windowsの場合、上記のような区別はなくて、どちらの場合も「チェックボックスなどの状態の変更は即座には反映しない」「OKボタンを押したら初めて反映」という挙動になるのが標準的です。なので、Windowsではtype="prefwindow"とtype="child"で差はありません。

アドオンを作る際に「設定ダイアログの挙動をプラットフォームの標準的な挙動に合わせたい」と思った時、普通にwindow要素やdialog要素を使うと、上記の挙動の違いを再現するためにnavigator.platformを見て判別するとかそういった面倒な事が必要になってきます。
その手間を軽減して、<prefwindow type="...">と書いておきさえすればFirefoxの方で勝手にプラットフォームに合わせた挙動を再現してくれる、というのがprefwindow要素と一連の要素の役割です。
逆に、全てのプラットフォームで必ず同じ挙動にさせたいのであれば、window要素を使って構成要素を全て作り込む必要があります。(dialog要素も、OKボタンとキャンセルボタンの表示位置がプラットフォームごとに自動調整されます)

引用:
上記説明によるとtype属性がchildの時は「複数のペインをもつことはできません。」となっているのが気になります。


ここは僕が訳したのですが、原文でそうなっていたので特に疑問も持たずそのまま訳してしまいました。

というわけで、実装はどうなっているのかを見てみました。
http://mxr.mozilla.org/mozilla-central/ ... es.xml#595
http://mxr.mozilla.org/mozilla-central/ ... es.xml#778
見たところ、type="child"な設定ダイアログではペインを切り替えてもダイアログの大きさが変化しない(OS Xではtype="prefwindow"な設定ダイアログではペインを切り替えるとダイアログの大きさが内容に合わせて変わる)という違いがあるようです。
実装上は、childな設定ダイアログでも複数ペインは持てるようですが、GUI設計ガイドライン的には想定されていない、といったところではないかと思われます。

……といった感じの回答で当を得ていますでしょうか?

作成者:  ma2ten [ 2008年12月09日(火) 14:58 ]
記事の件名:  Re: prefwindowのtype属性について

解説をありがとうございます。ようやくあの説明の意味が飲み込めた気がします。

確かにLinuxではチェックボックス等の変更した結果はOKボタンが無くとも保存されていました。
つまり、preference項目の値と関連付けたコントロールの値は、環境ごとUIガイドラインにそったタイミングで保存されるということですね。

しかしそうすると、単純にpreference項目と連結できない値の保存で困ることになります、というか現在それで困っています。

例えば、あるボックス(vbox)の中に複数(動的に変わる)のチェックボックスが含まれる時、この内チェックされているものだけのIDを1つのpreference項目に文字列に加工して保存したいとします。
Windowsではprefwindowのondialogacceptハンドラの処理で行う事で解決していますが、これをLinux(GNOME)環境で実現するには普通どう実装するのが適当なのでしょうか。

作成者:  Piro [ 2008年12月09日(火) 17:12 ]
記事の件名:  Re: prefwindowのtype属性について

ma2ten さんが書きました:
例えば、あるボックス(vbox)の中に複数(動的に変わる)のチェックボックスが含まれる時、この内チェックされているものだけのIDを1つのpreference項目に文字列に加工して保存したいとします。
Windowsではprefwindowのondialogacceptハンドラの処理で行う事で解決していますが、これをLinux(GNOME)環境で実現するには普通どう実装するのが適当なのでしょうか。


prefwindow関連要素の設計としては、このような場合は以下のようにするといいようです。

1. 文字列値の設定を保持するためのpreference要素を置いておく。(これに関連づけるtextboxなどは置かない)
2. prefpane要素のonpaneloadイベントハンドラで、上記preference要素のvalueプロパティの値を取得し、それを元にcheckbox要素(これらはpreference属性を持たず、preference要素には関連づけられていない)を初期化する。
3. checkboxのcommandイベントをoncommandイベントハンドラ等で拾って、動的に上記preference要素のvalueプロパティを更新する。

あと、onsyncfrompreferenceイベントハンドラ、onsynctopreferenceイベントハンドラあたりも使えるかもしれません。
https://developer.mozilla.org/ja/Prefer ... attributes

作成者:  ma2ten [ 2008年12月09日(火) 18:34 ]
記事の件名:  Re: prefwindowのtype属性について

Piro さんが書きました:
1. 文字列値の設定を保持するためのpreference要素を置いておく。(これに関連づけるtextboxなどは置かない)
2. prefpane要素のonpaneloadイベントハンドラで、上記preference要素のvalueプロパティの値を取得し、それを元にcheckbox要素(これらはpreference属性を持たず、preference要素には関連づけられていない)を初期化する。
3. checkboxのcommandイベントをoncommandイベントハンドラ等で拾って、動的に上記preference要素のvalueプロパティを更新する。

なるほど。
自分が今までpreferenceについて色々誤解したまま使っていた事が分かりました。
示していただいた方法で何とか対応できそうです。
(onsyncfrompreference、onsynctopreferenceの両イベントハンドラについても未確認でした)

もやもやが晴れた気分です、ありがとうございました。

作成者:  [ 2008年12月09日(火) 22:35 ]
記事の件名:  Re: prefwindowのtype属性について

Piro さんが書きました:
Windowsではtype="prefwindow"とtype="child"で差はありません。
差はあります。
type="prefwindow" では、OK を押すと設定が反映されます。
そこから開いた type="child" な prefwindow では、OK を押しても反映はされません。元の type="prefwindow" で OK を押して初めて反映されます。(親の方でキャンセルすると、子での OK を反映せずに済ますことができます。)

# 余談ですが、Fx3 はそのロジックが一部壊されたままリリースされてました。理解されてないから壊されるんですかね。
# バグ Fix して、リリース版としては Fx3.0.4 で直しました。自動テストも入れましたので同じ過ちは繰り返させません。(Piro さんが今やってるのと似たような話ですね)

Piro さんが書きました:
http://mxr.mozilla.org/mozilla-central/source/toolkit/content/widgets/preferences.xml#595
http://mxr.mozilla.org/mozilla-central/ ... es.xml#778
リンクを書き込む際は、MXR へのリンクではなく、そのページ右上の HG Blame というリンクをたどって、特定のリビジョンへのリンクを書き込むのをお薦めします。
MXR では、ソースが修正されて行が追加/削除されると行がずれてしまって、後から見たときにはどこを指しているつもりなのかわからなくなっている場合があります。
(変更で、指していた場所がなくなってしまうことさえあり得ます。)

ページ 11 All times are UTC + 9 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/