Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

按钮的 normalimage 怎么设置可以在按钮内居中显示? #53

Closed
01haike opened this issue Jun 26, 2019 · 22 comments
Closed

按钮的 normalimage 怎么设置可以在按钮内居中显示? #53

01haike opened this issue Jun 26, 2019 · 22 comments
Labels
question Further information is requested

Comments

@01haike
Copy link

01haike commented Jun 26, 2019

我尝试使用 dest,不能达到居中显示的效果。
xml 如下:

<Button name="testbtn" width="100" height="35" bkcolor="blue" normalimage="file='add_normal.png' dest='0,0,25,25'" hotimage="file='add_hover.png' dest='0,0,25,25'" pushedimage="file='add_pushed.png' dest='0,0,25,25'" />
@smallevilbeast
Copy link
Contributor

dest 前两个值 你得设置
(控件宽度-图片显示宽度)/ 2

你设置成0,0 肯定在左上角开始绘制的

@01haike
Copy link
Author

01haike commented Jun 26, 2019

dest 前两个值 你得设置
(控件宽度-图片显示宽度)/ 2

你设置成0,0 肯定在左上角开始绘制的

嗯嗯,是的。不过我想要的效果是自动居中显示,不用每次都计算一下按钮和图片的大小。

@smallevilbeast
Copy link
Contributor

dest 前两个值 你得设置
(控件宽度-图片显示宽度)/ 2
你设置成0,0 肯定在左上角开始绘制的

嗯嗯,是的。不过我想要的效果是自动居中显示,不用每次都计算一下按钮和图片的大小。

那需要使用Box组合下

@01haike
Copy link
Author

01haike commented Jun 26, 2019

@lovesnow 用 box 组合还需要处理鼠标消息,hover之类的。
现在我改 duilil 代码,可以实现。不知道有没有现成的方法。

在 Control::DrawImage 里加了:

	if (newImageAttribute.bDestCenter)
	{
		rcNewDest.left = m_rcItem.left + m_rcItem.GetWidth() / 2 - (duiImage.imageCache->nX) / 2;
		rcNewDest.right = rcNewDest.left + duiImage.imageCache->nX;
		rcNewDest.top = m_rcItem.top + m_rcItem.GetHeight() / 2 - (duiImage.imageCache->nY) / 2;
		rcNewDest.bottom = rcNewDest.top + duiImage.imageCache->nY;
	}

在 ImageAttribute::ModifyAttribute 里加了:

			else if (sItem == _T("dest_center")) {
				imageAttribute.bDestCenter = true;
			}

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jun 26, 2019

可使用 ButtonBox,具有布局属性的控件盒子模型,参考:https://github.com/netease-im/NIM_Duilib_Framework/blob/master/docs/ControlBox/Other.md

<ButtonBox width="100" height="100" bkcolor="darkcolor">
  <Control width="auto" height="auto" bkimage="..\public\animation\ani_loading_ex.gif" valign="center" halign="center"/>
</ButtonBox>

@nmgwddj nmgwddj added the question Further information is requested label Jun 26, 2019
@01haike
Copy link
Author

01haike commented Jun 26, 2019

@nmgwddj
这样的话,我鼠标放到 buttonbox 上,但是没在内部 control 上的时候,内部 control 并不会收到鼠标消息,不会更改内部 control 的图片状态。对了,中间的control 想做成 normal,hot, pushed 这种。

还有处理 click 事件的时候,给 buttonbox 绑定的话,点击中间 control 就没有效果。

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jun 26, 2019

这些属于业务层面的问题,请根据您自己的需求定制业务代码就可以了,很多种方式都可以实现以上需求。您可以自己处理不同控件的不同事件、根据自己的需求做过滤。标准控件中没有这么复杂的实现,所以可能需要您自己来重写一些控件实现以上功能。

@smallevilbeast
Copy link
Contributor

如果说 mouse消息事件能够向父传递 也可以解决这个问题

@01haike
Copy link
Author

01haike commented Jun 26, 2019

如果说 mouse消息事件能够向父传递 也可以解决这个问题

是啊,跟我之前提的一个问题很像。#49

@smallevilbeast
Copy link
Contributor

如果说 mouse消息事件能够向父传递 也可以解决这个问题

是啊,跟我之前提的一个问题很像。#49

我晚上看上, 看看能不能提交一个PR上来

@01haike
Copy link
Author

01haike commented Jun 26, 2019

如果说 mouse消息事件能够向父传递 也可以解决这个问题

是啊,跟我之前提的一个问题很像。#49

我晚上看上, 看看能不能提交一个PR上来

辛苦了。其实给 normalimage 加上一个 dest_center 属性就可以解决 issue 的问题。
在画图片的时候,如果有 dest_center 属性,就忽略 dest 属性,然后计算一下新的 rect。

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jun 27, 2019

@01haike @lovesnow 这个功能为更建议从上层业务代码来实现,Duilib 提供控件的一些基础功能,其实我们完全可以从 ButtonBox 继承来实现更丰富的功能,但这样与业务高度耦合的代码放到基础代码中,可能并不是特别合适。

@01haike
Copy link
Author

01haike commented Jun 27, 2019

