こんにちは、高木です。
前回予告したように今回はplacerを実装していくことにします。placerには固有のサブコマンドはないので、geometry_managerクラスで定義したサブコマンド用のメンバー関数だけで十分です。
ただ、placerでは複数のウィジェットを指定することができません。geometry_managerの基本コマンドやconfigureは複数のウィジェットを指定できるようになっていますので、それらを使えないようにした方がいいでしょう。
それでは、placerのコードをざっと書いてみることにします。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
namespace tk { class placer : public geometry_manager { public: placer() : geometry_manager(u8"place") { } int operator()(std::initializer_list<window> windows, std::initializer_list<tcl::obj> options) const = delete; int operator()(std::initializer_list<window> windows) const = delete; int operator()(const window& w) const = delete; int configure(std::initializer_list<window> windows, std::initializer_list<tcl::obj> options) const = delete; }; } |
これで最低限のことはできるようになりました。使えないメンバー関数はdeleteしておきました。
これだけでもいいのですが、placerのもっとも基本的な使い方はXY座標を指定してウィジェットを配置するというものです。ですので、その使い方に特化したメンバー関数を追加した方がいいでしょう。
configureまでXY指定専用のメンバー関数を用意するかどうかは微妙なところですが、今回は割愛して基本コマンドだけにしておきます。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using geometry_manager::operator(); int operator()(const window& w, int x, int y, std::initializer_list<tcl::obj> options) const { tcl::obj x_option(u8"-x"); tcl::obj y_option(u8"-y"); tcl::obj x_arg(x); tcl::obj y_arg(y); std::vector<Tcl_Obj*> args{ type().get(), w.get().path().get(), x_option.get(), x_arg.get(), y_option.get(), y_arg.get() }; auto interp = w.get().interpreter(); set_options(args, options); return interp.evaluate(args); } int operator()(const window& w, int x, int y) const { return operator()(w, x, y, {}); } |
基底クラスであるgeometry_managerのoperator()も使いたいので、新しく追加したoperator()がそれらを隠蔽してしまわないようにusingを使っています。あとは素直に実装しただけです。
ここまでやって気付いたのですが、こういう専用のメンバー関数を都度追加していくより、オプション用の関数かクラスを作って簡単に”-x 数値”や”-y 数値”を指定できるようにする方が得策かもしれませんね。
オプションの指定方法の改善については後日考えることにして、次回はgridderを考えていくことにします。