[Scummvm-cvs-logs] CVS: scummvm/gui PopUpWidget.cpp,NONE,1.1 PopUpWidget.h,NONE,1.1 ScrollBarWidget.cpp,1.6,1.7 launcher.cpp,1.28,1.29 module.mk,1.2,1.3 newgui.cpp,1.31,1.32 newgui.h,1.18,1.19

Max Horn fingolfin at users.sourceforge.net
Thu Dec 12 04:08:03 CET 2002


Update of /cvsroot/scummvm/scummvm/gui
In directory sc8-pr-cvs1:/tmp/cvs-serv12503

Modified Files:
	ScrollBarWidget.cpp launcher.cpp module.mk newgui.cpp newgui.h 
Added Files:
	PopUpWidget.cpp PopUpWidget.h 
Log Message:
added PopUpWidget; hacked it into the edit game dialog just to show how to use it; note: this is NOT finished by any means, the look will change, the code will change, this is just an early preview :-)

--- NEW FILE: PopUpWidget.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2002 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/gui/PopUpWidget.cpp,v 1.1 2002/12/12 12:07:45 fingolfin Exp $
 */

#include "stdafx.h"
#include "PopUpWidget.h"
#include "dialog.h"
#include "newgui.h"

/* TODO:
 * - draw an (unselectable) sepeator line for items that start with a '-'
 * - handle looong lists by allowing scrolling (a lot of work if done right, 
 *   so I will probably only implement if we really need it)
 * - ...
 */

#define UP_DOWN_BOX_HEIGHT	10

// Down arrow
static uint32 down_arrow[8] = {
	0x00000000,
	0x00000000,
	0x00100010,
	0x00110110,
	0x00011100,
	0x00011100,
	0x00001000,
	0x00001000,
};

const ScummVM::String PopUpWidget::emptyStr;

class PopUpDialog : public Dialog {
protected:
	PopUpWidget	*_popUpBoss;
	int			_clickX, _clickY;
	byte		*_buffer;
	int			_selection;
public:
	PopUpDialog(PopUpWidget *boss, int clickX, int clickY);
	
	void drawDialog();

	void handleMouseDown(int x, int y, int button, int clickCount);
	void handleMouseUp(int x, int y, int button, int clickCount);
//	void handleMouseWheel(int x, int y, int direction);	// Scroll through entries with scroll wheel
	void handleMouseMoved(int x, int y, int button);	// Redraw selections depending on mouse position
//	bool handleKeyDown(uint16 ascii, int keycode, int modifiers);	// Scroll through entries with arrow keys etc.
//	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);

protected:
//	void backupMenuBackground();
//	void restoreMenuBackground();
	
	void drawMenuEntry(int entry, bool hilite);
	
	int findItem(int x, int y) const;
};

PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY)
	: Dialog(boss->_boss->getGui(), 0, 0, 16, 16),
	_popUpBoss(boss)
{
	// Calculate real popup dimensions
	_x = _popUpBoss->_boss->getX() + _popUpBoss->_x;
	_y = _popUpBoss->_boss->getY() + _popUpBoss->_y - _popUpBoss->_selectedItem * kLineHeight;
	_h = _popUpBoss->_entries.size() * kLineHeight + 2;
	_w = _popUpBoss->_w;
	
	// Copy the selection index
	_selection = _popUpBoss->_selectedItem;
	
	// TODO - perform clipping / switch to scrolling mode if we don't fit on the screen
	
	// TODO - backup background here

	// Remember original mouse position
	_clickX = clickX - _x;
	_clickY = clickY - _y;
}

void PopUpDialog::drawDialog()
{
	// Draw the menu border
	_gui->box(_x, _y, _w, _h);

	// Draw the entries
	int count = _popUpBoss->_entries.size();
	for (int i = 0; i < count; i++) {
		drawMenuEntry(i, i == _selection);
	}

	_gui->addDirtyRect(_x, _y, _w, _h);
}

void PopUpDialog::handleMouseDown(int x, int y, int button, int clickCount)
{
}


void PopUpDialog::handleMouseUp(int x, int y, int button, int clickCount)
{
	// Mouse was released. If it wasn't moved much since the original mouse down, 
	// let the popup stay open. If it did move, assume the user made his selection.
	int dist = (_clickX - x) * (_clickX - x) + (_clickY - y) * (_clickY - y);
	if (dist > 3*3) {
		setResult(_selection);
		close();
	}
	_clickX = -1;
	_clickY = -1;
}

void PopUpDialog::handleMouseMoved(int x, int y, int button)
{
	// Compute over which item
	int item = findItem(x, y);
	if (item != _selection) {
		// Undraw old selection
		if (_selection >= 0)
			drawMenuEntry(_selection, false);

		// Change selection
		_selection = item;

		// Draw new selection
		if (item >= 0)
			drawMenuEntry(item, true);
	}
}

int PopUpDialog::findItem(int x, int y) const
{
	if (x >= 0 && x < _w && y >= 0 && y < _h) {
		return (y-2) / kLineHeight;
	}
	return _popUpBoss->_selectedItem;
}

/*
void PopUpWidget::backupMenuBackground()
{
	NewGui	*gui = _boss->getGui();

	assert(_menu.buffer);
	gui->blitToBuffer(_menu.x1, _menu.y1, _menu.w, _menu.h, _menu.buffer, _menu.w * 2);
}

void PopUpWidget::restoreMenuBackground()
{
	NewGui	*gui = _boss->getGui();

	assert(_menu.buffer);
	gui->blitFromBuffer(_menu.x1, _menu.y1, _menu.w, _menu.h, _menu.buffer, _menu.w * 2);
	gui->addDirtyRect(_menu.x1, _menu.y1, _menu.w, _menu.h);
	draw();
}
*/

void PopUpDialog::drawMenuEntry(int entry, bool hilite)
{
	// Draw one entry of the popup menu, including selection
	assert(entry >= 0);
	int x = _x + 2;
	int y = _y + 2 + kLineHeight * entry;
	int w = _w - 4;

	_gui->fillRect(x, y, w, kLineHeight,
						hilite ? _gui->_textcolorhi : _gui->_bgcolor);
	_gui->drawString(_popUpBoss->_entries[entry].name, x+1, y+1, w-2,
						hilite ? _gui->_bgcolor : _gui->_textcolor);
	_gui->addDirtyRect(x, y, w, kLineHeight);
}

//
//
//
//
//


PopUpWidget::PopUpWidget(Dialog *boss, int x, int y, int w, int h)
	: Widget(boss, x, y-1, w, h+2), CommandSender(boss)
{
	_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS;
	_type = 'POPU';

	_selectedItem = -1;
}

void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount)
{
	PopUpDialog popupDialog(this, x + _x + _boss->getX(), y + _y + _boss->getY());
	int newSel = popupDialog.runModal();
	if (newSel != -1 && _selectedItem != newSel) {
		_selectedItem = newSel;
		sendCommand(kPopUpItemSelectedCmd, _selectedItem);
	}
}

void PopUpWidget::appendEntry(const String &entry, uint32 tag)
{
	Entry e;
	e.name = entry;
	e.tag = tag;
	_entries.push_back(e);
}

void PopUpWidget::clearEntries()
{
	_entries.clear();
	_selectedItem = -1;
}

void PopUpWidget::setSelected(int item)
{
	// FIXME
	if (item != _selectedItem) {
		if (item >= 0 && item < _entries.size()) {
			_selectedItem = item;
		} else {
			_selectedItem = -1;
		}
	}
}

void PopUpWidget::drawWidget(bool hilite)
{
	NewGui	*gui = _boss->getGui();

	// Draw a thin frame around us.
	// TODO - should look different than the EditTextWidget fram
	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);
	gui->vline(_x+_w-1, _y, _y+_h-1, gui->_shadowcolor);
	
	// Draw an arrow pointing down at the right end to signal this is a dropdown/popup
	gui->drawBitmap(down_arrow, _x+_w - 10, _y+1, hilite ? gui->_textcolorhi : gui->_textcolor);
	
	// Draw the selected entry, if any
	if (_selectedItem >= 0) {
		int align = (gui->getStringWidth(_entries[_selectedItem].name) > _w-6) ? kTextAlignRight : kTextAlignLeft;
		gui->drawString(_entries[_selectedItem].name, _x+2, _y+3, _w-6, gui->_textcolor, align);
	}
}

--- NEW FILE: PopUpWidget.h ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2002 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/gui/PopUpWidget.h,v 1.1 2002/12/12 12:07:46 fingolfin Exp $
 */

#ifndef POPUPWIDGET_H
#define POPUPWIDGET_H

#include "widget.h"
#include "common/str.h"
#include "common/list.h"

enum {
	kPopUpItemSelectedCmd	= 'POPs'
};

/* PopUpWidget
 * A popup or dropdown widget which, when clicked, "pop up" a list of items and
 * lets the user pick on of them.
 *
 * Implementation wise, when the user selects an item, then a kPopUpItemSelectedCmd 
 * is broadcast, with data being equal to the tag value of the selected entry.
 */
class PopUpWidget : public Widget, public CommandSender {
	friend class PopUpDialog;
	typedef ScummVM::String String;
	
	struct Entry {
		String	name;
		uint32	tag;
	};
	typedef ScummVM::List<Entry> EntryList;
protected:
	static const String emptyStr;

	EntryList		_entries;
	int				_selectedItem;

public:
	PopUpWidget(Dialog *boss, int x, int y, int w, int h);

	void handleMouseDown(int x, int y, int button, int clickCount);
/*
	void handleMouseUp(int x, int y, int button, int clickCount);
//	void handleMouseWheel(int x, int y, int direction);	// Scroll through entries with scroll wheel
	void handleMouseMoved(int x, int y, int button);	// Redraw selections depending on mouse position
//	bool handleKeyDown(uint16 ascii, int keycode, int modifiers);	// Scroll through entries with arrow keys etc.
//	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
*/

	void appendEntry(const String &entry, uint32 tag = (uint32)-1);
//	void setEntries(const EntryList &entries);
	void clearEntries();

	void setSelected(int item);
	int getSelected() const						{ return _selectedItem; }
	const String& getSelectedString() const		{ return (_selectedItem >= 0) ? _entries[_selectedItem].name : emptyStr; }

protected:
	void drawWidget(bool hilite);
};

#endif

Index: ScrollBarWidget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ScrollBarWidget.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ScrollBarWidget.cpp	13 Nov 2002 15:20:08 -0000	1.6
+++ ScrollBarWidget.cpp	12 Dec 2002 12:07:46 -0000	1.7
@@ -48,7 +48,7 @@
 	0x00100010,
 };
 
-// Up arrow
+// Down arrow
 static uint32 down_arrow[8] = {
 	0x00000000,
 	0x00000000,

Index: launcher.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/launcher.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- launcher.cpp	1 Dec 2002 12:47:13 -0000	1.28
+++ launcher.cpp	12 Dec 2002 12:07:46 -0000	1.29
@@ -26,6 +26,7 @@
 #include "message.h"
 #include "EditTextWidget.h"
 #include "ListWidget.h"
+#include "PopUpWidget.h"
 
 #include "backends/fs/fs.h"
 #include "common/config-file.h"
@@ -86,7 +87,8 @@
 };
 
 EditGameDialog::EditGameDialog(NewGui *gui, Config &config, const String &domain)
-	: Dialog(gui, 8, 50, 320-2*8, 200-2*40), _config(config), _domain(domain)
+//	: Dialog(gui, 8, 50, 320-2*8, 200-2*40), _config(config), _domain(domain)
+	: Dialog(gui, 8, 30, 320-2*8, 200-2*30), _config(config), _domain(domain)
 {
 	// Determine the description string
 	String gameid(_config.get("gameid", _domain));
@@ -130,7 +132,15 @@
 	// Load in settings for the checkboxs
 	_fullscreenCheckbox->setState(_config.getBool("fullscreen", false, _domain));
 	_AmigaPalCheckbox->setState(_config.getBool("amiga", false, _domain));
-
+	
+	// FIXME HACK - add a dummy popup widget here, for debugging.
+	// Note: this isn't useful at all right now...
+	PopUpWidget *foo;
+	foo = new PopUpWidget(this, 15, 102, 200, kLineHeight);
+	foo->appendEntry("Foo");
+	foo->appendEntry("Bar");
+	foo->appendEntry("Baz", 'QUUX');
+	foo->setSelected(0);
 }
 
 void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/module.mk,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- module.mk	21 Nov 2002 12:48:50 -0000	1.2
+++ module.mk	12 Dec 2002 12:07:46 -0000	1.3
@@ -9,6 +9,7 @@
 	gui/ListWidget.o \
 	gui/message.o \
 	gui/newgui.o \
+	gui/PopUpWidget.o \
 	gui/ScrollBarWidget.o \
 	gui/widget.o \
 

Index: newgui.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/newgui.cpp,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- newgui.cpp	22 Nov 2002 14:02:32 -0000	1.31
+++ newgui.cpp	12 Dec 2002 12:07:46 -0000	1.32
@@ -157,7 +157,7 @@
 					_system->set_mouse_pos(event.mouse.x, event.mouse.y);
 					activeDialog->handleMouseMoved(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 0);
 					break;
-				// We don'event distinguish between mousebuttons (for now at least)
+				// We don't distinguish between mousebuttons (for now at least)
 				case OSystem::EVENT_LBUTTONDOWN:
 				case OSystem::EVENT_RBUTTONDOWN: {
 					if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay)
@@ -297,9 +297,6 @@
 
 	ptr = getBasePtr(x, y);
 
-	if (ptr == NULL)
-		return;
-
 	if (x == x2) {
 		/* vertical line */
 		while (y++ <= y2) {
@@ -320,8 +317,6 @@
 	int g = GREEN_FROM_16(color) * 3;
 	int b = BLUE_FROM_16(color) * 3;
 	int16 *ptr = getBasePtr(x, y);
-	if (ptr == NULL)
-		return;
 
 	while (h--) {
 		for (int i = 0; i < w; i++) {
@@ -337,8 +332,6 @@
 {
 	int i;
 	int16 *ptr = getBasePtr(x, y);
-	if (ptr == NULL)
-		return;
 
 	while (h--) {
 		for (i = 0; i < w; i++) {
@@ -352,8 +345,6 @@
 {
 	int i;
 	int16 *ptr = getBasePtr(x, y);
-	if (ptr == NULL)
-		return;
 
 	while (h--) {
 		for (i = 0; i < w; i++) {
@@ -402,8 +393,6 @@
 	tmp = guifont + 224 + (chr + 1) * 8;
 
 	int16 *ptr = getBasePtr(xx, yy);
-	if (ptr == NULL)
-		return;
 
 	for (y = 0; y < 8; y++) {
 		for (x = 0; x < 8; x++) {
@@ -454,13 +443,43 @@
 }
 
 //
+// Blit from a buffer to the display
+//
+void NewGui::blitFromBuffer(int x, int y, int w, int h, const byte *buf, int pitch)
+{
+	int16 *ptr = getBasePtr(x, y);
+
+	assert(buf);
+	while (h--) {
+		memcpy(ptr, buf, w*2);
+		ptr += _screenPitch;
+		buf += pitch;
+	}
+}
+
+
+//
+// Blit from the display to a buffer
+//
+void NewGui::blitToBuffer(int x, int y, int w, int h, byte *buf, int pitch)
+{
+	int16 *ptr = getBasePtr(x, y);
+
+	assert(buf);
+	while (h--) {
+		memcpy(buf, ptr, w*2);
+		ptr += _screenPitch;
+		buf += pitch;
+	}
+}
+
+
+//
 // Draw an 8x8 bitmap at location (x,y)
 //
 void NewGui::drawBitmap(uint32 bitmap[8], int x, int y, int16 color)
 {
 	int16 *ptr = getBasePtr(x, y);
-	if (ptr == NULL)
-		return;
 
 	for (int y2 = 0; y2 < 8; y2++) {
 		uint32 mask = 0xF0000000;

Index: newgui.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/newgui.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- newgui.h	22 Nov 2002 14:02:32 -0000	1.18
+++ newgui.h	12 Dec 2002 12:07:46 -0000	1.19
@@ -132,13 +132,17 @@
 	void fillRect(int x, int y, int w, int h, int16 color);
 	void checkerRect(int x, int y, int w, int h, int16 color);
 	void frameRect(int x, int y, int w, int h, int16 color);
-	void addDirtyRect(int x, int y, int w, int h);
 	void drawChar(byte c, int x, int y, int16 color);
 	int getStringWidth(const String &str);
 	int getCharWidth(byte c);
 	void drawString(const String &str, int x, int y, int w, int16 color, int align = kTextAlignLeft);
 
+	void blitFromBuffer(int x, int y, int w, int h, const byte *buf, int pitch);
+	void blitToBuffer(int x, int y, int w, int h, byte *buf, int pitch);
+
 	void drawBitmap(uint32 bitmap[8], int x, int y, int16 color);
+
+	void addDirtyRect(int x, int y, int w, int h);
 };
 
 #endif





More information about the Scummvm-git-logs mailing list