diff options
| -rw-r--r-- | gui/EditTextWidget.cpp | 133 | ||||
| -rw-r--r-- | gui/EditTextWidget.h | 8 | ||||
| -rw-r--r-- | gui/ListWidget.cpp | 70 | ||||
| -rw-r--r-- | gui/dialog.cpp | 14 | ||||
| -rw-r--r-- | gui/dialog.h | 2 | ||||
| -rw-r--r-- | gui/launcher.cpp | 46 | ||||
| -rw-r--r-- | gui/launcher.h | 4 | ||||
| -rw-r--r-- | gui/widget.cpp | 6 | ||||
| -rw-r--r-- | gui/widget.h | 5 | 
9 files changed, 223 insertions, 65 deletions
| diff --git a/gui/EditTextWidget.cpp b/gui/EditTextWidget.cpp index 41fca2a0e8..af2b5733b6 100644 --- a/gui/EditTextWidget.cpp +++ b/gui/EditTextWidget.cpp @@ -22,3 +22,136 @@  #include "EditTextWidget.h"  #include "dialog.h"  #include "newgui.h" + +EditTextWidget::EditTextWidget(Dialog *boss, int x, int y, int w, int h, const String &text) +	: StaticTextWidget(boss, x, y-1, w, h+2, text, kTextAlignLeft), _backupString(text) +{ +	_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE; +	_type = kEditTextWidget; + +	_currentKeyDown = 0; + +	_caretVisible = false; +	_caretTime = 0; +} + +void EditTextWidget::handleTickle() +{ +	uint32 time = _boss->getGui()->get_time(); +	if (_caretTime < time) { +		_caretTime = time + kCaretBlinkTime; +		if (_caretVisible) { +			drawCaret(true); +		} else { +			drawCaret(false); +		} +	} +} + +void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) +{ +	// TODO - once we support "real editing" (i.e. caret can be at any spot), +	// a mouse click should place the caret. +} + +bool EditTextWidget::handleKeyDown(char key, int modifiers) +{ +	bool handled = true; +	bool dirty = false; + +	// First remove caret +	if (_caretVisible) +		drawCaret(true); + +	switch (key) { +		case '\n':	// enter/return +		case '\r': +			_boss->releaseFocus(); +			dirty = true; +			break; +		case 27:	// escape +			_label = _backupString; +			_boss->releaseFocus(); +			dirty = true; +			break; +		case 8:		// backspace +			_label.deleteLastChar(); +			dirty = true; +			break; +		case 20:	// left arrow +			break; +		case 19:	// right arrow +			break; +		case 22:	// home +			break; +		case 23:	// end +			break; +		default: +			if (isalnum(key)  || key == ' ') { +				_label += key; +				dirty = true; +			} else { +				handled = false; +			} +	} + +	if (dirty) +		draw(); + +#ifndef _WIN32_WCE + +	// not done on WinCE because keyboard is emulated and +	// keyup is not generated + +	_currentKeyDown = key; + +#endif +	 +	return handled; +} + +bool EditTextWidget::handleKeyUp(char key, int modifiers) +{ +	if (key == _currentKeyDown) +		_currentKeyDown = 0; +	return true; +} + +void EditTextWidget::drawWidget(bool hilite) +{ +	NewGui			*gui = _boss->getGui(); + +	// Draw a thin frame around us. +	gui->hline(_x, _y, _x+_w-1, gui->_color); +	gui->hline(_x, _y+_h-1, _x+_w-1, gui->_shadowcolor); +	gui->vline(_x, _y, _y+_h-1, gui->_color); + +	// Draw the text +	_align = (gui->getStringWidth(_label) > _w-6) ? kTextAlignRight : kTextAlignLeft; +	gui->drawString(_label, _x+2, _y+3, _w-6, gui->_textcolor, _align); +} + +void EditTextWidget::drawCaret(bool erase) +{ +	// Only draw if item is visible +	if (!isVisible() || !_boss->isVisible()) +		return; + +	NewGui *gui = _boss->getGui(); +	 +	int16 color = erase ? gui->_bgcolor : gui->_textcolorhi; +	int x = _x + _boss->getX() + 3; +	int y = _y + _boss->getY() + 1; + +	// TODO - once we support "real editing" (i.e. caret can be at any spot), +	// x should be calculated based on the current caret position. +	int width = gui->getStringWidth(_label); +	if (width > _w-6) +		width = _w-6; +	x += width; + +	gui->vline(x, y, y+kLineHeight, color); +	gui->addDirtyRect(x, y, 2, kLineHeight); +	 +	_caretVisible = !erase; +} diff --git a/gui/EditTextWidget.h b/gui/EditTextWidget.h index f955e22921..ecc5c2fe34 100644 --- a/gui/EditTextWidget.h +++ b/gui/EditTextWidget.h @@ -35,22 +35,20 @@ protected:  	bool			_caretVisible;  	uint32			_caretTime;  public: -	EditTextWidget(Dialog *boss, int x, int y, int w, int h); -	virtual ~EditTextWidget(); +	EditTextWidget(Dialog *boss, int x, int y, int w, int h, const String &text);  	virtual void handleTickle();  	virtual void handleMouseDown(int x, int y, int button, int clickCount); -	virtual void handleMouseUp(int x, int y, int button, int clickCount);  	virtual bool handleKeyDown(char key, int modifiers);  	virtual bool handleKeyUp(char key, int modifiers); -	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); +	//virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);  	virtual bool wantsFocus() { return true; };  protected:  	void drawWidget(bool hilite);  	void drawCaret(bool erase); -	void lostFocusWidget(); +	void lostFocusWidget() { _backupString = _label; drawCaret(true); }  };  #endif diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp index 751b31f037..db999d5d8e 100644 --- a/gui/ListWidget.cpp +++ b/gui/ListWidget.cpp @@ -92,7 +92,7 @@ void ListWidget::handleTickle()  {  	uint32 time = _boss->getGui()->get_time();  	if (_editMode && _caretTime < time) { -		_caretTime = time + 300; +		_caretTime = time + kCaretBlinkTime;  		if (_caretVisible) {  			drawCaret(true);  		} else { @@ -101,40 +101,6 @@ void ListWidget::handleTickle()  	}  } -void ListWidget::drawCaret(bool erase) -{ -	// Only draw if item is visible -	if (_selectedItem < _currentPos || _selectedItem >= _currentPos + _entriesPerPage) -		return; -	if (!isVisible() || !_boss->isVisible()) -		return; - -	NewGui *gui = _boss->getGui(); -	 -	// The item is selected, thus _bgcolor is used to draw the caret and _textcolorhi to erase it -	int16 color = erase ? gui->_textcolorhi : gui->_bgcolor; -	int x = _x + _boss->getX() + 3; -	int y = _y + _boss->getY() + 1; -	ScummVM::String	buffer; - -	y += (_selectedItem - _currentPos) * kLineHeight; - -	if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) { -		char temp[10]; -		sprintf(temp, "%2d. ", (_selectedItem + _numberingMode)); -		buffer = temp; -		buffer += _list[_selectedItem]; -	} else -		buffer = _list[_selectedItem]; - -	x += gui->getStringWidth(buffer); - -	gui->vline(x, y, y+kLineHeight, color); -	gui->addDirtyRect(x, y, 2, kLineHeight); -	 -	_caretVisible = !erase; -} -  void ListWidget::handleMouseDown(int x, int y, int button, int clickCount)  {  	if (isEnabled()) { @@ -332,6 +298,40 @@ void ListWidget::drawWidget(bool hilite)  	}  } +void ListWidget::drawCaret(bool erase) +{ +	// Only draw if item is visible +	if (_selectedItem < _currentPos || _selectedItem >= _currentPos + _entriesPerPage) +		return; +	if (!isVisible() || !_boss->isVisible()) +		return; + +	NewGui *gui = _boss->getGui(); +	 +	// The item is selected, thus _bgcolor is used to draw the caret and _textcolorhi to erase it +	int16 color = erase ? gui->_textcolorhi : gui->_bgcolor; +	int x = _x + _boss->getX() + 3; +	int y = _y + _boss->getY() + 1; +	ScummVM::String	buffer; + +	y += (_selectedItem - _currentPos) * kLineHeight; + +	if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) { +		char temp[10]; +		sprintf(temp, "%2d. ", (_selectedItem + _numberingMode)); +		buffer = temp; +		buffer += _list[_selectedItem]; +	} else +		buffer = _list[_selectedItem]; + +	x += gui->getStringWidth(buffer); + +	gui->vline(x, y, y+kLineHeight, color); +	gui->addDirtyRect(x, y, 2, kLineHeight); +	 +	_caretVisible = !erase; +} +  void ListWidget::scrollToCurrent() {  	// Only do something if the current item is not in our view port diff --git a/gui/dialog.cpp b/gui/dialog.cpp index d8569d979e..d2eb689d2e 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -90,12 +90,18 @@ void Dialog::close()  		_mouseWidget->handleMouseLeft(0);  		_mouseWidget = 0;  	} +	releaseFocus(); +} + +void Dialog::releaseFocus() +{  	if (_focusedWidget) {  		_focusedWidget->lostFocus();  		_focusedWidget = 0;  	}  } +  void Dialog::draw()  {  	_gui->_needRedraw = true; @@ -134,8 +140,7 @@ void Dialog::handleMouseDown(int x, int y, int button, int clickCount)  	if (w && w != _focusedWidget) {  		// The focus will change. Tell the old focused widget (if any)  		// that it lost the focus. -		if (_focusedWidget) -			_focusedWidget->lostFocus(); +		releaseFocus();  		// Tell the new focused widget (if any) that it just gained the focus.  		if (w) @@ -157,8 +162,7 @@ void Dialog::handleMouseUp(int x, int y, int button, int clickCount)  		// Lose focus on mouseup unless the widget requested to retain the focus  		if (! (_focusedWidget->getFlags() & WIDGET_RETAIN_FOCUS )) { -			_focusedWidget->lostFocus(); -			_focusedWidget = 0; +			releaseFocus();  		}  	} else { @@ -208,6 +212,8 @@ void Dialog::handleKeyDown(char key, int modifiers)  	// ESC closes all dialogs by default  	if (key == 27)  		close(); +	 +	// TODO: tab/shift-tab should focus the next/previous focusable widget  }  void Dialog::handleKeyUp(char key, int modifiers) diff --git a/gui/dialog.h b/gui/dialog.h index 2f8abf58fe..2096e325e5 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -62,6 +62,8 @@ public:  	int16	getX() const		{ return _x; }  	int16	getY() const		{ return _y; } +	void releaseFocus(); +  protected:  	virtual void open();  	virtual void close(); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 050071b3ef..e0d64eb9bc 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -50,6 +50,7 @@ typedef ScummVM::List<const VersionSettings *> GameList;   * - the description (used for user feedback only)   * - amiga/subtitles flag? Although those make only sense for Scumm games   * - the music driver for that game (<Default> or custom) + *   Of course this means we need an API to query the available music drivers.   * - maybe scaler. But there are two problems:   *   1) different backends can have different scalers with different names,   *      so we first have to add a way to query those... no Ender, I don't @@ -97,19 +98,18 @@ EditGameDialog::EditGameDialog(NewGui *gui, Config &config, const String &domain  	}  	// Label & edit widget for the description -	new StaticTextWidget(this, 10, 8, 40, kLineHeight, "Name: ", kTextAlignRight); -	new StaticTextWidget(this, 50, 8, _w-50-10, kLineHeight, description, kTextAlignLeft);	// TODO - should be an EditTextWidget -	 -	 +	new StaticTextWidget(this, 10, 10, 40, kLineHeight, "Name: ", kTextAlignRight); +	new EditTextWidget(this, 50, 10, _w-50-10, kLineHeight, description); +  	// Path to game data (view only)  	String path(_config.get("path", domain)); -	new StaticTextWidget(this, 10, 20, 40, kLineHeight, "Path: ", kTextAlignRight); -	new StaticTextWidget(this, 50, 20, _w-50-10, kLineHeight, path, kTextAlignLeft); +	new StaticTextWidget(this, 10, 24, 40, kLineHeight, "Path: ", kTextAlignRight); +	new StaticTextWidget(this, 50, 24, _w-50-10, kLineHeight, path, kTextAlignLeft);  	// Add OK & Cancel buttons  	addButton(_w-2*(kButtonWidth+10), _h-24, "Cancel", kCloseCmd, 0); -	addButton(_w-(kButtonWidth+10), _h-24, "OK", kCloseCmd, 0); +	addButton(_w-(kButtonWidth+10), _h-24, "OK", kOKCmd, 0);  }  void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) @@ -172,6 +172,7 @@ LauncherDialog::LauncherDialog(NewGui *gui, GameDetector &detector)  	// Create file browser dialog  	_browser = new BrowserDialog(_gui); +  }  LauncherDialog::~LauncherDialog() @@ -179,18 +180,29 @@ LauncherDialog::~LauncherDialog()  	delete _browser;  } +void LauncherDialog::open() +{ +	Dialog::open(); +	g_config->set_writing(true); +} + +void LauncherDialog::close() +{ +	g_config->flush(); +	g_config->set_writing(false); +	Dialog::close(); +} +  void LauncherDialog::updateListing()  {  	int i;  	const VersionSettings *v = version_settings;  	ScummVM::StringList l; -	// TODO - maybe only display those games for which settings are known -	// (i.e. a path to the game data was set and is accesible) ? -  	// Retrieve a list of all games defined in the config file +	_domains.clear();  	StringList domains = g_config->get_domains(); -	for (i = 0; i < domains.size();i++) { +	for (i = 0; i < domains.size(); i++) {  		String name(g_config->get("gameid", domains[i]));  		String description(g_config->get("description", domains[i])); @@ -217,8 +229,7 @@ void LauncherDialog::updateListing()  		}  	} -	if (l.size() > 0)  -		_list->setList(l); +	_list->setList(l);  }  /* @@ -340,9 +351,7 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat  					// User pressed OK, so make changes permanent  					// Write config to disk -					g_config->set_writing(true);  					g_config->flush(); -					g_config->set_writing(false);  					// Update the ListWidget and force a redraw  					updateListing(); @@ -358,6 +367,11 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat  		// Remove the currently selected game from the list  		assert(item >= 0);  		g_config->delete_domain(_domains[item]); + +		// Write config to disk +		g_config->flush(); +		 +		// Update the ListWidget and force a redraw  		updateListing();  		draw();  		break; @@ -374,9 +388,7 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat  			// User pressed OK, so make changes permanent  			// Write config to disk -			g_config->set_writing(true);  			g_config->flush(); -			g_config->set_writing(false);  			// Update the ListWidget and force a redraw  			updateListing(); diff --git a/gui/launcher.h b/gui/launcher.h index 1a02b9cb0c..33b26953f6 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -36,7 +36,9 @@ public:  	LauncherDialog(NewGui *gui, GameDetector &detector);  	~LauncherDialog(); -	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); +	virtual void open(); +	virtual void close(); +	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);  protected:  	ListWidget		*_list; diff --git a/gui/widget.cpp b/gui/widget.cpp index 1451dce773..b3c4aa4a58 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -101,7 +101,7 @@ void StaticTextWidget::setValue(int value)  void StaticTextWidget::drawWidget(bool hilite)  {  	NewGui *gui = _boss->getGui(); -	gui->drawString(_label.c_str(), _x, _y, _w, gui->_textcolor, _align); +	gui->drawString(_label, _x, _y, _w, gui->_textcolor, _align);  } @@ -125,7 +125,7 @@ void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount)  void ButtonWidget::drawWidget(bool hilite)  {  	NewGui *gui = _boss->getGui(); -	gui->drawString(_label.c_str(), _x, _y, _w, +	gui->drawString(_label, _x, _y, _w,  	                !isEnabled() ? gui->_color :  	                hilite ? gui->_textcolorhi : gui->_textcolor, _align);  } @@ -195,7 +195,7 @@ void CheckboxWidget::drawWidget(bool hilite)  		gui->fillRect(_x + 2, _y + 2, 10, 10, gui->_bgcolor);  	// Finally draw the label -	gui->drawString(_label.c_str(), _x + 20, _y + 3, _w, gui->_textcolor); +	gui->drawString(_label, _x + 20, _y + 3, _w, gui->_textcolor);  }  #pragma mark - diff --git a/gui/widget.h b/gui/widget.h index e68c291887..aa74167f41 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -41,6 +41,7 @@ enum {  enum {  	kStaticTextWidget	= 'TEXT', +	kEditTextWidget		= 'EDIT',  	kButtonWidget		= 'BTTN',  	kCheckboxWidget		= 'CHKB',  	kSliderWidget		= 'SLDE', @@ -49,6 +50,10 @@ enum {  };  enum { +	kCaretBlinkTime = 300 +}; + +enum {  	kButtonWidth = 56,  	kButtonHeight = 16,  }; | 
