[Scummvm-cvs-logs] CVS: scummvm/gui ListWidget.h,1.21,1.22 ListWidget.cpp,1.35,1.36

Max Horn fingolfin at users.sourceforge.net
Wed Jul 21 07:30:05 CEST 2004


Update of /cvsroot/scummvm/scummvm/gui
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1111

Modified Files:
	ListWidget.h ListWidget.cpp 
Log Message:
Allow user to select ListWidget entries by typing them (see FR #922921)

Index: ListWidget.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ListWidget.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- ListWidget.h	5 Feb 2004 00:19:54 -0000	1.21
+++ ListWidget.h	21 Jul 2004 14:28:57 -0000	1.22
@@ -56,8 +56,12 @@
 	ScrollBarWidget	*_scrollBar;
 	int				_currentKeyDown;
 	String			_backupString;
+
 	bool			_caretVisible;
 	uint32			_caretTime;
+	
+	String			_quickSelectStr;
+	uint32			_quickSelectTime;
 public:
 	ListWidget(GuiObject *boss, int x, int y, int w, int h);
 	virtual ~ListWidget();

Index: ListWidget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ListWidget.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- ListWidget.cpp	5 Feb 2004 00:19:54 -0000	1.35
+++ ListWidget.cpp	21 Jul 2004 14:28:57 -0000	1.36
@@ -41,6 +41,8 @@
 
 	_caretVisible = false;
 	_caretTime = 0;
+	
+	_quickSelectTime = 0;
 
 	// FIXME: This flag should come from widget definition
 	_editable = true;
@@ -125,48 +127,94 @@
 	_scrollBar->handleMouseWheel(x, y, direction);
 }
 
+
+static int matchingCharsIgnoringCase(const char *x, const char *y, bool &stop) {
+	int match = 0;
+	while (*x && *y && toupper(*x) == toupper(*y)) {
+		++x;
+		++y;
+		++match;
+	}
+	stop = !*y || (*x && (toupper(*x) >= toupper(*y)));
+	return match;
+}
+
 bool ListWidget::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
 	bool handled = true;
 	bool dirty = false;
 	int oldSelectedItem = _selectedItem;
 
-	if (_editMode) {
+	if (!_editMode && isprint((char)ascii)) {
+		// Quick selection mode: Go to first list item starting with this key
+		// (or a substring accumulated from the last couple key presses).
+		// Only works in a useful fashion if the list entries are sorted.
+		// TODO: Maybe this should be off by default, and instead we add a
+		// method "enableQuickSelect()" or so ?
+		uint32 time = g_system->get_msecs();
+		if (_quickSelectTime < time) {
+			_quickSelectStr = (char)ascii;
+		} else {
+			_quickSelectStr += (char)ascii;
+		}
+		_quickSelectTime = time + 300;	// TODO: Turn this into a proper constant (kQuickSelectDelay ?)
+		
+
+		// FIXME: This is bad slow code (it scans the list linearly each time a
+		// key is pressed); it could be much faster. Only of importance if we have
+		// quite big lists to deal with -- so for now we can live with this lazy
+		// implementation :-)
+		int newSelectedItem = 0;
+		int bestMatch = 0;
+		bool stop;
+		for (StringList::const_iterator i = _list.begin(); i != _list.end(); ++i) {
+			const int match = matchingCharsIgnoringCase(i->c_str(), _quickSelectStr.c_str(), stop);
+			if (match > bestMatch || stop) {
+				_selectedItem = newSelectedItem;
+				bestMatch = match;
+				if (stop)
+					break;
+			}
+			newSelectedItem++;
+		}
+
+		scrollToCurrent();
+	} else if (_editMode) {
 
 		if (_caretVisible)
 			drawCaret(true);
 
 		switch (keycode) {
-			case '\n':	// enter/return
-			case '\r':
-				// enter, confirm edit and exit editmode
-				_editMode = false;
-				dirty = true;
-				sendCommand(kListItemActivatedCmd, _selectedItem);
-				break;
-			case 27:	// escape
-				// ESC, abort edit and exit editmode
-				_editMode = false;
-				dirty = true;
-				_list[_selectedItem] = _backupString;
-				break;
-			case 8:		// backspace
-				_list[_selectedItem].deleteLastChar();
+		case '\n':	// enter/return
+		case '\r':
+			// confirm edit and exit editmode
+			_editMode = false;
+			dirty = true;
+			sendCommand(kListItemActivatedCmd, _selectedItem);
+			break;
+		case 27:	// escape
+			// abort edit and exit editmode
+			_editMode = false;
+			dirty = true;
+			_list[_selectedItem] = _backupString;
+			break;
+		case 8:		// backspace
+			_list[_selectedItem].deleteLastChar();
+			dirty = true;
+			break;
+		default:
+			if (isprint((char)ascii)) {
+				_list[_selectedItem] += (char)ascii;
 				dirty = true;
-				break;
-			default:
-				if (isprint((char)ascii)) {
-					_list[_selectedItem] += (char)ascii;
-					dirty = true;
-				} else {
-					handled = false;
-				}
+			} else {
+				handled = false;
+			}
 		}
 
 	} else {
 		// not editmode
 
 		switch (keycode) {
-		case '\n':	// enter
+		case '\n':	// enter/return
 		case '\r':
 			if (_selectedItem >= 0) {
 				// override continuous enter keydown





More information about the Scummvm-git-logs mailing list