こんにちは、高木です。
前回やり残してしまったgridderのサブコマンドを今回は実装してしまいましょう。残っているのは次の4つです。
- bbox
- location
- remove
- size
まずはbboxからです。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
std::span<Tcl_Obj*> bbox(const window& w) const { if (sub_command(u8"bbox", w) != TCL_OK) return {}; auto interp = w.get().interpreter().get(); auto r = Tcl_GetObjResult(interp); int objc; Tcl_Obj** objv; Tcl_ListObjGetElements(interp, r, &objc, &objv); return { objv + 0, objv + objc }; } int bbox(const window& w, std::initializer_list<tcl::obj> options) const { return sub_command(u8"bbox", w, options); } |
std::spanを返す最初の形式はslavesメンバー関数とほとんど同じです。下請けメンバー関数を作ってまとめられるので、今回は安直なコピペで対応したいと思います。
次はlocationです。
0 1 2 3 4 5 6 7 8 |
tcl::obj location(const window& w, int x, int y) const { if (sub_command(u8"locatione", w, { x, y }) != TCL_OK) return {}; auto interp = w.get().interpreter().get(); return Tcl_GetObjResult(interp); } |
結果は整数値になるので、tcl::obj型ではなくint型にしてもよかったのですが、エラー発生時に例外を送出するしかなくなるので、いったんtcl::obj型を返すことにしました。エラー発生時は空の値を返します。
次はremoveです。
0 1 2 3 4 5 6 7 8 9 10 |
int remove(const window& w) const { return sub_command(u"remove", w); } int remove(std::initializer_list<window> windows) const { return sub_command(u"remove", windows); } |
initalizer_listで渡すものだけでもいいのですが、単独のウィジェットを指定するケースが結構あると思うので、専用のメンバー関数を用意しました。
最後はsizeです。sizeメンバー関数が返す値のために、次のような構造体を用意することにします。
0 1 2 3 4 5 6 7 8 9 |
namespace tk { struct size { int width; int height; }; } |
この構造体は汎用的なものですので、今回に限らずいろいろ使っていけると思います。
準備ができたところで実際のsizeメンバー関数を実装していきます。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
tk::size size(const window& container) const { if (sub_command(u8"size", container) != TCL_OK) return { -1, -1 }; auto interp = container.get().interpreter().get(); auto r = Tcl_GetObjResult(interp); int objc; Tcl_Obj** objv; if (Tcl_ListObjGetElements(interp, r, &objc, &objv) != TCL_OK) return { -1, -1 }; if (objc != 2) return { -1, -1 }; return { tcl::obj(objv[0]).get_int().value_or(-1), tcl::obj(objv[1]).get_int().value_or(-1) }; } |
たったこれだけのことなのにちょっと煩雑になってしまいました。まだまだ改善の余地がありそうです。
なかなか完璧にはほど遠いですが、これでgridderクラスが一通り完成しました。