UI Framework-1: Native Controls
Native Controls
BackgroundDespite the fact that views provides facilities for custom layout, rendering and event processing, in many situations we have found it desirable to use the controls provided by the host operating system (Windows to begin with). This is because these widgets already have many desirable properties: a system-native appearance that reflects the latest and greatest of the host operating system (e.g. using the same Win32 API as Windows XP on Windows Vista, native buttons receive glow animations when highlighted), handling for accessibility, focus, etc. Implementing new controls using views and Skia would be possible but it would take a long time to replicate all of this functionality, and we would have to update it for each new operating system release as well. So for areas of our UI where it wasn't important to have a distinctive, custom look, we have fallen back to native controls.
Historic AbstractionHistorically, NativeControls have been used like so:
![]() A base class, NativeControl, is the root of all NativeControls, like buttons, checkboxes, tree views, etc. This View subclass is Windows-specific and has a child View that is a HWNDView. This HWNDView hosts a HWND (NativeControlContainer) that is the parent of the actual native control HWND. The parent is responsible for receiving messages sent from the child HWND (e.g. WM_COMMAND, WM_NOTIFY etc) and forwarding these back to the NativeControl. This structure with the additional HWND was thought necessary because the assorted Windows common controls communicate message notifications to the client app by sending messages to the parent window. Back when Chrome had several different ViewContainer/root widget types, it made sense to encapsulate this handling at the NativeControl level. These days, there is only one root HWND type to be concerned with - WidgetWin, so it actually makes more sense to have it receive control notifications and forward them back to the NativeControl, rather than having to carry around all these extra HWNDs.
Another problem with this abstraction is related to the fact that Chrome has many different kinds of Buttons. Because NativeButton has no shared base class with the other Button base (BaseButton), much of the API ends up being slightly different. It'd be desirable to share a base class and then implement any of the NativeButton-specific methods in the derived class. However this is not possible due to this structure.
A final point of note: some NativeControl subclasses like CheckBox are a combination of system native controls and views components. To get proper transparent rendering behind the text label of a checkbox, the CheckBox has two child views - one which is the native windows control rendering only the checkmark section, and a views::Label child which renders the text. This structure has to be accommodated in any proposed modifications to this design.
Proposed DesignFirst of all, for any proposed design it's desirable to keep the API simple for users since native controls are used in very many places throughout Chrome. Ideally, using a native control is as simple as constructing one and adding it to your view hierarchy, which is the usage model that exists today for the windows-specific native controls and the views controls.
To achieve this, we use the PIMPL idiom to hide the native control implementation from the client in a setup like this:
![]() In this world, NativeButton is a class derived from a base Button class just as the other Button classes are (e.g. TextButton, etc). It overrides various methods that require interaction with the native control, such as making the button appear as the default button in a dialog box etc. The interesting thing here is that the NativeButton itself is cross-platform code. The platform-specific details of implementing a native control are encapsulated behind a platform-neutral NativeControl interface implemented, in this example, by a new class NativeControlWin, a subclass of HWNDView that hosts the actual Windows native control. We avoid having an extra HWND here by stashing a pointer to the NativeControlWin on the attached HWND, and have the message handler in WidgetWin attempt to forward the message to the NativeControlWin directly if it finds such an association. The NativeButton implements a listener interface that receives higher level notifications from the NativeControl implementation about messages received from the operating system. Since NativeControl is an interface not a class, it must provide a GetView accessor for the View that is to be parented as a child of the NativeButton, CheckBox or other view.
In this way, NativeButton can share a base class with other button types. A similar relationship can exist for other native controls where this is applicable, e.g. scroll bars, tree views, etc.
More Complex ControlsFor controls more complex than buttons like, for example, TreeViews, there can be more elaborate code in NativeControlWin subclasses that handle messages from the native UI control and notify the view on the right half of the diagram as needed. Keeping the views on the right half of diagram platform neutral hides the complexity of maintaining platform-specific controls from consumers in the application - e.g. there is no need for ifdefs or factory methods at the call sites - the views can just be constructed directly and added to the view hierarchy:
void FooView::Init() {
button_ = new views::NativeButton;
button_->SetListener(this);
AddChildView(button_);
}
...
void FooView::Layout() {
button_->SetBounds(0, 0, width(), height());
}
vs the more baroque:
void FooView::Init() {
button_ = views::NativeButton::CreateNativeButton();
button_->SetListener(this);
AddChildView(button_->GetView());
}
...
void FooView::Layout() {
button_->GetView()->Layout(0, 0, width(), height());
}
|
UI Framework-1: Native Controls的更多相关文章
- Hybrid UI framework shootout: Ionic vs. Famo.us vs. F7 vs. OnsenUI
1 Introduction In the past 2 years I’ve been working intensively on mobile applications, mostly hybr ...
- 00 - Vue3 UI Framework - 阅读辅助列表
阅读列表 01 - Vue3 UI Framework - 开始 02 - Vue3 UI Framework - 顶部边栏 03 - Vue3 UI Framework - 首页 04 - Vue3 ...
- [转]Ionic – Mobile UI Framework for PhoneGap/Cordova Developers
本文转自:http://devgirl.org/2014/01/20/ionic-mobile-ui-framework-for-phonegapcordova-developers/ Ionic i ...
- 05 - Vue3 UI Framework - Button 组件
官网基本做好了,接下来开始做核心组件 返回阅读列表点击 这里 目录准备 在项目 src 目录下创建 lib 文件夹,用来存放所有的核心组件吧.然后再在 lib 文件夹下创建 Button.vue 文件 ...
- 01 - Vue3 UI Framework - 开始
写在前面 一年多没写过博客了,工作.生活逐渐磨平了棱角. 写代码容易,写博客难,坚持写高水平的技术博客更难. 技术控决定慢慢拾起这份坚持,用作技术学习的阶段性总结. 返回阅读列表点击 这里 开始 大前 ...
- 03 - Vue3 UI Framework - 首页
顶部边栏做完了,接下来开始做官网的首页 返回阅读列表点击 这里 创建视图文件夹 让我们先新建一个 src/views 文件夹,用来存放官网的主要视图 然后在该文件夹下新建两个 vue 文件,作为我们的 ...
- 07- Vue3 UI Framework - Switch 组件
为了更好的提升用户体验,我们这里再做一个很常用的开关组件 switch 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 switch 组件应分为选中/未被选中,两种状态 可以通过 ...
- 08 - Vue3 UI Framework - Input 组件
接下来再做一个常用的组件 - input 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 input 组件有两种类型,即 input 和 textarea 类型 当类型为 ...
- 09 - Vue3 UI Framework - Table 组件
接下来做个自定义的表格组件,即 table 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 基于原生 table 标签的强语义 允许用户自定义表头.表体 可选是否具有边框 ...
随机推荐
- httpClient模拟登陆校内某系统
package com.huowolf; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpE ...
- GitHub客户端和Shell的基本操作和理解
GitHub客户端和Shell指令的简单实用 客户端操作, web端操作, shell指令操作. 掌握了这三种操作,基本上就可以很好的运用gitHub了. 创建项目, 可以通过web端进行创建. 可以 ...
- DB-MySQL:MySQL 语句性能优化
ylbtech-DB-MySQL:MySQL 语句性能优化 1.返回顶部 1. MySQL概述1.数据库设计 3范式2.数据库分表分库---会员系统() 水平分割(分页如何查询)MyChar .垂直3 ...
- angular4(2-1)angular脚手架引入第三方类库(jquery)
欢迎加入前端交流群交流知识&&获取视频资料:749539640 如何在angular4脚手架中引入第三方类库呢比如jquery.swiper.bootstrap...... 例如引入j ...
- kafka的使用
kafka基于zookeeper. 需要安装kafka.zookeeper. 安装方法参考:http://tzz6.iteye.com/blog/2401197 启动zookeeper:点击zkSer ...
- 51nod 1649 齐头并进 (djikstra求最短路径,只用跑一次)
题目: 这道题有一个坑点:两种交通工具同时出发,中途不能停留在同一个小镇. 其实想通了就很简单,因为要么火车一步到达,要么汽车一步到达.不可能停留在同一个地方. 可是我还WA了好几次,蠢哭.想用BFS ...
- hdu 6082 - 完全背包,打表。
2017-08-06 15:02:50 Accepted 1003 187 MS 2168 K G++ redips 对背包有了进一步的认识 ----------------------------- ...
- 初识Git(二)
与我们前一篇随笔一样创建文件夹,init我们创建的文件夹,并且创建一个test.txt文本文件,add文本文件,commit文本文件,接下来在文本文件中添加文本: 与上一次不同的是我们这一次在编辑文件 ...
- 转 c#中 base64字符串与普通字符串互转
https://blog.csdn.net/hwt0101/article/details/79758912 转成 Base64 形式的 System.String: string a = &q ...
- 拓展Lucas小结
拓展Lucas是解决大组合数取模非质数(尤其是含平方因子的合数)问题的有力工具... 首先对模数质因数分解,把每个质因子单独拎出来处理答案,然后用中国剩余定理(excrt)合并 问题转化为,对于每个质 ...