@nmgwddj 其实我感觉这个 issue 并不是业务代码啊,本身 normalimage 提供 dest 属性,可以设置画在按钮上的位置。那么提供图片总是画在按钮中间位置的属性也是合理的啊。

还有,类似 Windows 窗口管理,当点击一个窗口的时候,会先通知子窗口,如果子窗口处理了,父窗口相应函数不会被调用;如果子窗口没处理,调用父窗口相应的函数。这样是不是更合理一些呢?

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jun 27, 2019

图片在中间的功能我们就不多赘述了,通过 ButtonBox 很方便的可以实现。关于控件事件捕获的问题,我们不如换个角度来考虑这个问题。类似的控件在什么交互场景下会用到呢?

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jun 27, 2019

换另外一种场景来解决这个问题。使用 Button 控件,图片素材自身就是有周边透明区域的,给 Button 设置不同状态下的不同背景图片,这样也可以实现类似需求。这样就不存在事件被图片控件捕获的情况了。
使用 ButtonBox,将内部控件 mouse 属性设置为 false,外部 ButtonBox 在收到不同的事件时去更改中间区域的图片状态也是可行的,不希望通过 C++ 代码实现使用 XML 的 Event 功能也是可以的。

@01haike
Copy link
Author

01haike commented Jun 27, 2019

@nmgwddj 比如我现在要实现的按钮,width=170,height=35,背景色不设置(跟随父Box),normalimage, hotimage, pushedimage 大小都是 25。当鼠标放到按钮上任意位置的时候,要改变 image 的状态。点击按钮任意位置也要产生 click 事件。

@01haike
Copy link
Author

01haike commented Jun 27, 2019

换另外一种场景来解决这个问题。使用 Button 控件,图片素材自身就是有周边透明区域的,给 Button 设置不同状态下的不同背景图片,这样也可以实现类似需求。这样就不存在事件被图片控件捕获的情况了。
使用 ButtonBox,将内部控件 mouse 属性设置为 false,外部 ButtonBox 在收到不同的事件时去更改中间区域的图片状态也是可行的,不希望通过 C++ 代码实现使用 XML 的 Event 功能也是可以的。

第一个透明区域那个好像有缩放问题,因为中间的小图标不能缩放。
第二个我试试,还是因为对 duilib 了解的不够,看来 xml event 很强大啊。

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jun 27, 2019

用以上介绍的两种方案都可以实现你的需求。
1、既然按钮大小已经确定,可以制作 width=170 height=35 的 png 图片素材,周边区域透明,只有中间 25x25 的位置有实际图片内容,使用 Button 控件三种状态的图片切换即可实现。如果按钮大小不确定的,又或者你说可能有缩放的情况可以用下面这种方案。
2、使用 ButtonBox,实际素材大小是 25x25,使用 Control 控件来绘制素材居中显示,并设置 mouse 属性为 false。设置 ButtonBox 有鼠标进入或者离开时去更新 Control 的背景图就可以了。

@01haike
Copy link
Author

01haike commented Jun 27, 2019

@nmgwddj 对于 BottonBox 这种方法,感觉 ButtonBox 本身可能存在问题。因为 BottonBox 既是 Box 也是 Button,对于BottonBox 感觉应该是一个整体,所以内部控件元素也应该收到整个 BottonBox 的鼠标事件。

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jul 5, 2019

@01haike ButtonBox 作为一个既具有布局又有控件功能的盒子就是给大家提供想实现类似功能而开发的,UI 库提供基础,当然更细节个性化的功能是需要开发者定制开发的。在开发过程中很多事情是鱼和熊掌不能兼得的,这就要开发者甚至产品人员介入来一起协商,所以我们希望底层的实现更接口化,与业务高度结合后的 UI 实现可以在不断沉淀后抽象出接口提供开发者去实现更细节的功能。
您这个需求的确也是有必要的,因为这种场景在 Web 开发中太常见了,这也是为什么越来越多人转移到用前端做 UI 展示的原因。
如果您觉得以上方法可能不能完全满足您的需求,您可以适当做一些代码上的调整,也欢迎提交 PR 来帮我们完善这些功能。

@nmgwddj nmgwddj closed this as completed Jul 18, 2019
@chaome
Copy link

chaome commented Jul 4, 2022

这是我见过最推诿的回复。
要么你推荐他自己动态计算图片缩放/裁剪后的最终位置,设置背景图的dest范围;要么来一个计划后续升级背景图的布局选项:居中、等比缩放、原图裁剪,背景图边距等。

背景图拉伸填充本身就是一个不合理的设计,需要辅助的属性以支持背景图的功能完整性。

@nmgwddj
Copy link
Collaborator

nmgwddj commented Jul 4, 2022

感谢您的批评,我们会重新思考接下来对 duilib 的迭代事宜。
duilib 在现代 UI 框架中并不占特别优势,所以不可避免的我们会适当倾斜资源到一些其他的框架的调研和学习中,这也导致我们工作重心无法投入到 duilib 的迭代。
我们希望 duilib 未来的发展是一个轻量级的跨平台 UI 框架,这中间不仅仅需要核心维护团队花费大量精力,更需要像您这样的社区朋友支持提交一些合理的设计方案或者 PR。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants