日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

chrome ui源码剖析-Accelerator(快捷键)

發(fā)布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 chrome ui源码剖析-Accelerator(快捷键) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

好久沒有自己寫東西了,chrome有著取之不盡的技術精華供學習,記錄一下.

源碼目錄:

http://src.chromium.org/viewvc/chrome/trunk/src/ui/base/accelerators/

一.Accelerator 類

// This class describe a keyboard accelerator (or keyboard shortcut). // Keyboard accelerators are registered with the FocusManager. // It has a copy constructor and assignment operator so that it can be copied. // It also defines the < operator so that it can be used as a key in a std::map. //#ifndef UI_BASE_ACCELERATORS_ACCELERATOR_H_ #define UI_BASE_ACCELERATORS_ACCELERATOR_H_ namespace ui {class PlatformAccelerator;// This is a cross-platform class for accelerator keys used in menus. // |platform_accelerator| should be used to store platform specific data. class UI_EXPORT Accelerator {public:Accelerator();Accelerator(ui::KeyboardCode keycode, int modifiers);Accelerator(const Accelerator& accelerator);~Accelerator(); ui::KeyboardCode key_code() const { return key_code_; }// Sets the event type if the accelerator should be processed on an event// other than ui::ET_KEY_PRESSED.void set_type(ui::EventType type) { type_ = type; }ui::EventType type() const { return type_; }int modifiers() const { return modifiers_; }bool IsShiftDown() const;bool IsCtrlDown() const;bool IsAltDown() const;bool IsCmdDown() const;protected:// The keycode (VK_...).KeyboardCode key_code_;// The event type (usually ui::ET_KEY_PRESSED).EventType type_;// The state of the Shift/Ctrl/Alt keys.int modifiers_;// Stores platform specific data. May be NULL.scoped_ptr<PlatformAccelerator> platform_accelerator_; };

定義了快捷鍵屬性

