[Scummvm-cvs-logs] CVS: scummvm/gui ScrollBarWidget.cpp,NONE,1.1 util.cpp,NONE,1.1 ScrollBarWidget.h,NONE,1.1 util.h,NONE,1.1 ListWidget.cpp,1.1,1.2 dialog.cpp,1.15,1.16 widget.cpp,1.13,1.14 ListWidget.h,1.2,1.3 dialog.h,1.7,1.8 widget.h,1.10,1.11

Max Horn fingolfin at users.sourceforge.net
Fri Jul 12 09:25:03 CEST 2002


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

Modified Files:
	ListWidget.cpp dialog.cpp widget.cpp ListWidget.h dialog.h 
	widget.h 
Added Files:
	ScrollBarWidget.cpp util.cpp ScrollBarWidget.h util.h 
Log Message:
Countless changes to the New GUI; some hightligths: new ScrollBarWidget class; ListWidget is usable (demo shows it off); added custom String/StringList classes

--- NEW FILE: ScrollBarWidget.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/ScrollBarWidget.cpp,v 1.1 2002/07/12 16:24:11 fingolfin Exp $
 */

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


/*
 * TODO:
 * - Dragging the slider with the mouse
 * - Auto-repeast: if one clicks & holds on one of the arrows, then after a
 *   brief delay, it should start to contiously scroll
 * - Allow for a horizontal scrollbar, too?
 */


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

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

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;
	_type = kScrollBarWidget;
	
	_part = kNoPart;
	
}

void ScrollBarWidget::handleClick(int x, int y, int button)
{
	int old_pos = _currentPos;
	if (y <= 10) {
		// Up arrow
		_currentPos--;
	} else if (y >= _h-10) {
		// Down arrow
		_currentPos++;
	} else if (y < _sliderPos) {
		_currentPos -= _entriesPerPage;
	} else if (y >= _sliderPos + _sliderHeight) {
		_currentPos += _entriesPerPage;
	} else {
		printf("Slider\n");
	}
	
	// Bound checking
	if (_currentPos > _numEntries - _entriesPerPage)
		_currentPos = _numEntries - _entriesPerPage;
	else if (_currentPos < 0)
		_currentPos = 0;
	
	// Redraw & notify, but only if the position really changed
	if (old_pos != _currentPos) {
		recalc();
		draw();
		sendCommand(kSetPositionCmd, _currentPos);
	}
}

void ScrollBarWidget::handleMouseMoved(int x, int y, int button)
{
	int old_part = _part;
	if (y <= 10)				// Up arrow
		_part = kUpArrowPart;
	else if (y >= _h-10)		// Down arrow
		_part = kDownArrowPart;
	else if (y < _sliderPos)
		_part = kPageUpPart;
	else if (y >= _sliderPos + _sliderHeight)
		_part = kPageDownPart;
	else
		_part = kSliderPart;
	
	if (old_part != _part)
		draw();
}

void ScrollBarWidget::recalc()
{
	_sliderHeight = (_h-20) * _entriesPerPage / _numEntries;
	if (_sliderHeight < 4)
		_sliderHeight = 4;
	
	_sliderPos = 10 + (_h-20-_sliderHeight+1) *_currentPos / (_numEntries - _entriesPerPage);
	if (_sliderPos < 0)
		_sliderPos = 0;
	
}


