From 52bd0792d15e9a814cd38cf77b26784003b8569f Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Sun, 29 Jan 2012 15:16:17 +0000
Subject:

---
 src/client/inventorylistview.cc |  9 +++--
 src/client/savegamemenu.cc      |  1 -
 src/ui/listview.cc              | 77 +++++++++++++++++++++++++++++------------
 src/ui/listview.h               |  3 ++
 src/ui/scrollbar.cc             | 19 +++++-----
 src/ui/slider.cc                | 19 +++++-----
 src/ui/widget.cc                |  1 +
 7 files changed, 83 insertions(+), 46 deletions(-)

diff --git a/src/client/inventorylistview.cc b/src/client/inventorylistview.cc
index 5b1dbde..ed3419d 100644
--- a/src/client/inventorylistview.cc
+++ b/src/client/inventorylistview.cc
@@ -22,15 +22,18 @@ InventoryListView::InventoryListView(ui::Widget *parent) : ui::ListView (parent)
 	listview_infotimestamp = 0;
 	listview_showempty = false;
 	
-	set_inventory(0, 0);
+	listview_timestamp = 0;
+	listview_infotimestamp = 0;
+	listview_inventory = 0;
 }
 
-InventoryListView::~InventoryListView() {
+InventoryListView::~InventoryListView()
+{
 }
 
 void InventoryListView::set_inventory(core::Inventory *inventory, core::InfoType *infotype)
 {
-	remove_children();
+	ListView::clear();
 	
 	deselect();
 	
diff --git a/src/client/savegamemenu.cc b/src/client/savegamemenu.cc
index a0da087..e39d59b 100644
--- a/src/client/savegamemenu.cc
+++ b/src/client/savegamemenu.cc
@@ -284,7 +284,6 @@ void SaveGameMenu::hide()
 void SaveGameMenu::show()
 {
 	Window::show();
-	event_resize();
 	refresh();
 }
 
diff --git a/src/ui/listview.cc b/src/ui/listview.cc
index 99bcd3c..cd87639 100644
--- a/src/ui/listview.cc
+++ b/src/ui/listview.cc
@@ -11,12 +11,16 @@ namespace ui
 
 ListView::ListView(Widget *parent) : Widget(parent)
 {
+	listview_scroll = 0.0f;
+	listview_selecteditem = 0;
+	
 	set_label("listview");
 	set_border(true);
 	set_background(true);
 	
-	listview_scroll = 0.0f;
-	listview_selecteditem = 0;
+	listview_scrollbar = new ScrollBar(this);
+	listview_scrollbar->set_background(false);
+	listview_scrollbar->set_border(false);
 }
 
 ListView::~ListView()
@@ -30,11 +34,11 @@ void ListView::set_scroll(float scroll)
 		listview_scroll = 0;
 	
 	// calculate maximal scroll size
-	float top = 0;
-	for (Children::iterator it = children().begin(); it != children().end(); it++) {		
-		top += (*it)->height();
+	float total_height = 0;
+	for (Children::iterator it = children().begin(); it != children().end(); it++) {
+		total_height += (*it)->height();
 	}
-	if (listview_scroll > top) listview_scroll = top;
+	if (listview_scroll > total_height) listview_scroll = total_height;
 }
 
 void ListView::inc_scroll(float scroll)
@@ -49,24 +53,33 @@ void ListView::dec_scroll(float scroll)
 	
 void ListView::resize()
 {
-	float content_top = 0;
+	listview_scrollbar->set_size(font()->height(), height());
+	listview_scrollbar->set_location(width() - listview_scrollbar->width(), 0);
+	
+	float total_height = 0;
 	
 	// reposition all children within the container
 	for (Children::iterator it = children().begin(); it != children().end(); it++) {
-		(*it)->set_width(width());
-		if (content_top - listview_scroll < 0) {
-			// child widget is invisible
-			(*it)->hide();
-		} else if ((content_top - listview_scroll) >= height()) {
-			// child widget is invisible
-			(*it)->hide();
-		} else {
-			(*it)->show();
-			(*it)->set_location(0, content_top - listview_scroll);
+		if ((*it) != static_cast<Widget *>(listview_scrollbar)) {
+			(*it)->set_width(width() - listview_scrollbar->width());
+			if (total_height - listview_scroll < 0) {
+				// child widget is invisible
+				(*it)->hide();
+			} else if ((total_height - listview_scroll) >= height()) {
+				// child widget is invisible
+				(*it)->hide();
+			} else {
+				(*it)->show();
+				(*it)->set_location(0, total_height - listview_scroll);
+			}
+			
+			total_height += (*it)->height();
 		}
-		
-		content_top += (*it)->height();
 	}
+	
+	listview_scrollbar->set_range(0.0f, total_height);
+	listview_scrollbar->set_value(listview_scroll);
+	
 }
 
 void ListView::deselect()
@@ -85,11 +98,23 @@ void ListView::clear()
 {
 	listview_selecteditem = 0;
 	remove_children();
+	
+	listview_scrollbar = new ScrollBar(this);
+	listview_scrollbar->set_background(false);
+	listview_scrollbar->set_border(false);
+	listview_scrollbar->set_range(0.0f, 0.0f);
 }
 
 bool ListView::on_emit(Widget *sender, const Event event, void *data)
 {
-	if ((sender->parent() == this) && (event == Widget::EventListItemClicked)) {
+	if (sender == listview_scrollbar) {
+		if (event == Widget::EventScrollBarChanged)  {
+			listview_scroll = listview_scrollbar->value();
+			resize();
+		}
+		return true;
+		
+	} else if ((sender->parent() == this) && (event == Widget::EventListItemClicked)) {
 		listview_selecteditem = static_cast<ListItem *>(sender);
 		emit(EventListViewChanged);
 		return true;
@@ -102,7 +127,11 @@ bool compare_listitems(const Widget *first, const Widget *second)
 {
 	const ListItem *firstitem = dynamic_cast<const ListItem *>(first);
 	const ListItem *seconditem = dynamic_cast<const ListItem *>(second);
-	assert(firstitem && seconditem);
+	
+	if (!firstitem)
+		return true;
+	else if (!seconditem)
+		return false;
 	
 	if (firstitem->sortkey() < seconditem->sortkey()) {
 		return true;
@@ -122,7 +151,11 @@ bool compare_listitems_reverse(const Widget *first, const Widget *second)
 {
 	const ListItem *firstitem = dynamic_cast<const ListItem *>(first);
 	const ListItem *seconditem = dynamic_cast<const ListItem *>(second);
-	assert(firstitem && seconditem);
+
+	if (!firstitem)
+		return true;
+	else if (!seconditem)
+		return false;
 	
 	if (firstitem->sortkey() < seconditem->sortkey()) {
 		return false;
diff --git a/src/ui/listview.h b/src/ui/listview.h
index 5a465f9..b097184 100644
--- a/src/ui/listview.h
+++ b/src/ui/listview.h
@@ -16,6 +16,7 @@ class ListView;
 }
 
 #include "ui/listitem.h"
+#include "ui/scrollbar.h"
 
 namespace ui
 {
@@ -81,7 +82,9 @@ protected:
 	
 private:
 	float		listview_scroll;
+	
 	ListItem	*listview_selecteditem;
+	ScrollBar	*listview_scrollbar;
 };
 
 } // namespacd ui
diff --git a/src/ui/scrollbar.cc b/src/ui/scrollbar.cc
index 9be1432..a8826a5 100644
--- a/src/ui/scrollbar.cc
+++ b/src/ui/scrollbar.cc
@@ -160,17 +160,16 @@ void ScrollBar::on_mousemove(const math::Vector2f &cursor)
 	}
 		
 	if (scrollbar_dragging && (scrollbar_maximum > scrollbar_minimum)) {
-		// total width of dragable area	
-		if ((cursor.y() >= 2.0f * width()) && (cursor.y() <= height() - 2.0f * width())) {
+		float y = cursor.y();
+		math::clamp(y, 2.0f * width() , height() - 2.0f * width());
 			
-			const float h = (height() - 4.0f * width());
-			const float s = h / (scrollbar_maximum - scrollbar_minimum);
-			const float p = cursor.y() - 2.0f * width();
-			const float newvalue = scrollbar_minimum + round(p / s);
-			if (scrollbar_value != newvalue) {
-				scrollbar_value = newvalue;
-				emit(EventScrollBarChanged, this);
-			}
+		const float h = (height() - 4.0f * width());
+		const float s = h / (scrollbar_maximum - scrollbar_minimum);
+		const float p = y - 2.0f * width();
+		const float newvalue = scrollbar_minimum + round(p / s);
+		if (scrollbar_value != newvalue) {
+			scrollbar_value = newvalue;
+			emit(EventScrollBarChanged, this);
 		}
 	}
 	
diff --git a/src/ui/slider.cc b/src/ui/slider.cc
index 1fa999b..c1b473c 100644
--- a/src/ui/slider.cc
+++ b/src/ui/slider.cc
@@ -160,16 +160,15 @@ void Slider::on_mousemove(const math::Vector2f &cursor)
 	}
 	
 	if (slider_dragging && (slider_maximum > slider_minimum)) {
-		// total width of dragable area	
-		if ((cursor.x() >= 2.0f * height()) && (cursor.x() <= width() - 2.0f * height())) {
-			const float w = (width() - 4.0f * height());
-			const float s = w / (slider_maximum - slider_minimum);
-			const float p = cursor.x() - 2.0f * height();
-			const float newvalue = slider_minimum + round(p /s);
-			if (slider_value != newvalue) {
-				slider_value = newvalue;
-				emit(EventSliderChanged, this);
-			}
+		float x = cursor.x();
+		math::clamp(x,  2.0f * height(), width() - 2.0f * height());
+		const float w = (width() - 4.0f * height());
+		const float s = w / (slider_maximum - slider_minimum);
+		const float p = cursor.x() - 2.0f * height();
+		const float newvalue = slider_minimum + round(p /s);
+		if (slider_value != newvalue) {
+			slider_value = newvalue;
+			emit(EventSliderChanged, this);
 		}
 	}
 }
diff --git a/src/ui/widget.cc b/src/ui/widget.cc
index 7cde03b..e931147 100644
--- a/src/ui/widget.cc
+++ b/src/ui/widget.cc
@@ -492,6 +492,7 @@ void Widget::event_draw()
 
 void Widget::event_resize()
 {
+	//con_debug << "event_resize in " << label() << std::endl();
 	resize();
 
 	for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) {
-- 
cgit v1.2.3