こんにちは、高木です。
前回予告したように今回は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を考えていくことにします。






