Browse Source

Refactor and minor improvement on ListView class.

Handle arrow keys to modify selections even when there is no selection yet initially.
Yao Wei Tjong 姚伟忠 12 years ago
parent
commit
fcb2f52035
2 changed files with 23 additions and 25 deletions
  1. 23 23
      Source/Engine/UI/ListView.cpp
  2. 0 2
      Source/Engine/UI/ListView.h

+ 23 - 23
Source/Engine/UI/ListView.cpp

@@ -207,14 +207,15 @@ void ListView::OnKey(int key, int buttons, int qualifiers)
     bool additive = multiselect_ && qualifiers & (QUAL_SHIFT | QUAL_CTRL);
     bool additive = multiselect_ && qualifiers & (QUAL_SHIFT | QUAL_CTRL);
     int delta = 0;
     int delta = 0;
     int pageDirection = 1;
     int pageDirection = 1;
+    bool acceptZeroDelta = false;
 
 
-    if (selection != M_MAX_UNSIGNED && numItems)
+    if (numItems)
     {
     {
         switch (key)
         switch (key)
         {
         {
         case KEY_LEFT:
         case KEY_LEFT:
         case KEY_RIGHT:
         case KEY_RIGHT:
-            if (hierarchyMode_)
+            if (selection != M_MAX_UNSIGNED && hierarchyMode_)
             {
             {
                 Expand(selection, key == KEY_RIGHT);
                 Expand(selection, key == KEY_RIGHT);
                 return;
                 return;
@@ -224,7 +225,7 @@ void ListView::OnKey(int key, int buttons, int qualifiers)
         case KEY_RETURN:
         case KEY_RETURN:
         case KEY_RETURN2:
         case KEY_RETURN2:
         case KEY_KP_ENTER:
         case KEY_KP_ENTER:
-            if (hierarchyMode_)
+            if (selection != M_MAX_UNSIGNED && hierarchyMode_)
             {
             {
                 ToggleExpand(selection);
                 ToggleExpand(selection);
                 return;
                 return;
@@ -246,7 +247,9 @@ void ListView::OnKey(int key, int buttons, int qualifiers)
         case KEY_PAGEDOWN:
         case KEY_PAGEDOWN:
             {
             {
                 // Convert page step to pixels and see how many items have to be skipped to reach that many pixels
                 // Convert page step to pixels and see how many items have to be skipped to reach that many pixels
-                int stepPixels = ((int)(pageStep_ * scrollPanel_->GetHeight())) - GetSelectedItem()->GetHeight();
+                if (selection == M_MAX_UNSIGNED)
+                    selection = 0;      // Assume as if first item is selected
+                int stepPixels = ((int)(pageStep_ * scrollPanel_->GetHeight())) - contentElement_->GetChild(selection)->GetHeight();
                 unsigned newSelection = selection;
                 unsigned newSelection = selection;
                 unsigned okSelection = selection;
                 unsigned okSelection = selection;
                 unsigned invisible = 0;
                 unsigned invisible = 0;
@@ -267,6 +270,7 @@ void ListView::OnKey(int key, int buttons, int qualifiers)
                     newSelection += pageDirection;
                     newSelection += pageDirection;
                 }
                 }
                 delta = okSelection - selection - pageDirection * invisible;
                 delta = okSelection - selection - pageDirection * invisible;
+                acceptZeroDelta = true;     // Ensure Page Up and Down are being treated as handled key even though they generate zero delta
             }
             }
             break;
             break;
 
 
@@ -280,7 +284,7 @@ void ListView::OnKey(int key, int buttons, int qualifiers)
         }
         }
     }
     }
 
 
-    if (delta)
+    if (delta || acceptZeroDelta)
     {
     {
         ChangeSelection(delta, additive);
         ChangeSelection(delta, additive);
         return;
         return;
@@ -612,15 +616,21 @@ void ListView::ToggleSelection(unsigned index)
 
 
 void ListView::ChangeSelection(int delta, bool additive)
 void ListView::ChangeSelection(int delta, bool additive)
 {
 {
+    unsigned numItems = GetNumItems();
     if (selections_.Empty())
     if (selections_.Empty())
-        return;
+    {
+        // Select first item if there is no selection yet
+        if (numItems > 0)
+            SetSelection(0);
+        if (abs(delta) == 1)
+            return;
+    }
     if (!multiselect_)
     if (!multiselect_)
         additive = false;
         additive = false;
 
 
     // If going downwards, use the last selection as a base. Otherwise use first
     // If going downwards, use the last selection as a base. Otherwise use first
     unsigned selection = delta > 0 ? selections_.Back() : selections_.Front();
     unsigned selection = delta > 0 ? selections_.Back() : selections_.Front();
     int direction = delta > 0 ? 1 : -1;
     int direction = delta > 0 ? 1 : -1;
-    unsigned numItems = GetNumItems();
     unsigned newSelection = selection;
     unsigned newSelection = selection;
     unsigned okSelection = selection;
     unsigned okSelection = selection;
     PODVector<unsigned> indices = selections_;
     PODVector<unsigned> indices = selections_;
@@ -708,16 +718,8 @@ void ListView::SetClearSelectionOnDefocus(bool enable)
     if (enable != clearSelectionOnDefocus_)
     if (enable != clearSelectionOnDefocus_)
     {
     {
         clearSelectionOnDefocus_ = enable;
         clearSelectionOnDefocus_ = enable;
-
-        if (clearSelectionOnDefocus_)
-        {
-            SubscribeToEvent(this, E_DEFOCUSED, HANDLER(ListView, HandleClearSelectionOnDefocused));
-
-            if (!HasFocus())
-                ClearSelection();
-        }
-        else
-            SubscribeToEvent(this, E_DEFOCUSED, HANDLER(ListView, HandleFocusChanged));
+        if (clearSelectionOnDefocus_ && !HasFocus())
+            ClearSelection();
     }
     }
 }
 }
 
 
@@ -1077,15 +1079,13 @@ void ListView::HandleItemFocusChanged(StringHash eventType, VariantMap& eventDat
     }
     }
 }
 }
 
 
-void ListView::HandleClearSelectionOnDefocused(StringHash eventType, VariantMap& eventData)
-{
-    ClearSelection();
-}
-
 void ListView::HandleFocusChanged(StringHash eventType, VariantMap& eventData)
 void ListView::HandleFocusChanged(StringHash eventType, VariantMap& eventData)
 {
 {
     scrollPanel_->SetSelected(eventType == E_FOCUSED);
     scrollPanel_->SetSelected(eventType == E_FOCUSED);
-    UpdateSelectionEffect();
+    if (clearSelectionOnDefocus_ && eventType == E_DEFOCUSED)
+        ClearSelection();
+    else if (highlightMode_ == HM_FOCUS)
+        UpdateSelectionEffect();
 }
 }
 
 
 }
 }

+ 0 - 2
Source/Engine/UI/ListView.h

@@ -163,8 +163,6 @@ private:
     void HandleUIMouseDoubleClick(StringHash eventType, VariantMap& eventData);
     void HandleUIMouseDoubleClick(StringHash eventType, VariantMap& eventData);
     /// Handle global focus change to check whether an invisible item was focused.
     /// Handle global focus change to check whether an invisible item was focused.
     void HandleItemFocusChanged(StringHash eventType, VariantMap& eventData);
     void HandleItemFocusChanged(StringHash eventType, VariantMap& eventData);
-    /// Handle being defocused.
-    void HandleClearSelectionOnDefocused(StringHash eventType, VariantMap& eventData);
     /// Handle focus changed.
     /// Handle focus changed.
     void HandleFocusChanged(StringHash eventType, VariantMap& eventData);
     void HandleFocusChanged(StringHash eventType, VariantMap& eventData);
 };
 };