void ScrollBarWidget::drawWidget(bool hilite)
{
	NewGui *gui = _boss->getGui();
	int		bottomY = _y + _h;
	
	gui->frameRect(_x, _y, _w, _h, gui->_shadowcolor);
	
	// Up arrow
	gui->frameRect(_x, _y, _w, 10, gui->_color);
	gui->drawBitmap(up_arrow, _x, _y,
				(hilite && _part == kUpArrowPart) ? gui->_textcolorhi : gui->_textcolor);
	
	// Down arrow
	gui->frameRect(_x, bottomY - 9, _w, 10, gui->_color);
	gui->drawBitmap(down_arrow, _x, bottomY - 9,
				(hilite && _part == kDownArrowPart) ? gui->_textcolorhi : gui->_textcolor);
	
	// Slider
	// FIXME - determine slider position and size. This depends on:
	// * the number of entries per page
	// * total number of entries
	// * current scroll position (i.e. index of "first" visible entry)
	gui->checkerRect(_x, _y + _sliderPos, _w, _sliderHeight,
				(hilite && _part == kSliderPart) ? gui->_textcolorhi : gui->_textcolor);
	gui->frameRect(_x, _y + _sliderPos, _w, _sliderHeight, gui->_color);
}

--- NEW FILE: util.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/util.cpp,v 1.1 2002/07/12 16:24:11 fingolfin Exp $
 */

#include "stdafx.h"
#include "util.h"

// 8-bit alpha blending routines
int BlendCache[256][256];

int RGBMatch(byte *palette, int r, int g, int b)
{
	int i, bestidx = 0, besterr = 0xFFFFFF;
	int error = 0;

	for (i = 0;i < 256;i++) {
		byte *pal = palette + (i * 3);
		int r_diff = r - (int)*pal++; 
		int g_diff = g - (int)*pal++; 
		int b_diff = b - (int)*pal++; 
		r_diff *= r_diff; g_diff *= g_diff; b_diff *= b_diff;

		error = r_diff + g_diff + b_diff;
		if (error < besterr) {
			besterr = error;
			bestidx = i;
		}
	}
	return bestidx;
}

int Blend(int src, int dst, byte *palette)
{
	int r, g, b;
	int alpha = 128;	// Level of transparency [0-256]
	byte *srcpal = palette + (dst  * 3);
	byte *dstpal = palette + (src * 3);

	if (BlendCache[dst][src] > -1)
		return BlendCache[dst][src];

	r =  (*srcpal++ * alpha);
    r += (*dstpal++ * (256-alpha));
    r /= 256;

    g =  (*srcpal++ * alpha);
    g += (*dstpal++ * (256-alpha));
    g /= 256;

    b =  (*srcpal++ * alpha);
    b += (*dstpal++  * (256-alpha));
    b /= 256;
       
	return (BlendCache[dst][src] = RGBMatch(palette, r , g , b ));
}

void ClearBlendCache(byte *palette, int weight)
{
	for (int i = 0; i < 256; i++)
		for (int j = 0 ; j < 256 ; j++)			
//			BlendCache[i][j] = i;	// No alphablending
//			BlendCache[i][j] = j;	// 100% translucent
			BlendCache[i][j] = -1;	// Enable alphablending
}


#pragma mark -


String::String(const char *str)
{
	_capacity = _len = strlen(str);
	_str = (char *)calloc(1, _capacity+1);
	memcpy(_str, str, _len+1);
}

String::String(const String &str)
{
	_capacity = str._capacity;
	_len = str._len;
	_str = (char *)calloc(1, _capacity+1);
	memcpy(_str, str._str, _len+1);
}

String::~String()
{
	if (_str)
		free(_str);
}

String& String::operator  =(const char* str)
{
	int len = strlen(str);
	ensureCapacity(len, false);
	
	_len = len;
	memcpy(_str, str, _len + 1);

	return *this;
}

String& String::operator  =(const String& str)
{
	int len = str._len;
	ensureCapacity(len, false);
	
	_len = len;
	memcpy(_str, str._str, _len + 1);

	return *this;
}

String& String::operator +=(const char* str)
{
	int len = strlen(str);
	ensureCapacity(_len + len, true);
	
	memcpy(_str + _len, str, len + 1);
	_len += len;

	return *this;
}

String& String::operator +=(const String& str)
{
	int len = str._len;
	ensureCapacity(_len + len, true);
	
	memcpy(_str + _len, str._str, len + 1);
	_len += len;

	return *this;
}

String& String::operator +=(char c)
{
	int len = _len + 1;
	ensureCapacity(len, true);
	
	_str[_len++] = c;
	_str[_len] = 0;

	return *this;
}

void String::ensureCapacity(int new_len, bool keep_old)
{
	if (new_len <= _capacity)
		return;

	char	*old_str = _str;
	_capacity = new_len + 32;
	_str = (char *)calloc(1, _capacity+1);

	if (old_str) {
		if (keep_old)
			memcpy(_str, old_str, _len+1);
		free(old_str);
	}
}


#pragma mark -


StringList::StringList(const StringList& list)
	: _capacity(0), _size(0), _data(0)
{
	printf("EEEEK! StringList copy constructor called!\n");
	assert(0);
}

StringList::~StringList()
{
	if (_data)
		free(_data);
}


void StringList::push_back(const char* str)
{
	ensureCapacity(_size + 1);
	
	if (!_data[_size])
		_data[_size] = new String(str);
	else
		*_data[_size] = str;

	_size++;
}

void StringList::push_back(const String& str)
{
	ensureCapacity(_size + 1);
	
	if (!_data[_size])
		_data[_size] = new String(str);
	else
		*_data[_size] = str;

	_size++;
}


String& StringList::operator [](int idx)
{
	assert(idx >= 0 && idx < _size);
	return *_data[idx];
}

const String& StringList::operator [](int idx) const
{
	assert(idx >= 0 && idx < _size);
	return *_data[idx];
}

void StringList::ensureCapacity(int new_len)
{
	if (new_len <= _capacity)
		return;

	String	**old_data = _data;
	_capacity = new_len + 32;
	_data = (String **)calloc(sizeof(String*), _capacity);

	if (old_data) {
		memcpy(_data, old_data, _size * sizeof(String*));
		free(old_data);
	}
}

--- NEW FILE: ScrollBarWidget.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/ScrollBarWidget.h,v 1.1 2002/07/12 16:24:11 fingolfin Exp $
 */

#ifndef SCROLLBARWIDGET_H
#define SCROLLBARWIDGET_H

#include "widget.h"

#define SCROLLBAR_WIDTH	9

enum {
	kSetPositionCmd		= 'SETP'
};


class ScrollBarWidget : public Widget, public CommandSender {
protected:
	enum {
		kNoPart,
		kUpArrowPart,
		kDownArrowPart,
		kSliderPart,
		kPageUpPart,
		kPageDownPart
	}		_part;
	int		_sliderHeight;
	int		_sliderPos;
public:
	int		_numEntries;
	int		_entriesPerPage;
	int		_currentPos;
public:
	ScrollBarWidget(Dialog *boss, int x, int y, int w, int h);
//	virtual ~ScrollBarWidget();

	void handleClick(int x, int y, int button);
	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(); }

	void recalc();

protected:
	void drawWidget(bool hilite);
};


#endif

--- NEW FILE: util.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/util.h,v 1.1 2002/07/12 16:24:11 fingolfin Exp $
 */

#ifndef UTIL_H
#define UTIL_H

#include "scummsys.h"


int RGBMatch(byte *palette, int r, int g, int b);
int Blend(int src, int dst, byte *palette);
void ClearBlendCache(byte *palette, int weight);


class String {
protected:
	int		_capacity;
	int		_len;
	char	*_str;
public:
	String() : _capacity(0), _len(0), _str(0) {}
	String(const char *str);
	String(const String &str);
	~String();
	
	String& operator  =(const char* str);
	String& operator  =(const String& str);
	String& operator +=(const char* str);
	String& operator +=(const String& str);
	String& operator +=(char c);

//	operator char *()				{ return _str; }
	operator const char *()	const	{ return _str; }
	const char *c_str() const		{ return _str; }
	int size() const				{ return _len; }

protected:
	void ensureCapacity(int new_len, bool keep_old);
};

class StringList {
protected:
	int		_capacity;
	int		_size;
	String	**_data;
public:
	StringList() : _capacity(0), _size(0), _data(0) {}
	StringList(const StringList& list);
	~StringList();
	
	void push_back(const char* str);
	void push_back(const String& str);
	
	// TODO: insert, remove, ...
	
	String& operator [](int idx);
	const String& operator [](int idx) const;

	int size() const	{ return _size; }

protected:
	void ensureCapacity(int new_len);
};


#endif

Index: ListWidget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ListWidget.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ListWidget.cpp	10 Jul 2002 22:49:41 -0000	1.1
+++ ListWidget.cpp	12 Jul 2002 16:24:11 -0000	1.2
@@ -20,20 +20,19 @@
 
 #include "stdafx.h"
 #include "ListWidget.h"
+#include "ScrollBarWidget.h"
 #include "dialog.h"
 #include "newgui.h"
 
 
 /*
- * Some thoughts:
- * - We should split out the scrollbar into a seperate widget. This will
- *   simplify the drawing & mouse handling considerably, but also requires
- *   us to come up with a way to couple both widgets (shouldn't be to hard)
- * - Write a class to encapsulate the data instead of using std::list<string>.
- *   How exactly this will look and what it does has yet to be determined.
+ * 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 editing of the selected string in a generic fashion
  */
 
 
@@ -41,85 +40,87 @@
 #define	LINE_HEIGHT		10
 
 
-// Up/down arrow for the scrollbar
-static uint32 up_arrow[8] = {
-	0x00000000,
-	0x00000000,
-	0x00001000,
-	0x00001000,
-	0x00011100,
-	0x00011100,
-	0x00110110,
-	0x00100010,
-};
-
-static uint32 down_arrow[8] = {
-	0x00000000,
-	0x00000000,
-	0x00100010,
-	0x00110110,
-	0x00011100,
-	0x00011100,
-	0x00001000,
-	0x00001000,
-};
-
 ListWidget::ListWidget(Dialog *boss, int x, int y, int w, int h)
-	: Widget(boss, x, y, w, h)
+	: Widget(boss, x, y, w - SCROLLBAR_WIDTH, h)
 {
-	_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG;
+	_flags = WIDGET_ENABLED | WIDGET_CLEARBG;
 	_type = kListWidget;
+	_numberingMode = kListNumberingOne;
+	_entriesPerPage = (_h - 4) / LINE_HEIGHT;
+	_currentPos = 3;
+	
+	_scrollBar = new ScrollBarWidget(boss, _x + _w, _y, SCROLLBAR_WIDTH, _h);
+	_scrollBar->setTarget(this);
+	
+	// FIXME - fill in dummy data for now
+	_list.push_back("A simple game?");
+	_list.push_back("This space for rent!");
+	_list.push_back("To be or not to be...");
+	_list.push_back("It's not easy come up with dummy text :-)");
+	_list.push_back("Foo bar baz");
+	_list.push_back("Empty slots follow:");
+	_list.push_back("");
+	_list.push_back("");
+	_list.push_back("Now again a filled slot");
+	_list.push_back("We need some more text!");
+	_list.push_back("Because only this way...");
+	_list.push_back("...can you see the scrollbar...");
+	_list.push_back("...and verify that it works!");
+	_list.push_back("One");
+	_list.push_back("Two");
+	_list.push_back("Three");
+	_list.push_back("Four");
+	_list.push_back("The End");
+
+
+	_scrollBar->_numEntries = _list.size();
+	_scrollBar->_entriesPerPage = _entriesPerPage;
+	_scrollBar->_currentPos = _currentPos;
+	_scrollBar->recalc();
 }
 
 ListWidget::~ListWidget()
 {
 }
 
-void ListWidget::handleClick(int button)
+void ListWidget::handleClick(int x, int y, int button)
 {
 	if (_flags & WIDGET_ENABLED) {
 	}
 }
 
-void ListWidget::handleMouseMoved(int x, int y, int state)
+void ListWidget::handleKey(char key, int modifiers)
 {
 }
 
-
-void ListWidget::handleKey(char key, int modifiers)
+void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
 {
+	switch (cmd) {
+	case kSetPositionCmd:
+		if (_currentPos != data) {
+			_currentPos = data;
+			draw();
+		}
+		break;
+	}
 }
 
 void ListWidget::drawWidget(bool hilite)
 {
-	NewGui *gui = _boss->getGui();
-	int		rightX = _x + _w - 1;
-	int		leftX = rightX - 8;
-	int		bottomY = _y + _h;
-	
-	gui->frameRect(leftX, _y, 9, _h, gui->_shadowcolor);
-	
-	// Up arrow
-	gui->fillRect(leftX, _y, 9, 10, gui->_bgcolor);
-	gui->frameRect(leftX, _y, 9, 10, gui->_color);
-	gui->drawBitmap(up_arrow, leftX, _y, gui->_textcolor);
-
-	// Down arrow
-	gui->fillRect(leftX, bottomY - 9, 9, 10, gui->_bgcolor);
-	gui->frameRect(leftX, bottomY - 9, 9, 10, gui->_color);
-	gui->drawBitmap(down_arrow, leftX, bottomY - 9, gui->_textcolor);
+	NewGui	*gui = _boss->getGui();
+	int		i, pos;
+	String	buffer;
 
-	// Slider
-	// FIXME - determine slider position and size. This depends on:
-	// * the number of entries/page
-	// * total number of entries
-	// * current scroll position (i.e. idx of "first" visible entry
-	gui->fillRect(leftX, _y+20, 9, 4, gui->_textcolor);
-	gui->frameRect(leftX, _y+20, 9, 4, gui->_color);
-	
-	// Now draw the list items
+	// Draw the list items
 	// FIXME - this is just a temporary demo hack
-	gui->drawString("1. A simple game", _x+1, _y+1, _w - 10, gui->_textcolor);
-	gui->drawString("2. This space for rent", _x+1, _y+1 + LINE_HEIGHT, _w - 10, gui->_textcolorhi);
-	gui->drawString("3. To be or not to be", _x+1, _y+1 + LINE_HEIGHT*2, _w - 10, gui->_textcolor);
+	for (i = 0, pos = _currentPos; i < _entriesPerPage; i++, pos++) {
+		if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) {
+			char temp[10];
+			sprintf(temp, "%2d. ", (pos + _numberingMode));
+			buffer = temp;
+		} else
+			buffer = "";
+		buffer += _list[pos];
+		gui->drawString(buffer, _x+5, _y+2 + LINE_HEIGHT * i, _w - 10, gui->_textcolor);
+	}
 }

Index: dialog.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/dialog.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- dialog.cpp	10 Jul 2002 22:49:41 -0000	1.15
+++ dialog.cpp	12 Jul 2002 16:24:11 -0000	1.16
@@ -84,7 +84,7 @@
 {
 	Widget *w = findWidget(x - _x, y - _y);
 	if (w)
-		w->handleClick(button);
+		w->handleClick(x - _x - w->_x, y - _y - w->_y, button);
 }
 
 void Dialog::handleKey(char key, int modifiers)
@@ -98,7 +98,7 @@
 	key = toupper(key);
 	while (w) {
 		if (w->_type == kButtonWidget && key == toupper(((ButtonWidget *)w)->_hotkey)) {
-			w->handleClick(1);
+			w->handleClick(0, 0, 1);
 			break;
 		}
 		w = w->_next;
@@ -130,7 +130,7 @@
 }
 
 
-void Dialog::handleCommand(uint32 cmd)
+void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
 {
 	switch (cmd) {
 	case kCloseCmd:
@@ -205,10 +205,10 @@
 	new SliderWidget(this, 110, 20, 80, 16, "Volume", 0);
 	
 	// FIXME - test
-	new ListWidget(this, 10, 40, 180, 70);
+	new ListWidget(this, 10, 40, 180, 74);
 }
 
-void SaveLoadDialog::handleCommand(uint32 cmd)
+void SaveLoadDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
 {
 	switch (cmd) {
 	case kSaveCmd:
@@ -225,7 +225,7 @@
 		exit(1);
 		break;
 	default:
-		Dialog::handleCommand(cmd);
+		Dialog::handleCommand(sender, cmd, data);
 	}
 }
 
@@ -249,7 +249,7 @@
 	addButton(150, 35, 40, 15, CUSTOM_STRING(23), kCloseCmd, 'C');	// Close dialog - FIXME
 }
 
-void OptionsDialog::handleCommand(uint32 cmd)
+void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
 {
 	switch (cmd) {
 	case kSoundCmd:
@@ -262,7 +262,7 @@
 	case kMiscCmd:
 		break;
 	default:
-		Dialog::handleCommand(cmd);
+		Dialog::handleCommand(sender, cmd, data);
 	}
 }
 

Index: widget.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/widget.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- widget.cpp	10 Jul 2002 22:49:41 -0000	1.13
+++ widget.cpp	12 Jul 2002 16:24:11 -0000	1.14
@@ -44,7 +44,7 @@
 	_y += _boss->_y;
 
 	// Clear background (unless alpha blending is enabled)
-	if (_flags & WIDGET_CLEARBG && !_boss->_screenBuf)
+	if (_flags & WIDGET_CLEARBG)
 		gui->fillRect(_x, _y, _w, _h, gui->_bgcolor);
 
 	// Draw border
@@ -74,37 +74,37 @@
 
 
 StaticTextWidget::StaticTextWidget(Dialog *boss, int x, int y, int w, int h, const char *text)
-	: Widget (boss, x, y, w, h), _text(0)
+	: Widget (boss, x, y, w, h), _label(0)
 {
 	_type = kStaticTextWidget;
-	setText(text);
+	setLabel(text);
 }
 
 StaticTextWidget::~StaticTextWidget()
 {
-	if (_text) {
-		free(_text);
-		_text = 0;
+	if (_label) {
+		free(_label);
+		_label = 0;
 	}
 }
 
-void StaticTextWidget::setText(const char *text)
+void StaticTextWidget::setLabel(const char *label)
 {
-	// Free old text if any
-	if (_text)
-		free(_text);
+	// Free old label if any
+	if (_label)
+		free(_label);
 
-	// Duplicate new text
-	if (text)
-		_text = strdup(text);
+	// Duplicate new label
+	if (label)
+		_label = strdup(label);
 	else
-		_text = 0;
+		_label = 0;
 }
 
 void StaticTextWidget::drawWidget(bool hilite)
 {
 	NewGui *gui = _boss->getGui();
-	gui->drawString(_text, _x, _y, _w, hilite ? gui->_textcolorhi : gui->_textcolor);
+	gui->drawString(_label, _x, _y, _w, hilite ? gui->_textcolorhi : gui->_textcolor);
 }
 
 
@@ -112,18 +112,26 @@
 
 
 ButtonWidget::ButtonWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd, uint8 hotkey)
-	: StaticTextWidget(boss, x, y, w, h, label), _cmd(cmd), _hotkey(hotkey)
+	: StaticTextWidget(boss, x, y, w, h, label), CommandSender(boss), _cmd(cmd), _hotkey(hotkey)
 {
+	assert(label);
 	_flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG ;
 	_type = kButtonWidget;
 }
 
-void ButtonWidget::handleClick(int button)
+ButtonWidget::~ButtonWidget()
 {
-	if (_flags & WIDGET_ENABLED && _cmd)
-		_boss->handleCommand(_cmd);
+	if (_label) {
+		free(_label);
+		_label = 0;
+	}
 }
 
+void ButtonWidget::handleClick(int x, int y, int button)
+{
+	if (_flags & WIDGET_ENABLED)
+		sendCommand(_cmd, 0);
+}
 
 #pragma mark -
 
@@ -147,13 +155,12 @@
 	_type = kCheckboxWidget;
 }
 
-void CheckboxWidget::handleClick(int button)
+void CheckboxWidget::handleClick(int x, int y, int button)
 {
 	if (_flags & WIDGET_ENABLED) {
 		_state = !_state;
 		draw();
-		if (_cmd)
-			_boss->handleCommand(_cmd);
+		sendCommand(_cmd, 0);
 	}
 }
 
@@ -171,7 +178,7 @@
 		gui->fillRect(_x + 2, _y + 2, 10, 10, gui->_bgcolor);
 	
 	// Finally draw the label
-	gui->drawString(_text, _x + 20, _y + 3, _w, gui->_textcolor);
+	gui->drawString(_label, _x + 20, _y + 3, _w, gui->_textcolor);
 }
 
 #pragma mark -

Index: ListWidget.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/ListWidget.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ListWidget.h	11 Jul 2002 23:09:07 -0000	1.2
+++ ListWidget.h	12 Jul 2002 16:24:11 -0000	1.3
@@ -22,13 +22,9 @@
 #define LISTWIDGET_H
 
 #include "widget.h"
+#include "util.h"
 
-// FIXME - use own list class later, this is for rapid development
-//#include <string>
-//#include <vector>
-//typedef	std::vector<std::string>	StringList;
-typedef int StringList;	// FIXME placeholder
-
+class ScrollBarWidget;
 
 enum {
 	kListNumberingOff	= -1,
@@ -37,13 +33,14 @@
 };
 
 /* ListWidget */
-class ListWidget : public Widget {
+class ListWidget : public Widget, public CommandReceiver {
 protected:
-	StringList	_list;
-	bool		_editable;
-	int			_numberingMode;
-	int			_currentPos;
-	
+	StringList		_list;
+	bool			_editable;
+	int				_numberingMode;
+	int				_currentPos;
+	int				_entriesPerPage;
+	ScrollBarWidget	*_scrollBar;
 public:
 	ListWidget(Dialog *boss, int x, int y, int w, int h);
 	virtual ~ListWidget();
@@ -53,9 +50,9 @@
 	
 	void setNumberingMode(int numberingMode)	{ _numberingMode = numberingMode; }
 	
-	virtual void handleClick(int button);
-	virtual void handleMouseMoved(int x, int y, int button);
+	virtual void handleClick(int x, int y, int button);
 	virtual void handleKey(char key, int modifiers);
+	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
 
 protected:
 	void drawWidget(bool hilite);

Index: dialog.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/dialog.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- dialog.h	10 Jul 2002 16:49:45 -0000	1.7
+++ dialog.h	12 Jul 2002 16:24:11 -0000	1.8
@@ -22,9 +22,8 @@
 #define DIALOG_H
 
 #include "scummsys.h"
+#include "widget.h"
 
-
-class Widget;
 class NewGui;
 
 #define RES_STRING(id)		_gui->queryResString(id)
@@ -35,7 +34,7 @@
 	kCloseCmd = 'clos'
 };
 
-class Dialog {
+class Dialog : public CommandReceiver {
 	friend class Widget;
 protected:
 	NewGui	*_gui;
@@ -57,7 +56,7 @@
 	virtual void handleClick(int x, int y, int button);
 	virtual void handleKey(char key, int modifiers); // modifiers = alt/shift/ctrl etc.
 	virtual void handleMouseMoved(int x, int y, int button);
-	virtual void handleCommand(uint32 cmd);
+	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
 	
 	NewGui	*getGui()	{ return _gui; }
 	
@@ -77,7 +76,7 @@
 public:
 	SaveLoadDialog(NewGui *gui);
 
-	virtual void handleCommand(uint32 cmd);
+	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
 };
 
 
@@ -94,7 +93,7 @@
 public:
 	OptionsDialog(NewGui *gui);
 
-	virtual void handleCommand(uint32 cmd);
+	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
 };
 
 class PauseDialog : public Dialog {

Index: widget.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/gui/widget.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- widget.h	10 Jul 2002 22:49:41 -0000	1.10
+++ widget.h	12 Jul 2002 16:24:11 -0000	1.11
@@ -41,7 +41,35 @@
 	kButtonWidget		= 'BTTN',
 	kCheckboxWidget		= 'CHKB',
 	kSliderWidget		= 'SLDE',
-	kListWidget			= 'LIST'
+	kListWidget			= 'LIST',
+	kScrollBarWidget	= 'SCRB'
+};
+
+class CommandReceiver;
+class CommandSender;
+
+class CommandReceiver
+{
+friend class CommandSender;
+protected:
+	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) = 0;
+};
+
+class CommandSender
+{
+protected:
+	CommandReceiver	*_target;
+public:
+	CommandSender(CommandReceiver *target) : _target(target) {}
+
+	void setTarget(CommandReceiver *target)	{ _target = target; }
+	CommandReceiver *getTarget() const		{ return _target; }
+
+	virtual void sendCommand(uint32 cmd, uint32 data)
+	{
+		if (_target && cmd)
+			_target->handleCommand(this, cmd, data);
+	}
 };
 
 /* Widget */
@@ -59,7 +87,7 @@
 	Widget(Dialog *boss, int x, int y, int w, int h);
 	virtual ~Widget() {}
 
-	virtual void handleClick(int button) {}
+	virtual void handleClick(int x, int y, int button) {}
 	virtual void handleMouseEntered(int button) {}
 	virtual void handleMouseLeft(int button) {}
 	virtual void handleMouseMoved(int x, int y, int button) {}
@@ -78,12 +106,12 @@
 /* StaticTextWidget */
 class StaticTextWidget : public Widget {
 protected:
-	char	*_text;
+	char	*_label;
 public:
 	StaticTextWidget(Dialog *boss, int x, int y, int w, int h, const char *text);
 	~StaticTextWidget();
-	void setText(const char *text);
-	const char *getText() const	{ return _text; }
+	void setLabel(const char *label);
+	const char *getLabel() const	{ return _label; }
 
 protected:
 	void drawWidget(bool hilite);
@@ -91,17 +119,19 @@
 
 
 /* ButtonWidget */
-class ButtonWidget : public StaticTextWidget {
-friend class Dialog;
+class ButtonWidget : public StaticTextWidget, public CommandSender {
+	friend class Dialog;	// Needed for the hotkey handling
 protected:
-	uint32	_cmd;
-	uint8	_hotkey;
+	uint32			_cmd;
+	uint8			_hotkey;
 public:
 	ButtonWidget(Dialog *boss, int x, int y, int w, int h, const char *label, uint32 cmd = 0, uint8 hotkey = 0);
-	void setCmd(uint32 cmd)	{ _cmd = cmd; }
-	uint32 getCmd() const	{ return _cmd; }
+	virtual ~ButtonWidget();
 
-	void handleClick(int button);
+	void setCmd(uint32 cmd)					{ _cmd = cmd; }
+	uint32 getCmd() const					{ return _cmd; }
+
+	void handleClick(int x, int y, int button);
 	void handleMouseEntered(int button)	{ setFlags(WIDGET_HILITED); draw(); }
 	void handleMouseLeft(int button)	{ clearFlags(WIDGET_HILITED); draw(); }
 };
@@ -115,7 +145,7 @@
 	void setState(bool state)	{ _state = state; }
 	bool getState() const		{ return _state; }
 
-	void handleClick(int button);
+	void handleClick(int x, int y, int button);
 	virtual void handleMouseEntered(int button)	{}
 	virtual void handleMouseLeft(int button)	{}
 





More information about the Scummvm-git-logs mailing list