|
本帖最后由 ancientcc 于 2017-4-15 09:32 编辑
- twidget* twiddet::find_at(const tpoint& coordinate, const bool must_be_active);
- twidget* twidget::find(const std::string& id, const bool must_be_active);
- template<class T>
- T* find_widget(typename utils::tconst_clone<twidget, T>::pointer widget, const std::string& id, const bool must_be_active const bool must_exist)
- {
- T* result = dynamic_cast<T*>(widget->find(id, must_be_active));
- VALIDATE(!must_exist || result, missing_widget(id));
- return result;
- }
复制代码
find_at根据坐标搜索控件,find根据id搜索控件,它们都是twidget的成员函数。find_widget则是全局函数,它借用find实现根据id搜索控件,第三个参数must_exist不是搜索条件,它是指示当搜不到控件时,是否要弹出诊断框。
搜索要不断深入,最后位置的控件称末端控件,中间遍历过的称为非末端控件。
过程中遇到不是VISIBLE状态的非末端控件时(或INVISIBLE,或HIDDEN),find_at会中断搜索,find则会继续。为什么这样设计?find_at是根据坐标搜索,坐标能够有效,意味着要成功布局,而INVISIBLE状态的控件不参与布局,它的坐标即使值是在窗口内,也应该视为无效;HIDDEN虽然参与布局,但对鼠标来说,不可操作。要注意,当控件处于INVISIBLE时,它的渲染矩形依旧可能在窗口内,举个例子,有时代码只是简单把某个控件设为INVISIBLE。
过程中遇到不是滚动面板(scroll_panel)的滚动控件,find会略过搜内容网格,find_at则会深入搜此网格。为什么这样设计?像列表,很少需要从窗口起搜索行内控件,而且一旦每次都要搜所有行,会耗时。默认不会搜索内容网格,如果非要搜,可调用set_find_content_grid(true)。
find_at对末端控件要求。1)不论must_be_active是何值,都不会搜出非VISIBLE控件。2)must_be_active要求tcontrol处于active状态。3)采用了不拉伸对齐方式的控件,那会产生“空洞”,如果坐标属于“空洞”,那认为搜不到。举个例子,一个中间对齐的label,如果文字不能满行,那两侧就会产生“空洞”,那find_at将返回NULL。在这方面尤其要注意的是spacer控件,在放置这类控件往往都是不拉伸的,这意味着它们占有的空间都是“空洞”。4)不会把派生于tcontian_的控件做为搜索结果,这意味着像不可能搜出twindow。
find对末端控件要求。它不管控件处于INVISIBLE、HIDEN还是VISIBLE,只要满足active和id一致则认为搜索成功。
find_at是Rose内部使用,只用在鼠标模块,而且must_be_active固定是true,用于搜索鼠标位于它之上的控件。
|
|