2014-02-17 65 views
0

這個函數將循環遍歷在中繪製的矩形,正常順序(我實現了畫家的算法)。但是,我將事件處理循環變爲顛倒的順序,所以最後繪製的矩形將成爲事件處理的優先級。如果其中一個矩形已被鼠標懸停,請打破該循環,然後將其他rectangle.hovering屬性重置爲false,但當前正在懸停的矩形除外。我在這裏看到了代碼的重複,所以我想將它轉換成遞歸的,以使其更具靈活性。在這裏,我提出了可怕的,有限而且不靈活的代碼,但它仍然在運行將這個可怕但功能正常的代碼轉換爲遞歸函數

void swcApplication::overrideOnMouseMove(int x, int y) 
{ 
    static swcWidget *prev_widget = nullptr; 

    auto i = controls.getWidgets().size(); 

    while (i) 
    { 

     auto &widget = controls.getWidgets()[--i]; 

     if (!widget->enable) continue; 

     auto j = widget->components.size(); 

     while (j) 
     { 

      auto &widget_component1 = widget->components[--j]; 

      if (!widget_component1->enable) continue; 

      auto k = widget_component1->components.size(); 

      while (k) 
      { 

       auto &widget_component2 = widget_component1->components[--k]; 

       if (!widget_component2->enable) continue; 

       widget_component2->hovering = widget_component2->contains(x, y); 

       widget_component2->efOnMouseMove(x, y); 

       if (widget_component2->hovering) 
       { 

        if (prev_widget != nullptr && 
         prev_widget != widget_component2) 
        { 
         prev_widget->hovering = false; 

         prev_widget->efOnMouseMove(x, y); 
        } 

        prev_widget = widget_component2; 

        widget_component1->hovering = false; 

        break; 
       } 
      } 

      widget_component1->hovering = widget_component1->contains(x, y); 

      widget_component1->efOnMouseMove(x, y); 

      if (widget_component1->hovering) 
      { 

       if (prev_widget != nullptr && 
        prev_widget != widget_component1) 
       { 
        prev_widget->hovering = false; 

        prev_widget->efOnMouseMove(x, y); 
       } 

       prev_widget = widget_component1; 

       widget->hovering = false; 

       break; 
      } 
     } 

     widget->hovering = widget->contains(x, y); 

     widget->efOnMouseMove(x, y); 

     if (widget->hovering) 
     { 
      if (prev_widget != nullptr && 
       prev_widget != widget) 
      { 
       prev_widget->hovering = false; 

       prev_widget->efOnMouseMove(x, y); 
      } 

      prev_widget = widget; 

      break; 
     } 
    } 
} 

我試圖讓我自己遞歸函數來做到這一點,但只有當我開始畫的最後矩形徘徊工作。如果我開始從徘徊在第一個長方形畫,它變得越來越多,我不知道什麼順序(的事件)和條件我應該模仿迭代。

這裏是遞歸函數調用

//post-order traversal 
void swcApplication::recursiveOnMouseMove(swcWidget *next, int x, int y) 
{ 
    if (!next->enable) return; 

    static swcWidget *prev_widget = nullptr; 

    auto i = next->components.size(); 

    while (i) 
    { 
     auto &next_component = next->components[--i]; 

     recursiveOnMouseMove(next_component, x, y); 
    } 


    if (prev_widget != nullptr && 
     prev_widget != next && 
     prev_widget->hovering) 
    { 
     prev_widget->hovering = false; 

     prev_widget->efOnMouseMove(x, y); 

     prev_widget = next; 

     return; 
    } 

    next->hovering = next->contains(x, y); 

    next->efOnMouseMove(x, y); 

    prev_widget = next; 
} 


//Here is the big loop 
//prioritize first all rectangle.components w/c are another rectangle also (...so on and so forth) 
while (i) 
{ 
    auto &widget = controls.getWidgets()[--i]; 

    recursiveOnMouseMove(widget, x, y); 
} 

BTW代碼:我正在通過OpenGL的

+0

關於'靜態swcWidget * prev_widget1 = nullptr;'和其他類似的線,'static',使用靜態的' '可能是不必要的,甚至在多線程上調用方法時可能會導致問題。 –

+0

@MarkGarcia我用它來保留前一個「矩形」的繪製軌跡,我不知道有其他解決方案來跟蹤其他軌跡。 (嘿,記得我嗎?哈哈) – mr5

+0

我只想說,如果你可以讓他們成爲班級成員,那麼最好讓他們成爲班級成員,這樣做比較容易識別,比靜態隱藏在其他代碼下面。使它們成爲類成員也更有意義,因爲它表達了對象的狀態,而不是函數的狀態。 (*和是的,我記得你':)'*) –

回答

0

經過模擬試驗和錯誤的小時圖形用戶界面,我就又找出我的問題! HAHA

這正是我要尋找正確的解決方案:

我做什麼我做了一個全球*ptr並將其設置爲nullptr

swcWidget *prev = nullptr; 

然後我走過它post-order像這樣

void swcApplication::recursiveOnMouseMove(swcWidget *next, int x, int y) 
{ 
    if (!next->enable) return; 

    //self explanatory 
    if (prev != nullptr && prev != next) 
    { 
     next->hovering = false; 

     //perform visitation and tell them a bad news 
     next->efOnMouseMove(x, y); 

     return; 
    } 

    auto i = next->components.size(); 

    while (i) 
    { 
     auto &next_component = next->components[--i]; 

     recursiveOnMouseMove(next_component, x, y); 
    } 

    next->hovering = next->contains(x, y); 

    //perform visitation 
    next->efOnMouseMove(x, y); 

    //Then I made a track for the very first rectangle to be hovered! 
    if (next->hovering) 
     prev_widget = next; 
} 

然後在最外圈

我所做的這是什麼

void swcApplication::overrideOnMouseMove(int x, int y) 
{ 

    auto i = controls.getWidgets().size(); 

    //for every widget, do postorder traversal 
    while (i) 
    { 
     auto &widget = controls.getWidgets()[--i]; 

     recursiveOnMouseMove(widget, x, y); 
    } 

    //re-assign it to `nullptr` 
    prev = nullptr; 
} 

希望有人可以通過這個幫助:d