主要有三個屬性

  • key_code_:按下的鍵盤鍵
  • type_:觸發(fā)的事件,比如keydown,keyup
  • modifiers_:特殊組合按鈕
  • 二.AcceleratorTarget

    ?

    // An interface that classes that want to register for keyboard accelerators // should implement. class UI_EXPORT AcceleratorTarget {public:// Should return true if the accelerator was processed.virtual bool AcceleratorPressed(const Accelerator& accelerator) = 0;// Should return true if the target can handle the accelerator events. The// AcceleratorPressed method is invoked only for targets for which// CanHandleAccelerators returns true.virtual bool CanHandleAccelerators() const = 0;protected:virtual ~AcceleratorTarget() {} };

    注冊快捷鍵的對象,

  • AcceleratorPressed方法為處理快捷鍵事件,返回true則表明處理完畢
  • CanHandleAccelerators方法是處理快捷鍵之前的狀態(tài)檢查
  • 三.AcceleratorManager

    #ifndef UI_BASE_ACCELERATORS_ACCELERATOR_MANAGER_H_ #define UI_BASE_ACCELERATORS_ACCELERATOR_MANAGER_H_#include <list> #include <map> #include <utility> namespace ui {// The AcceleratorManger is used to handle keyboard accelerators. class UI_EXPORT AcceleratorManager {public:enum HandlerPriority {kNormalPriority,kHighPriority,};AcceleratorManager();~AcceleratorManager();// Register a keyboard accelerator for the specified target. If multiple// targets are registered for an accelerator, a target registered later has// higher priority.// |accelerator| is the accelerator to register.// |priority| denotes the priority of the handler.// NOTE: In almost all cases, you should specify kNormalPriority for this// parameter. Setting it to kHighPriority prevents Chrome from sending the// shortcut to the webpage if the renderer has focus, which is not desirable// except for very isolated cases.// |target| is the AcceleratorTarget that handles the event once the// accelerator is pressed.// Note that we are currently limited to accelerators that are either:// - a key combination including Ctrl or Alt// - the escape key// - the enter key// - any F key (F1, F2, F3 ...)// - any browser specific keys (as available on special keyboards)void Register(const Accelerator& accelerator,HandlerPriority priority,AcceleratorTarget* target);// Unregister the specified keyboard accelerator for the specified target.void Unregister(const Accelerator& accelerator, AcceleratorTarget* target);// Unregister all keyboard accelerator for the specified target.void UnregisterAll(AcceleratorTarget* target);// Activate the target associated with the specified accelerator.// First, AcceleratorPressed handler of the most recently registered target// is called, and if that handler processes the event (i.e. returns true),// this method immediately returns. If not, we do the same thing on the next// target, and so on.// Returns true if an accelerator was activated.bool Process(const Accelerator& accelerator);// Returns the AcceleratorTarget that should be activated for the specified// keyboard accelerator, or NULL if no view is registered for that keyboard// accelerator.AcceleratorTarget* GetCurrentTarget(const Accelerator& accelertor) const;// Whether the given |accelerator| has a priority handler associated with it.bool HasPriorityHandler(const Accelerator& accelerator) const;private:// The accelerators and associated targets.typedef std::list<AcceleratorTarget*> AcceleratorTargetList;// This construct pairs together a |bool| (denoting whether the list contains// a priority_handler at the front) with the list of AcceleratorTargets.typedef std::pair<bool, AcceleratorTargetList> AcceleratorTargets;typedef std::map<Accelerator, AcceleratorTargets> AcceleratorMap;AcceleratorMap accelerators_;DISALLOW_COPY_AND_ASSIGN(AcceleratorManager); };} // namespace ui#endif // UI_BASE_ACCELERATORS_ACCELERATOR_MANAGER_H_

    數(shù)據(jù)結構為一個Accelerator對應一個AcceleratorTargets列表,bool用來表示優(yōu)先級

    Process方法用來處理快捷鍵流程

    bool AcceleratorManager::Process(const Accelerator& accelerator) {bool result = false;AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);if (map_iter != accelerators_.end()) {// We have to copy the target list here, because an AcceleratorPressed// event handler may modify the list.AcceleratorTargetList targets(map_iter->second.second);for (AcceleratorTargetList::iterator iter = targets.begin();iter != targets.end(); ++iter) {if ((*iter)->CanHandleAccelerators() &&(*iter)->AcceleratorPressed(accelerator)) {result = true;break;}}}return result; }

    再來看下Register方法,新注冊的快捷鍵都排到前面來了,這個是比較關鍵的

    void AcceleratorManager::Register(const Accelerator& accelerator,HandlerPriority priority,AcceleratorTarget* target) {AcceleratorTargetList& targets = accelerators_[accelerator].second;DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end())<< "Registering the same target multiple times";// All priority accelerators go to the front of the line.if (priority) {DCHECK(!accelerators_[accelerator].first)<< "Only one _priority_ handler can be registered";targets.push_front(target);// Mark that we have a priority accelerator at the front.accelerators_[accelerator].first = true;return;}// We are registering a normal priority handler. If no priority accelerator// handler has been registered before us, just add the new handler to the// front. Otherwise, register it after the first (only) priority handler.if (!accelerators_[accelerator].first)targets.push_front(target);elsetargets.insert(++targets.begin(), target); }

    測試代碼:

    1.注冊一個快捷鍵

    TEST_F(AcceleratorManagerTest, Register) {const Accelerator accelerator_a(VKEY_A, EF_NONE);TestTarget target;manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,&target);// The registered accelerator is processed.EXPECT_TRUE(manager_.Process(accelerator_a));EXPECT_EQ(1, target.accelerator_pressed_count()); }

    2.注冊多個快捷鍵

    TEST_F(AcceleratorManagerTest, RegisterMultipleTarget) {const Accelerator accelerator_a(VKEY_A, EF_NONE);TestTarget target1;manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,&target1);TestTarget target2;manager_.Register(accelerator_a, AcceleratorManager::kNormalPriority,&target2);// If multiple targets are registered with the same accelerator, the target// registered later processes the accelerator.EXPECT_TRUE(manager_.Process(accelerator_a));EXPECT_EQ(0, target1.accelerator_pressed_count());EXPECT_EQ(1, target2.accelerator_pressed_count()); }

    ?

    簡單的用以上關系來表達三者之間的關系,其實邏輯還是比較清晰的,使用map查找起來速度也比較快,不會存在什么性能上面的問題,Register方法都是push_front也保證了時效性,所以其還是滿足了快捷鍵使用的需求,非常輕巧

    總結

    以上是生活随笔為你收集整理的chrome ui源码剖析-Accelerator(快捷键)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。