[Scummvm-cvs-logs] CVS: scummvm/gui ListWidget.cpp,1.6,1.7 ScrollBarWidget.cpp,1.4,1.5 dialog.cpp,1.19,1.20 widget.cpp,1.15,1.16 ScrollBarWidget.h,1.3,1.4 dialog.h,1.10,1.11 widget.h,1.13,1.14

Max Horn fingolfin at users.sourceforge.net
Sat Jul 13 15:42:01 CEST 2002


Update of /cvsroot/scummvm/scummvm/gui
In directory usw-pr-cvs1:/tmp/cvs-serv4338/gui

Modified Files:
	ListWidget.cpp ScrollBarWidget.cpp dialog.cpp widget.cpp 
	ScrollBarWidget.h dialog.h widget.h 
Log Message:
added latest of painelf's patches which makes NewGui handle system events directly (code becomes much cleaner and more powerful this way); he also implemented a 'focus' item in NewGui; atop of this several changes of my own that further improve the GUI behaviour

Index: ListWidget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ListWidget.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ListWidget.cpp	13 Jul 2002 18:32:08 -0000	1.6
+++ ListWidget.cpp	13 Jul 2002 22:41:29 -0000	1.7
@@ -27,11 +27,7 @@
 
 /*
  * TODO:
- * - The handleKey method of widgets is currently never called, code for that has
- *   to be added to dialog.cpp
- * - Once the above item is done, implement scrolling using arrow keys,
- *   pageup/pagedown, home/end keys etc.
- * - Allow user to select an entry w/ the mouse
+ * - Implement scrolling using arrow keys, pageup/pagedown, home/end keys etc.
  * - Implement editing of the selected string in a generic fashion
  */
 

Index: ScrollBarWidget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ScrollBarWidget.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- ScrollBarWidget.cpp	13 Jul 2002 18:32:08 -0000	1.4
+++ ScrollBarWidget.cpp	13 Jul 2002 22:41:29 -0000	1.5
@@ -60,11 +60,11 @@
 ScrollBarWidget::ScrollBarWidget(Dialog *boss, int x, int y, int w, int h)
 	: Widget (boss, x, y, w, h), CommandSender(boss)
 {
-	_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG;
+	_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG | WIDGET_WANT_TICKLE;
 	_type = kScrollBarWidget;
 
 	_part = kNoPart;
-	_isDraggingSlider = false;
+	_draggingPart = kNoPart;
 
 }
 
@@ -75,37 +75,33 @@
 	if (y <= UP_DOWN_BOX_HEIGHT) {
 		// Up arrow
 		_currentPos--;
+		_draggingPart = kUpArrowPart;
 	} else if (y >= _h - UP_DOWN_BOX_HEIGHT) {
 		// Down arrow
 		_currentPos++;
+		_draggingPart = kDownArrowPart;
 	} else if (y < _sliderPos) {
 		_currentPos -= _entriesPerPage;
 	} else if (y >= _sliderPos + _sliderHeight) {
 		_currentPos += _entriesPerPage;
 	} else {
-		_isDraggingSlider = true;
+		_draggingPart = kSliderPart;
 		_sliderDeltaMouseDownPos = y - _sliderPos;
 	}
 
 	// Make sure that _currentPos is still inside the bounds
