• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Cpper
            C/C++高級(jí)工程師 Android高級(jí)軟件工程師 IT集成工程師 音頻工程師 熟悉c,c++,java,c#,py,js,asp等多種語(yǔ)言 程序猿
            接上文:http://m.shnenglu.com/gaimor/archive/2010/09/30/128134.html
            本文我們接著說(shuō)UI庫(kù)的消息事件部分:
            1.UI基本事件類(lèi)型
              基本上就下面幾種:
            ////////////////////////////////////////////////////////////
            /// 枚舉UI消息類(lèi)型
            ////////////////////////////////////////////////////////////
            enum UI_EVENT
            {
                
            //! 鼠標(biāo)移動(dòng)
                UI_EVENT_MOUSE_MOVE = 0,
                
            //! 鼠標(biāo)點(diǎn)擊
                UI_EVENT_MOUSE_CLICK,
                
            //! 鼠標(biāo)進(jìn)入
                UI_EVENT_MOUSE_ENTERED,
                
            //! 鼠標(biāo)退出
                UI_EVENT_MOUSE_EXITED,
                
            //! 鼠標(biāo)滾輪事件
                UI_EVENT_MOUSE_WHEEL,
                
            //! 字符輸入
                UI_EVENT_CHAR_INPUT,
                
            //! 鍵盤(pán)按鍵
                UI_EVENT_KEY_PRESS,
                
            //! 按鍵退出
                UI_EVENT_KEY_RELEASE,
                
            //! 焦點(diǎn)事件
                UI_EVENT_LOST_FOCUSE,
                UI_EVENT_GAIN_FOCUSE,
                
            //! 滑塊事件
                UI_EVENT_SLIDER_MOVE,
                
            //! 編輯事件
                UI_EVENT_EDIT,
                
            //! 選擇,反選擇
                UI_EVENT_SELECTED,
                UI_EVENT_DESELECTED
            };
            2.
            關(guān)于事件一般就3個(gè)相關(guān)對(duì)象:
            事件,消息聽(tīng)者和消息處理對(duì)象3個(gè)單元塊:
            如下所示:

            ///////////////////////////////////////////////////////////
            /// 定義引擎事件基類(lèi)模板
            ///////////////////////////////////////////////////////////
            template<class EventType = int>
            class Event : NonCopyable
            {
            public:
                
            ///////////////////////////////////////////////////////
                
            /// 事件基類(lèi)構(gòu)造函數(shù)
                
            ///////////////////////////////////////////////////////
                Event(const EventType& type):type_(type){}

                
            ////////////////////////////////////////////////////////
                
            /// 事件基類(lèi)析構(gòu)函數(shù)
                
            ////////////////////////////////////////////////////////
                virtual ~Event(){}

                
            ////////////////////////////////////////////////////////
                
            /// 獲取事件類(lèi)型
                
            ////////////////////////////////////////////////////////
                EventType GetEventType()const{return type_;}
            private:
                
            ////////////////////////////////////////////////////////
                
            /// 數(shù)據(jù)成員變量
                
            ////////////////////////////////////////////////////////
                EventType type_;
            };

            ////////////////////////////////////////////////////////////
            /// 定義事件聽(tīng)者基類(lèi)
            ////////////////////////////////////////////////////////////
            template<class Event,class Target>
            class EventListener
            {
            public:
                
            ////////////////////////////////////////////////////////
                
            /// 事件聽(tīng)者虛析構(gòu)函數(shù)
                
            ////////////////////////////////////////////////////////
                virtual ~EventListener(){}

                
            ////////////////////////////////////////////////////////
                
            /// 消息派送
                
            ////////////////////////////////////////////////////////
                virtual bool Dispatch(const Event& message,Target object= 0;
            };

            ////////////////////////////////////////////////////////////
            /// 定義事件處理者基類(lèi)
            ////////////////////////////////////////////////////////////
            template<class Event,class EventListener>
            class EventHandler
            {
            public:
                
            ////////////////////////////////////////////////////////
                
            /// 事件聽(tīng)者虛析構(gòu)函數(shù)
                
            ////////////////////////////////////////////////////////
                virtual ~EventHandler(){}

                
            ////////////////////////////////////////////////////////
                
            /// 消息處理
                
            ////////////////////////////////////////////////////////
                virtual bool Process(const Event& message){return false;}

                
            ////////////////////////////////////////////////////////
                
            /// 增加,移除事件消息
                
            ////////////////////////////////////////////////////////
                virtual void AddEventListener(EventListener* listener){}
                
            virtual void RemoveEventListener(EventListener* listener){}
            };
            然后便是模板實(shí)例:
            typedef Event<UI_EVENT>                          UI_Event;
            typedef EventListener<UI_Event,UI_Widget*>       UI_EventListener;
            typedef EventHandler<UI_Event,UI_EventListener*> UI_EventHandler;
            說(shuō)實(shí)話(huà)可以不這樣做而是用boost::function之類(lèi)的函數(shù)綁定
            但是沒(méi)法子這樣寫(xiě)我習(xí)慣了 呵呵
            2.下面是UI事件的承接部分:
            通過(guò)UI管理器承接輸入輸出系統(tǒng)的消息響應(yīng):
            {
            ////////////////////////////////////////////////////////////
            /// 蓋莫GUI管理器
            ////////////////////////////////////////////////////////////
            class GAPI UI_WidgetManager : public UI_EventListenerImpl
            public:
                
            ////////////////////////////////////////////////////////
                
            /// 按鍵處理
                
            ////////////////////////////////////////////////////////
                bool OnMouseLeftDown(int x,int y);
                
            bool OnMouseLeftUp(int x,int y);
                
            bool OnMouseMiddleDown(int x,int y);
                
            bool OnMouseMiddleUp(int x,int y);
                
            bool OnMouseRightDown(int x,int y);
                
            bool OnMouseRightUp(int x,int y);
                
            bool OnMouseMove(int x,int y);
                
            bool OnChar(wchar_t code);
                
            bool OnKeyDown(int code);
                
            bool OnKeyUp(int code);
                
            bool OnMouseWheel(int z);
            public:
            3.事件生成:
            以上2部分分別是UI事件對(duì)象系列和UI事件輸入部分
            下面設(shè)計(jì)UI事件的生成
            無(wú)論是鼠標(biāo)還是鍵盤(pán)事件實(shí)際上都相當(dāng)于生成了一個(gè)新的事件
            舉例如下:
            OnMouseLeftDown(int x,int y)
            如果該函數(shù)被調(diào)用
            那么就說(shuō)明鼠標(biāo)的左鍵被點(diǎn)擊同時(shí)我們還知道了點(diǎn)擊的位置坐標(biāo)
            這樣就生成了一個(gè)UI_MouseClickEvent 對(duì)象
            不過(guò)這里需要考慮是鼠標(biāo)雙擊還是單擊
            這就要考慮本次點(diǎn)擊和上次點(diǎn)擊的時(shí)間間隔了
            這樣就生成了一個(gè)UI鼠標(biāo)事件
            那本事件應(yīng)該傳給誰(shuí)?
            應(yīng)該是目標(biāo)對(duì)象
            直觀一點(diǎn)應(yīng)該是傳給鼠標(biāo)當(dāng)前位置下的控件對(duì)象
            但是考慮到實(shí)際情況
            這里有一個(gè)聚焦控件和活動(dòng)控件的概念
            比如說(shuō)我們打開(kāi)一個(gè)對(duì)話(huà)框(這是一個(gè)聚焦控件)
            對(duì)話(huà)框上有1個(gè)按鍵
            當(dāng)用戶(hù)點(diǎn)擊本按鍵則消息發(fā)送給這個(gè)按鍵了
            但是當(dāng)鼠標(biāo)移出對(duì)話(huà)框之外
            一般情況其他控件此時(shí)處于非活動(dòng)狀態(tài)
            消息應(yīng)該發(fā)送給聚焦控件
            所以這里至少有3各類(lèi)型的控件指針?lè)謩e為:聚焦控件,活動(dòng)控件以及鼠標(biāo)下控件(當(dāng)然他們可以是同一控件)
            在這里需要說(shuō)明這三個(gè)控件是這樣切換的
            如果發(fā)生特定的uI事件則修改當(dāng)前的聚焦控件等對(duì)象了
            4.具體控件對(duì)消息的處理:
               生成特定消息,并發(fā)送給相應(yīng)的控件對(duì)象之后那么控件就需要相應(yīng)該消息了:
            控件對(duì)象的相關(guān)函數(shù):
            ///////////////////////////////////////////////////////////
            /// 定義UI控件基類(lèi)
            ///////////////////////////////////////////////////////////
            class GAPI UI_Widget : public SlotHolder,public UI_EventHandler,public Object
            {
            public:
                typedef std::list
            <UI_EventListener*> UIEventListener;
                typedef std::list
            <UI_EventListener*>::iterator UIEventListenerItr;
                
            void RemoveEventListener(UI_EventListener* listener);
                
            ////////////////////////////////////////////////////////
                
            /// 消息處理
                
            ////////////////////////////////////////////////////////
                virtual bool Process(const UI_Event& event)
            在這里我們通過(guò)Process函數(shù)來(lái)接受UI管理器傳過(guò)來(lái)的消息對(duì)象.
            這里是想要的處理
            注意我們并不直接根據(jù)消息響應(yīng)控件的各種狀態(tài)!
            而是通過(guò)迭代消息聽(tīng)者鏈表的
            如下:
            bool UI_Widget::Process(const UI_Event& event)
            {
                
            bool ret = false;
                
            if(IsVisible() && IsEnabled())
                {
                    UIEventListenerItr it;
                    
            for(it = message_listeners_.begin();it != message_listeners_.end();++it)
                    {
                        UI_EventListener
            * listener = *it;
                        ret 
            = ret || listener->Dispatch(event,this);
                    }
                    
            //! 處理控件邊框事件
                    if(border_)
                        border_
            ->Process(event);
                }
                
            return ret;
            }
            當(dāng)消息傳來(lái)之后我們并不能確定這就是本控件所需要的消息需要驗(yàn)證它
            如何驗(yàn)證?
            就看當(dāng)前控件是不是可顯示和活動(dòng)的咯
            同時(shí)如何控件有邊框?qū)ο笪覀儎t把消息發(fā)給它以改變可能的邊框外觀

            下篇:UI設(shè)計(jì)概要4:UI控件對(duì)象

            posted on 2010-10-04 16:46 ccsdu2009 閱讀(1863) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Game引擎
             
            一本久久综合亚洲鲁鲁五月天| 国产成人久久精品麻豆一区| 久久SE精品一区二区| 理论片午午伦夜理片久久 | 国内精品伊人久久久久AV影院| 国产麻豆精品久久一二三| 国产69精品久久久久9999| 久久亚洲精品国产亚洲老地址 | 伊人久久大香线蕉亚洲五月天| 久久精品无码一区二区无码| 久久香蕉国产线看观看乱码| 日韩欧美亚洲国产精品字幕久久久 | 久久综合亚洲鲁鲁五月天| 国产欧美久久一区二区| 久久精品无码免费不卡| 国产V亚洲V天堂无码久久久| 婷婷综合久久狠狠色99h| 久久久亚洲裙底偷窥综合| 国产精品对白刺激久久久| 国内精品久久久久影院老司| 青青草国产精品久久| 久久久久亚洲AV无码网站| 久久久无码精品亚洲日韩京东传媒 | 国产91久久精品一区二区| 思思久久99热免费精品6| 成人a毛片久久免费播放| 国产精品99久久免费观看| 波多野结衣久久一区二区| 久久久久无码专区亚洲av| 久久99国产亚洲高清观看首页| 午夜天堂av天堂久久久| 一级女性全黄久久生活片免费| 亚洲欧美日韩精品久久| 一本色道久久88加勒比—综合| 久久久久亚洲av无码专区| 麻豆AV一区二区三区久久| 狠狠色婷婷久久综合频道日韩| 色老头网站久久网| 一本色道久久HEZYO无码| 囯产极品美女高潮无套久久久| 国产69精品久久久久9999APGF|