chromium书签栏实现

本篇文章主要讲解chromium书签栏的实现,主要是想以某一个UI为切入点,更加了解chromium中的UI实现。书签栏的UI界面如下图所示,它包含以下元素:

  • apps_page_shortcut_:一个指向WebUI的按钮,指向chrome://apps/,该按钮总是显示。
  • overflow_button_:当书签栏长度不足够显示全部标签时,会显示该按钮,点击后出现下拉菜单,用于显示剩下的书签页。
  • other_bookmarked_button:其它书签按钮,当其他书签文件夹下保存有书签时会显示该按钮,点击后显示其它书签的下拉菜单。
  • bookmarks_separator_view_:分隔其它书签用的竖线,显示其它书签按钮时会一块显示。
  • instructions_:当没有书签时,会显示该视图,用于导入书签。
  • bookmark button:书签栏上显示的书签。


BookmarkModel

书签栏的视图由BookmarkBarView类实现,在BookmarkBarView::Init函数中,会实例化除了bookmark button外的其它元素,并通过AddChildView函数把它们加入到它的child view中。注意到,BookmarkBarView的chilBookmarkModeld view除了上述5个元素,其它的child view全部是bookmark button。在Init函数中,会创造出BookmarkModel的实例model_,用于实现书签的数据逻辑。BookmarkModel与BookmarkBarView的关系如下图所示:

BookmarkBarView继承自DetachableToolbarView,这种类型的View是可分离工具栏视图,用于书签栏这种可以用户指定显示或者不显示的视图。

BookmarkModel在更新数据后,例如进行增加书签、删除书签、更改书签等操作,会调用监听者BookmarkModelObserver对应的函数,对更新事件进行处理。BookmarkBarView继承了BookmarkModelObserver,当BookmarkModel数据更新后,会对视图进行更新。

BookmarkModel中保存了一棵书签树,书签树的根节点是root,根节点下是三个节点,分别是bookmark_bar_node_、other_node_和mobile_node_,其中bookmark_bar_node_下保存书签栏节点,other_node_保存其它书签节点,mobile_node_作用不祥。具体的书签会保存在这三个节点下,通过parent可以判断该节点是属于书签栏书签或者是其它书签。

书签栏目录菜单

书签栏的子文件夹在显示时会根据需要弹出下拉菜单,包括点击文件夹或拖动书签至文件夹时会弹出。BookmarkBarView中定义了两个菜单对书签栏的子菜单进行管理:
BookmarkMenuController* bookmark_menu_;
bookmark_menu_用于管理用户点击BookmarkBarView中的文件夹时弹出的菜单
BookmarkMenuController* bookmark_drop_menu_;
bookmark_drop_menu_是用户拖拽一个书签到文件夹上时弹出的菜单。

书签菜单的实现较为复杂,类图如下


首先需要显示菜单的按钮包括overflow_button_、other_bookmarked_button_和书签栏上的文件夹,它们都是MenuButton的实例,创建他们时,会把BookmarkBarView设置为其MenuButtonListener。

BookmarkBarView继承MenuButtonListener,当收到MenuButton的点击消息后,调用OnMenuButtonClicked创建BookmarkMenuController实例。

BookmarkMenuController的析构函数为私有的,只能自已析构自己,析构分别在RunMenuAt函数、OnPerformDrop函数和DropMenuClosed函数中进行,也就是关闭显示菜单时。析构时会调用BookmarkBarView::BookmarkMenuControllerDelete函数,将对应的bookmark_menu_或者bookmark_drop_menu_指针置空。

BookmarkMenuController包含BookmarkMenuDelegate,BookmarkMenuDelegate持有菜单的视图menu_(MenuItemView实例),同时BookmarkMenuController继承自MenuDelegate的接口函数都交给BookmarkMenuDelegate对应的函数执行,通过BookmarkMenuDelegate可以操作菜单视图。

BookmarkMenuDelegate中MenuItemView的结构和BookmarkModel类似,都是用树形结构,同时用node_to_menu_map_维护从BookmarkNode节点到MenuItemView节点的映射关系,对BookmarkNode节点的操作可以映射到菜单视图。

MenuRunner在一个嵌套的消息循环上运行菜单视图,目前看到的菜单都需要这个实现机制,目前没有进行研究。

书签栏右键菜单

对书签栏的对象点击鼠标右键时会弹出右键菜单,BookmarkBarView中定义了context_menu_用于管理右键菜单。

scoped_ptr<BookmarkContextMenu> context_menu_;

右键菜单的类图如下所示,以其他书签按钮为例,在创建其它书签按钮时,会通过set_context_menu_controller函数,将BookmarkBarView设置为other_bookmarked_button_的ContextMenuController。在点击右键时,调用BookmarkBarView::ShowContextMenuForView函数,该函数创建BookmarkContextMenu对象。

BookmarkContextMenu对象包含BookmarkContextMenuController类,这个类负责菜单命令管理和菜单命令的执行,在BuildMenu函数中会生成菜单的命令。

BookmarkContextMenu根据BookmarkContextMenuController中的菜单命令生成菜单视图menu_。

BookmarkContextMenu继承MenuDelegate类,当点击右键菜单时,执行BookmarkContextMenu::ExecuteCommand函数,进而调用BookmarkContextMenuController::ExecuteCommand函数执行相应的命令。

在右键菜单中对书签进行操作,比如删除操作,会调用BookmarkContextMenuController::BookmarkModelChanged函数,该函数最终调用BookmarkContextMenu的CloseMenu函数,隐藏菜单。




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值