-	checkbounds();
-
-	if (old_pos != _currentPos) {
-		recalc();
-		draw();
-		sendCommand(kSetPositionCmd, _currentPos);
-	}
+	checkBounds(old_pos);
 }
 
 void ScrollBarWidget::handleMouseUp(int x, int y, int button)
 {
-	if (_isDraggingSlider)
-		_isDraggingSlider = false;
+	if (_draggingPart != kNoPart)
+		_draggingPart = kNoPart;
 }
 
 void ScrollBarWidget::handleMouseMoved(int x, int y, int button)
 {
-	if (_isDraggingSlider) {
+	if (_draggingPart == kSliderPart) {
 		int old_pos = _currentPos;
 		_sliderPos = y - _sliderDeltaMouseDownPos;
 
@@ -118,12 +114,7 @@
 		_currentPos =
 			(_sliderPos - UP_DOWN_BOX_HEIGHT) * (_numEntries - _entriesPerPage) / (_h - _sliderHeight -
 																																						 2 * UP_DOWN_BOX_HEIGHT);
-		checkbounds();
-
-		if (_currentPos != old_pos) {
-			draw();
-			sendCommand(kSetPositionCmd, _currentPos);
-		}
+		checkBounds(old_pos);
 	} else {
 		int old_part = _part;
 
@@ -143,12 +134,39 @@
 	}
 }
 
-void ScrollBarWidget::checkbounds()
+void ScrollBarWidget::handleTickle()
+{
+/*
+	// FIXME - this code is supposed to allow for "click-repeat" (like key repeat),
+	// i.e. if you click on one of the arrows and keep clicked, it will scroll
+	// continously. However, just like key repeat, this requires two delays:
+	// First an "initial" delay that has to pass before repeating starts (otherwise
+	// it is near to impossible to achieve single clicks). Secondly, a repeat delay
+	// that determines how often per second a click is simulated.
+	int old_pos = _currentPos;
+
+	if (_draggingPart == kUpArrowPart)
+		_currentPos--;
+	else if (_draggingPart == kDownArrowPart)
+		_currentPos++;
+
+	// Make sure that _currentPos is still inside the bounds
+	checkBounds(old_pos);
+*/
+}
+
+void ScrollBarWidget::checkBounds(int old_pos)
 {
 	if (_currentPos > _numEntries - _entriesPerPage)
 		_currentPos = _numEntries - _entriesPerPage;
 	else if (_currentPos < 0)
 		_currentPos = 0;
+
+	if (old_pos != _currentPos) {
+		recalc();
+		draw();
+		sendCommand(kSetPositionCmd, _currentPos);
+	}
 }
 
 void ScrollBarWidget::recalc()
@@ -171,6 +189,9 @@
 	int bottomY = _y + _h;
 
 	gui->frameRect(_x, _y, _w, _h, gui->_shadowcolor);
+
+	if (_draggingPart != kNoPart)
+		_part = _draggingPart;
 
 	// Up arrow
 	gui->frameRect(_x, _y, _w, UP_DOWN_BOX_HEIGHT, gui->_color);

Index: dialog.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/dialog.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- dialog.cpp	13 Jul 2002 18:32:08 -0000	1.19
+++ dialog.cpp	13 Jul 2002 22:41:29 -0000	1.20
@@ -40,15 +40,6 @@
 	// Draw the fixed parts of the dialog: background and border.
 	_gui->blendRect(_x, _y, _w, _h, _gui->_bgcolor);
 	_gui->box(_x, _y, _w, _h);
-
-	// Draw a bgcolor rectangle for all widgets which have WIDGET_CLEARBG set. 
-	Widget *w = _firstWidget;
-	while (w) {
-		if (w->_flags & WIDGET_CLEARBG)
-			_gui->fillRect(_x + w->_x, _y + w->_y, w->_w, w->_h, _gui->_bgcolor);
-		// FIXME - should we also draw borders here if WIDGET_BORDER is set?
-		w = w->_next;
-	}
 	
 	// Finally blit this to _screenBuf
 	_gui->blitTo(_screenBuf, _x, _y, _w, _h); 
@@ -82,18 +73,30 @@
 
 void Dialog::handleMouseDown(int x, int y, int button)
 {
-	// FIXME: If outside focused widget, widget loses focus
+	_focusedWidget = findWidget(x, y);
 
-	Widget *w = findWidget(x - _x, y - _y);
-	if (w)
-		w->handleMouseDown(x - _x - w->_x, y - _y - w->_y, button);
+	if (_focusedWidget) {
+		_focusedWidget->handleMouseDown(x - _focusedWidget->_x, y - _focusedWidget->_y, button);
+	}
 }
 
 void Dialog::handleMouseUp(int x, int y, int button)
 {
-	Widget *w = findWidget(x - _x, y - _y);
+	Widget *w;
+	
+	if (_focusedWidget) {
+		w = _focusedWidget;
+		
+		// Lose focus on mouseup unless the widget requested to retain the focus
+		if (! (_focusedWidget->getFlags() & WIDGET_RETAIN_FOCUS ))
+			_focusedWidget = 0;
+
+	} else {
+		w = findWidget(x, y);
+	}
+
 	if (w)
-		w->handleMouseUp(x - _x - w->_x, y - _y - w->_y, button);
+		w->handleMouseUp(x - w->_x, y - w->_y, button);
 }
 
 void Dialog::handleKeyDown(char key, int modifiers)
@@ -102,53 +105,76 @@
 	if (key == 27)
 		close();
 	
-	// FIXME: Only if not focused widget
-
-	// Hotkey handling
-	Widget *w = _firstWidget;
-	key = toupper(key);
-	while (w) {
-		if (w->_type == kButtonWidget && key == toupper(((ButtonWidget *)w)->_hotkey)) {
-			// FIXME: Calling both handlers is bad style, but we don't really know which one we're supposed to call
-			w->handleMouseDown(0, 0, 1);
-			w->handleMouseUp(0, 0, 1);
-			break;
+	if (_focusedWidget) {
+		_focusedWidget->handleKeyDown(key, modifiers);
+	} else {
+		// Hotkey handling
+		Widget *w = _firstWidget;
+		key = toupper(key);
+		while (w) {
+			if (w->_type == kButtonWidget && key == toupper(((ButtonWidget *)w)->_hotkey)) {
+				// We first send a mouseDown then a mouseUp.
+				// FIXME: insert a brief delay between both.
+				w->handleMouseDown(0, 0, 1);
+				w->handleMouseUp(0, 0, 1);
+				break;
+			}
+			w = w->_next;
 		}
-		w = w->_next;
 	}
-	
-	// TODO - introduce the notion of a "focused" widget which receives
-	// key events (by calling its handleKey method). Required for editfields
-	// and also for an editable list widget.
 }
 
 void Dialog::handleKeyUp(char key, int modifiers)
 {
-	// FIXME: Focused widget recieves keyup
+	// Focused widget recieves keyup events
+	if (_focusedWidget)
+		_focusedWidget->handleKeyUp(key, modifiers);
 }
 
 void Dialog::handleMouseMoved(int x, int y, int button)
 {
-	Widget *w = findWidget(x - _x, y - _y);
-
-	if (_mouseWidget != w) {
-		if (_mouseWidget)
-			_mouseWidget->handleMouseLeft(button);
-		if (w)
+	Widget *w;
+	
+	if (_focusedWidget) {
+		w = _focusedWidget;
+		
+		// We still send mouseEntered/Left messages to the focused item
+		// (but to no other items).
+		bool mouseInFocusedWidget = (x >= w->_x && x < w->_x + w->_w && y >= w->_y && y < w->_y + w->_h);
+		if (mouseInFocusedWidget && _mouseWidget != w) {
+			_mouseWidget = w;
 			w->handleMouseEntered(button);
-		_mouseWidget = w;
-	} 
+		} else if (!mouseInFocusedWidget && _mouseWidget == w) {
+			_mouseWidget = 0;
+			w->handleMouseLeft(button);
+		}
+			
+	} else {
+		w = findWidget(x, y);
 
-	if (!w)
-		return;
-	
-	if (w->getFlags() & WIDGET_TRACK_MOUSE) {
-		w->handleMouseMoved(x - _x - w->_x, y - _y - w->_y, button);
-	}
+		if (_mouseWidget != w) {
+			if (_mouseWidget)
+				_mouseWidget->handleMouseLeft(button);
+			if (w)
+				w->handleMouseEntered(button);
+			_mouseWidget = w;
+		} 
 
-	//FIXME: Focused widget recieves mouseup
+		if (!w || !(w->getFlags() & WIDGET_TRACK_MOUSE)) {
+			return;
+		}
+	}
+	
+	w->handleMouseMoved(x - w->_x, y - w->_y, button);
 }
 
+void Dialog::handleTickle()
+{
+	// Focused widget recieves tickle notifications
+	if (_focusedWidget && _focusedWidget->getFlags() & WIDGET_WANT_TICKLE) {
+		_focusedWidget->handleTickle();
+	}
+}
 
 void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
 {
@@ -167,8 +193,8 @@
 {
 	Widget *w = _firstWidget;
 	while (w) {
-		// Stop as soon as we find a fidget that contains (x,y)
-		if (x >= w->_x && x <= w->_x + w->_w && y >= w->_y && y <= w->_y + w->_h)
+		// Stop as soon as we find a widget that contains the point (x,y)
+		if (x >= w->_x && x < w->_x + w->_w && y >= w->_y && y < w->_y + w->_h)
 			break;
 		w = w->_next;
 	}
@@ -177,6 +203,8 @@
 
 void Dialog::close()
 {
+	_mouseWidget = 0;
+	_focusedWidget = 0;
 	_gui->closeTopDialog();
 }
 

Index: widget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/widget.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- widget.cpp	13 Jul 2002 18:32:08 -0000	1.15
+++ widget.cpp	13 Jul 2002 22:41:29 -0000	1.16
@@ -34,7 +34,7 @@
 
 void Widget::draw()
 {
-	NewGui *gui = _boss->_gui;
+	NewGui *gui = _boss->getGui();
 	
 	if (_flags & WIDGET_INVISIBLE)
 		return;
@@ -127,9 +127,9 @@
 	}
 }
 
-void ButtonWidget::handleMouseDown(int x, int y, int button)
+void ButtonWidget::handleMouseUp(int x, int y, int button)
 {
-	if (_flags & WIDGET_ENABLED)
+	if (_flags & WIDGET_ENABLED && x >= 0 && x < _w && y >= 0 && y < _h)
 		sendCommand(_cmd, 0);
 }
 

Index: ScrollBarWidget.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ScrollBarWidget.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- ScrollBarWidget.h	13 Jul 2002 18:32:08 -0000	1.3
+++ ScrollBarWidget.h	13 Jul 2002 22:41:29 -0000	1.4
@@ -27,6 +27,7 @@
 	kScrollBarWidth		= 9
 };
 
+
 enum {
 	kSetPositionCmd		= 'SETP'
 };
@@ -34,24 +35,27 @@
 
 class ScrollBarWidget : public Widget, public CommandSender {
 protected:
-	enum {
+	typedef enum {
 		kNoPart,
 		kUpArrowPart,
 		kDownArrowPart,
 		kSliderPart,
 		kPageUpPart,
 		kPageDownPart
-	}		_part;
+	} Part;
+	
+	Part	_part;
 	int		_sliderHeight;
 	int		_sliderPos;
 
-	bool	_isDraggingSlider;
+	Part	_draggingPart;
 	int		_sliderDeltaMouseDownPos;
 
 public:
 	int		_numEntries;
 	int		_entriesPerPage;
 	int		_currentPos;
+
 public:
 	ScrollBarWidget(Dialog *boss, int x, int y, int w, int h);
 
@@ -60,13 +64,16 @@
 	void handleMouseMoved(int x, int y, int button);
 	void handleMouseEntered(int button)	{ setFlags(WIDGET_HILITED); }
 	void handleMouseLeft(int button)	{ clearFlags(WIDGET_HILITED); _part = kNoPart; draw(); }
-
-	// FIXME: Shouldn't these be private?
+	void handleTickle();
+	
+	// FIXME - this should be private, but then we also have to add accessors
+	// for _numEntries, _entriesPerPage and _currentPos. This again leads to the question:
+	// should these accessors force a redraw?
 	void recalc();
 
 protected:
 	void drawWidget(bool hilite);
-	void checkbounds();
+	void checkBounds(int old_pos);
 };
 
 

Index: dialog.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/dialog.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- dialog.h	13 Jul 2002 18:32:08 -0000	1.10
+++ dialog.h	13 Jul 2002 22:41:29 -0000	1.11
@@ -36,27 +36,30 @@
 
 class Dialog : public CommandReceiver {
 	friend class Widget;
+	friend class NewGui;
 protected:
 	NewGui	*_gui;
-	Widget	*_firstWidget;
 	int16	_x, _y;
 	uint16	_w, _h;
+	Widget	*_firstWidget;
 	Widget	*_mouseWidget;
+	Widget  *_focusedWidget;
 	byte	*_screenBuf;
 
 public:
 	Dialog(NewGui *gui, int x, int y, int w, int h)
-		: _gui(gui), _firstWidget(0), _x(x), _y(y), _w(w), _h(h), _mouseWidget(0), _screenBuf(0)
+		: _gui(gui), _x(x), _y(y), _w(w), _h(h), _firstWidget(0),
+		  _mouseWidget(0), _focusedWidget(0), _screenBuf(0)
 		{}
 	virtual ~Dialog();
 
 	virtual void draw();
 
-	//virtual void handleIdle(); // Called periodically
+	virtual void handleTickle(); // Called periodically (in every guiloop() )
 	virtual void handleMouseDown(int x, int y, int button);
 	virtual void handleMouseUp(int x, int y, int button);
-	virtual void handleKeyDown(char key, int modifiers); // modifiers = alt/shift/ctrl etc.
-	virtual void handleKeyUp(char key, int modifiers); // modifiers = alt/shift/ctrl etc.
+	virtual void handleKeyDown(char key, int modifiers);
+	virtual void handleKeyUp(char key, int modifiers);
 	virtual void handleMouseMoved(int x, int y, int button);
 	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
 	

Index: widget.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/widget.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- widget.h	13 Jul 2002 18:32:08 -0000	1.13
+++ widget.h	13 Jul 2002 22:41:29 -0000	1.14
@@ -32,7 +32,9 @@
 	WIDGET_BORDER		= 1 << 3,
 	WIDGET_CLEARBG		= 1 << 4,
 	WIDGET_WANT_TICKLE	= 1 << 5,
-	WIDGET_TRACK_MOUSE	= 1 << 6
+	WIDGET_TRACK_MOUSE	= 1 << 6,
+	WIDGET_RETAIN_FOCUS	= 1 << 7		// Retain focus on mouse up. By default widgets lose focus on mouseup, but some widgets might want to retain it - widgets where you enter text, for instance
+
 };
 
 enum {
@@ -75,13 +77,14 @@
 class Widget {
 friend class Dialog;
 protected:
-	int			_type;
+	uint32		_type;
 	Dialog		*_boss;
 	Widget		*_next;
 	int16		_x, _y;
 	uint16		_w, _h;
 	uint16		_id;
-	int			_flags;
+	uint16		_flags;
+
 public:
 	Widget(Dialog *boss, int x, int y, int w, int h);
 	virtual ~Widget() {}
@@ -93,6 +96,7 @@
 	virtual void handleMouseMoved(int x, int y, int button) {}
 	virtual void handleKeyDown(char key, int modifiers) {}
 	virtual void handleKeyUp(char key, int modifiers) {}
+	virtual void handleTickle() {}
 	void draw();
 
 	void setFlags(int flags)	{ _flags |= flags; }
@@ -132,7 +136,7 @@
 	void setCmd(uint32 cmd)					{ _cmd = cmd; }
 	uint32 getCmd() const					{ return _cmd; }
 
-	void handleMouseDown(int x, int y, int button);
+	void handleMouseUp(int x, int y, int button);
 	void handleMouseEntered(int button)	{ setFlags(WIDGET_HILITED); draw(); }
 	void handleMouseLeft(int button)	{ clearFlags(WIDGET_HILITED); draw(); }
 };





More information about the Scummvm-git-logs mailing list