GUI

布局建议

尽量不要使用以下事件:松开右键、双击左键。原因是移动平台不支持或不推荐这些操作。

原则上不再支持使用水平滚动条,为此尽量不让出现水平滚动。实在避免不了,1)只让小幅滚动,2)界面让有较好提示,举个例子,要在一行显示10个按钮,而每屏最多只能显示两个,那在每个按钮左上角放上(1/10)字样,让用户很快知道前、后还有多少内容。

 

一、布局

1.1 栈层(stack)

单选(radio)模式,用在场景时,需打勾“最大页的标称尺寸作为该控件的标称尺寸”

对单选模式,如果不打勾该选项,控件的标称尺寸等于当前正显示layer的标称尺寸。为什么不像画中画一样取所有layer中最大的标称尺寸。

  1. 按布局规则,INVISIBLE状态的控件不应该计算标称尺寸,layer也是控件,一旦不符合就会造成错误。举个例子,要用layout_init置text_maximum_width_为0,而tgrid::layout_init只清visible!=twidget::INVISIBLE的栅格,此时若计算visible==twidget::INVISIBLE栅格标称尺寸,会使得当中存在多行文本控件时,用不是0的text_maximum_width_去计算,导致算出过大标称尺寸。
  2. app可能在每个layer放上复杂布局,每次计算标称尺寸时都要算所有layer会影响效率。举个例子,该窗口从上到下以着header、body、navigation布局,body顶层就是个stack,然后通过navigation切换到相应layer。

回到问题,为什么场景下得打勾控件的标称尺寸取最大页的,让看一个示例。

一stack有两个layer:tb_normal_layer(标称高度50)和tb_share_layer(标称高度45)。现在要从tb_share_layer切换到tb_normal_layer。因为当前正显示的layer是tb_share_layer,计算渲染尺寸是根据它来的,值是(1080, 45)。要切到换tb_normal_layer,这时要计算标称尺寸,这个是按切换到的tb_normal_layer来的,算出的是(450, 50)。由于标称高度50大于渲染高度45,set_radio_layer(layer)中的tgrid::place认为放不下,抛出异常。此时tgrid::place中的grid是tb_normal_layer,是那个要被显示的grid。

<librose>/gui/widgets/stack.cpp
------
void tstack::set_radio_layer(int layer)
{
	...

	if (desire_visible_grid != nullptr) {
		if (window->layouted()) {
			// below logic likes invalidate_layout
			desire_visible_grid->clear_text_maximum_width();
			// 此时已在显示tb_normal_layer, 如果不打勾选项,算出的是此layer的标称高度50
			tpoint size = get_best_size();
			// size是现在正在用的渲染尺寸。如果不打勾选项,基于的标称尺寸是根据tb_share_layer算出的,高度是45
			bool require_layout = size.x > w_ || size.y > h_;
			if (!require_layout) {
				size = calculate_best_size_bh(w_);
				require_layout = size.x > w_ || size.y > h_;
			}

			if (!require_layout || window->is_scene()) {
				// 场景时,不管将有的标称高度有没有大于现在的渲染高度,都会进入这里
				desire_visible_grid->place(get_origin(), get_size());
			} else {
				// 场景时,trigger_invalidate_layout(window)是个空操作,因而不会进入这里
				// if this best_size > last render_size, -->layout
				lock.reset();
				trigger_invalidate_layout(window);
			}
		}
		...
	}
}

解决办法。

  1. stack计算渲染尺寸时,使用tb_normal_layer的。——此时显示上已切换到tb_normal_layer,但只能计算标称尺寸。渲染尺寸只能使用之前,而之前的i渲染尺寸是根据之前正显示的layer计算的,即tb_share_layer。
  2. 不调用tgrid::place,而是告知重布局整个窗口。——场景时,trigger_invalidate_layout(window)是个空操作,没有重布局窗口功能。
  3. 把此个stack配置成“最大页的标称尺寸作为该控件的标称尺寸”。

采用第三种方案。这也要求,在场景中,使用的stack控件必须打勾“最大页的标称尺寸作为该控件的标称尺寸”。

 

1.2 报表(report)

对多行报表,如果各个单元控件含有长、短不一文字,建议给宽度的标称尺寸设个固定值。原因是多行时,一旦宽度没有设固定值,报表单元标称尺寸取的是第一个显示单元的标称尺寸。设固定值能避免报表布局受第一个单元是啥文字的影响。

举个例子,有一个单元类型是vertical_node风格按钮的多行报表。在t1时刻,第一个单元底下文字是“聊天”,算出的标称尺寸是(96, 116),此时报表会按96这个宽度去布局每个单元(多行报表时,每单元尺寸必相等)。在t2时刻,第一个单元文字是“去位置”,算出标称尺寸是(108, 116),此时报表会变成按108这个宽度去布局每个单元。

全部评论: 0

    写评论: