/** * @brief * Update mouse-over widget */ void Gui::UpdateMouseOverWidget() { // Has the mouse-over widget changed? if (m_pMouseOverWidget != m_pMouseOverWidgetNew) { // Get old mouse-over widget Widget *m_pMouseOverWidgetOld = m_pMouseOverWidget; // Save new mouse-over widget m_pMouseOverWidget = m_pMouseOverWidgetNew; // Get common parent of old mouse-over widget and the new one Widget *pParent = (m_pMouseOverWidgetOld && m_pMouseOverWidgetNew) ? m_pMouseOverWidgetNew->GetCommonParent(*m_pMouseOverWidgetOld) : nullptr; // Choose where to stop (include parent itself only when necessary) Widget *pStop = pParent; if (m_pMouseOverWidgetOld == pParent || m_pMouseOverWidgetNew == pParent) { pStop = (pParent ? pParent->GetParent() : nullptr); } // Inform old widgets, that they are no longer mouse-over widgets Widget *pWidget = m_pMouseOverWidgetOld; while (pWidget && pWidget != pStop) { // Send mouse-over message SendMessage(GuiMessage::OnMouseOver(pWidget, false)); // Next widget pWidget = pWidget->GetParent(); } // Inform new widgets, that they are now mouse-over widgets pWidget = m_pMouseOverWidgetNew; while (pWidget && pWidget != pStop) { // Send mouse-over message SendMessage(GuiMessage::OnMouseOver(pWidget, true)); // Next widget pWidget = pWidget->GetParent(); } // Start hover timer if (m_pMouseOverWidget) { // Create timer if it has not yet been created if (!m_pHoverTimer && m_nHoverTime > 0) { m_pHoverTimer = new Timer(*this); m_pHoverTimer->EventFire.Connect(EventHandlerOnHoverTimer); } // Start timer if (!m_pHoverTimer->IsActive()) m_pHoverTimer->StartOnce(m_nHoverTime); } } }
BOOL WidDispatch::Destroy( HWID& hWid ) { std::map<HWID, Widget*>::iterator it = m_Handle2Object.find(hWid); if (it == m_Handle2Object.end()) { return FALSE; } Widget* pWid = it->second; WFX_CONDITION(pWid != NULL); Widget* pParent = pWid->GetParent(); if (pParent != NULL) { pParent->RemoveChild(pWid); } m_Handle2Object.erase(it); std::map<HWID, Widget*>::iterator itPaint = m_h2oOrphan.find(hWid); if (itPaint != m_h2oOrphan.end()) { m_h2oOrphan.erase(itPaint); } if (m_h2oCaptured.first == hWid) { ClearH2O(m_h2oCaptured); } m_pTimer->Destroy(pWid); RecycleHwid(hWid); return TRUE; }
/** * @brief * Get top level widget that is parent of this widget */ Widget *Widget::GetTopLevelWidget() const { // Start with this widget Widget *pWidget = const_cast<Widget*>(this); // Find top-level widget in hierarchy while (pWidget && !pWidget->IsTopLevel()) pWidget = pWidget->GetParent(); // Return widget return pWidget; }
/** * @brief * Update focus widget */ void Gui::UpdateFocusWidget() { // Has the focus widget changed? if (m_pFocusWidget != m_pFocusWidgetNew) { // Get old focus widget Widget *m_pFocusWidgetOld = m_pFocusWidget; // Save new focus widget m_pFocusWidget = m_pFocusWidgetNew; // Get common parent of old focus widget and the new one Widget *pParent = (m_pFocusWidgetOld && m_pFocusWidgetNew) ? m_pFocusWidgetNew->GetCommonParent(*m_pFocusWidgetOld) : nullptr; // Choose where to stop (include parent itself only when necessary) Widget *pStop = pParent; if (m_pFocusWidgetOld == pParent || m_pFocusWidgetNew == pParent) { pStop = (pParent ? pParent->GetParent() : nullptr); } // Inform old widgets, that they are no longer activated Widget *pWidget = m_pFocusWidgetOld; while (pWidget && pWidget != pStop) { // Send activate message SendMessage(GuiMessage::OnActivate(pWidget, false)); // Next widget pWidget = pWidget->GetParent(); } // Inform new widgets, that they are now activated pWidget = m_pFocusWidgetNew; while (pWidget && pWidget != pStop) { // Send activate message SendMessage(GuiMessage::OnActivate(pWidget, true)); // Next widget pWidget = pWidget->GetParent(); } } }
/** * @brief * Send and process a message directly */ void Gui::SendMessage(const GuiMessage &cMessage) { // Pass message to message filters for (uint32 i=0; i<m_lstMessageFilters.GetNumOfElements(); i++) { // Pass message to filter m_lstMessageFilters[i]->AddMessage(cMessage); } // Get widget Widget *pWidget = cMessage.GetWidget(); // Process message switch (cMessage.GetType()) { // Exit application case MessageOnExit: // Set flag to leave application m_bActive = false; // Skip passing message to widget return; // Timer fired case MessageOnTimer: { // Get timer Timer *pTimer = cMessage.GetTimer(); // Discard message, if the timer has already been destroyed if (pTimer && m_lstTimers.IsElement(pTimer)) { // Fire timer pTimer->Fire(); } // Skip passing message to widget return; } // Widget has been destroyed case MessageOnDestroy: // Remove from parent widget if (pWidget->GetParent()) { pWidget->GetParent()->RemoveChild(pWidget); } // Remove from list of top-level widgets if (m_lstTopLevelWidgets.IsElement(pWidget)) { m_lstTopLevelWidgets.Remove(pWidget); } // Add widget to list of destroyed widgets m_lstDestroyedWidgets.Add(pWidget); // Pass message on to widget break; // Mouse has entered a widget case MessageOnMouseEnter: // Set new mouse-over widget if (m_pMouseOverWidget != pWidget) { // Update mouse-over widget m_pMouseOverWidgetNew = pWidget; UpdateMouseOverWidget(); } break; // Mouse has left a widget case MessageOnMouseLeave: // Reset mouse-over widget if (m_pMouseOverWidget == pWidget) { // Update mouse-over widget m_pMouseOverWidgetNew = nullptr; UpdateMouseOverWidget(); } break; // Widget has got the focus case MessageOnGetFocus: // Set focus widget if (m_pFocusWidget != pWidget) { // Update focus widget m_pFocusWidgetNew = pWidget; UpdateFocusWidget(); } break; // Widget has lost the focus case MessageOnLooseFocus: // Set focus widget if (m_pFocusWidget == pWidget) { // Update focus widget m_pFocusWidgetNew = nullptr; UpdateFocusWidget(); } break; case MessageOnUnknown: case MessageOnInternalMessage: case MessageOnWakeup: case MessageOnThemeChanged: case MessageOnUpdateContent: case MessageOnUpdateChildWidget: case MessageOnAddChildWidget: case MessageOnRemoveChildWidget: case MessageOnClose: case MessageOnCreate: case MessageOnShow: case MessageOnHide: case MessageOnEnable: case MessageOnDisable: case MessageOnActivate: case MessageOnDrawBackground: case MessageOnDraw: case MessageOnMove: case MessageOnSize: case MessageOnWindowState: case MessageOnEnterFullscreen: case MessageOnLeaveFullscreen: case MessageOnPreferredSize: case MessageOnAdjustContent: case MessageOnMouseOver: case MessageOnMouseMove: case MessageOnMouseHover: case MessageOnMousePosUpdate: case MessageOnMouseButtonDown: case MessageOnMouseButtonUp: case MessageOnMouseButtonClick: case MessageOnMouseButtonDoubleClick: case MessageOnMouseWheel: case MessageOnKeyDown: case MessageOnKeyUp: case MessageOnHotkey: case MessageOnDrop: case MessageOnUserMessage: default: // Nothing to do in here break; } // Pass message to widget if (pWidget) { pWidget->OnMessage(cMessage); } }