Browse Source

For dropdown and sliders:
1. propagate disabled and focus state (pseudo-class) to child elements.
2. when element has focus, allow arrow keys to move slider and select next/prev options from dropdown.

Frank Becker 14 years ago
parent
commit
b3f94f3752
2 changed files with 100 additions and 2 deletions
  1. 49 2
      Source/Controls/WidgetDropDown.cpp
  2. 51 0
      Source/Controls/WidgetSlider.cpp

+ 49 - 2
Source/Controls/WidgetDropDown.cpp

@@ -30,6 +30,7 @@
 #include <Rocket/Core/Factory.h>
 #include <Rocket/Core/ElementUtilities.h>
 #include <Rocket/Core/Event.h>
+#include <Rocket/Core/Input.h>
 #include <Rocket/Core/Property.h>
 #include <Rocket/Core/StyleSheetKeywords.h>
 #include <Rocket/Controls/ElementFormControl.h>
@@ -59,6 +60,8 @@ WidgetDropDown::WidgetDropDown(ElementFormControl* element)
 
 	parent_element->AddEventListener("click", this, true);
 	parent_element->AddEventListener("blur", this);
+	parent_element->AddEventListener("focus", this);
+	parent_element->AddEventListener("keydown", this, true);
 
 	// Add the elements to our parent element.
 	parent_element->AppendChild(button_element, false);
@@ -72,6 +75,8 @@ WidgetDropDown::~WidgetDropDown()
 
 	parent_element->RemoveEventListener("click", this, true);
 	parent_element->RemoveEventListener("blur", this);
+	parent_element->RemoveEventListener("focus", this);
+	parent_element->RemoveEventListener("keydown", this, true);
 
 	button_element->RemoveReference();
 	selection_element->RemoveReference();
@@ -104,6 +109,13 @@ void WidgetDropDown::OnRender()
 
 void WidgetDropDown::OnLayout()
 {
+	if(parent_element->IsDisabled())
+	{
+		// Propagate disabled state to selectvalue and selectarrow
+		value_element->SetPseudoClass("disabled", true);
+		button_element->SetPseudoClass("disabled", true);
+	}
+
 	// Layout the button and selection boxes.
 	Core::Box parent_box = parent_element->GetBox();
 
@@ -265,9 +277,11 @@ int WidgetDropDown::GetNumOptions() const
 
 void WidgetDropDown::ProcessEvent(Core::Event& event)
 {
+	if (parent_element->IsDisabled()) 
+		return;
+
 	// Process the button onclick
-	if (event == "click" &&
-		!parent_element->IsDisabled())
+	if (event == "click")
 	{
 
 		if (event.GetCurrentElement()->GetParentNode() == selection_element)
@@ -309,7 +323,40 @@ void WidgetDropDown::ProcessEvent(Core::Event& event)
 		}		
 	}
 	else if (event == "blur" && event.GetTargetElement() == parent_element)
+	{
 		ShowSelectBox(false);
+	}
+	else if (event == "keydown")
+	{
+		Core::Input::KeyIdentifier key_identifier = (Core::Input::KeyIdentifier) event.GetParameter< int >("key_identifier", 0);
+
+		switch (key_identifier)
+		{
+			case Core::Input::KI_UP:
+				SetSelection( (selected_option - 1 + options.size()) % options.size() );
+				break;
+			case Core::Input::KI_DOWN:		
+				SetSelection( (selected_option + 1) % options.size() );
+				break;
+			default:
+				break;
+		}
+	}
+
+	if (event.GetTargetElement() == parent_element)
+	{
+		if (event == "focus")
+		{
+			value_element->SetPseudoClass("focus", true);
+			button_element->SetPseudoClass("focus", true);
+		}
+		else if (event == "blur")
+		{
+			value_element->SetPseudoClass("focus", false);
+			button_element->SetPseudoClass("focus", false);
+		}
+	}
+
 }
 
 // Shows or hides the selection box.

+ 51 - 0
Source/Controls/WidgetSlider.cpp

@@ -62,6 +62,10 @@ WidgetSlider::~WidgetSlider()
 		parent->RemoveChild(bar);
 	}
 
+	parent->RemoveEventListener("blur", this);
+	parent->RemoveEventListener("focus", this);
+	parent->RemoveEventListener("keydown", this, true);
+
 	if (track != NULL)
 	{
 		track->RemoveEventListener("click", this);
@@ -128,6 +132,9 @@ bool WidgetSlider::Initialise()
 	bar->AddEventListener("drag", this);
 	bar->AddEventListener("dragstart", this);
 
+	parent->AddEventListener("blur", this);
+	parent->AddEventListener("focus", this);
+	parent->AddEventListener("keydown", this, true);
 	track->AddEventListener("click", this);
 
 	for (int i = 0; i < 2; i++)
@@ -283,6 +290,15 @@ void WidgetSlider::FormatElements(const Rocket::Core::Vector2f& containing_block
 	}
 
 	FormatBar(bar_length);
+
+	if (parent->IsDisabled())
+	{
+	    // Propagate disabled state to child elements
+	    bar->SetPseudoClass("disabled", true);
+	    track->SetPseudoClass("disabled", true);
+	    arrows[0]->SetPseudoClass("disabled", true);
+	    arrows[1]->SetPseudoClass("disabled", true);
+	}
 }
 
 // Lays out and positions the bar element.
@@ -447,6 +463,41 @@ void WidgetSlider::ProcessEvent(Core::Event& event)
 		else if (event.GetTargetElement() == arrows[1])
 			arrow_timers[1] = -1;
 	}
+	else if (event == "keydown")
+	{
+		Core::Input::KeyIdentifier key_identifier = (Core::Input::KeyIdentifier) event.GetParameter< int >("key_identifier", 0);
+
+		switch (key_identifier)
+		{
+			case Core::Input::KI_LEFT:
+				if (orientation == HORIZONTAL) SetBarPosition(OnLineDecrement());
+				break;
+			case Core::Input::KI_UP:
+				if (orientation == VERTICAL) SetBarPosition(OnLineDecrement());
+				break;
+			case Core::Input::KI_RIGHT:
+				if (orientation == HORIZONTAL) SetBarPosition(OnLineIncrement());
+				break;
+			case Core::Input::KI_DOWN:		
+				if (orientation == VERTICAL) SetBarPosition(OnLineIncrement());
+				break;
+			default:
+				break;
+		}
+	}
+
+
+	if (event.GetTargetElement() == parent)
+	{
+		if (event == "focus")
+		{
+			bar->SetPseudoClass("focus", true);
+		}
+		else if (event == "blur")
+		{
+			bar->SetPseudoClass("focus", false);
+		}
+	}
 }
 
 void WidgetSlider::PositionBar()