| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 | #include "StdInc.h"#include "ObjectLists.h"#include "../gui/CGuiHandler.h"#include "Buttons.h"/* * ObjectLists.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */static void intDeleter(CIntObject* object){	delete object;}CObjectList::CObjectList(CreateFunc create, DestroyFunc destroy):createObject(create),destroyObject(destroy){	if (!destroyObject)		destroyObject = intDeleter;}void CObjectList::deleteItem(CIntObject* item){	if (!item)		return;	removeChild(item);	destroyObject(item);}CIntObject* CObjectList::createItem(size_t index){	OBJ_CONSTRUCTION_CAPTURING_ALL;	CIntObject * item = createObject(index);	if (item == nullptr)		item = new CIntObject();	item->recActions = defActions;	addChild(item);	return item;}CTabbedInt::CTabbedInt(CreateFunc create, DestroyFunc destroy, Point position, size_t ActiveID):CObjectList(create, destroy),activeTab(nullptr),activeID(ActiveID){	pos += position;	reset();}void CTabbedInt::setActive(size_t which){	if (which != activeID)	{		activeID = which;		reset();	}}void CTabbedInt::reset(){	deleteItem(activeTab);	activeTab = createItem(activeID);	activeTab->moveTo(pos.topLeft());	if (active)		redraw();}CIntObject * CTabbedInt::getItem(){	return activeTab;}CListBox::CListBox(CreateFunc create, DestroyFunc destroy, Point Pos, Point ItemOffset, size_t VisibleSize,				   size_t TotalSize, size_t InitialPos, int Slider, Rect SliderPos):	CObjectList(create, destroy),	first(InitialPos),	totalSize(TotalSize),	itemOffset(ItemOffset),    slider(nullptr){	pos += Pos;	items.resize(VisibleSize, nullptr);	if (Slider & 1)	{		OBJ_CONSTRUCTION_CAPTURING_ALL;		slider = new CSlider(SliderPos.x, SliderPos.y, SliderPos.w, boost::bind(&CListBox::moveToPos, this, _1),			VisibleSize, TotalSize, InitialPos, Slider & 2, Slider & 4);	}	reset();}// Used to move active items after changing list positionvoid CListBox::updatePositions(){	Point itemPos = pos.topLeft();	for (auto & elem : items)	{		(elem)->moveTo(itemPos);		itemPos += itemOffset;	}	if (active)	{		redraw();		if (slider)			slider->moveTo(first);	}}void CListBox::reset(){	size_t current = first;	for (auto & elem : items)	{		deleteItem(elem);		elem = createItem(current++);	}	updatePositions();}void CListBox::resize(size_t newSize){	totalSize = newSize;	if (slider)		slider->setAmount(totalSize);	reset();}size_t CListBox::size(){	return totalSize;}CIntObject * CListBox::getItem(size_t which){	if (which < first || which > first + items.size() || which > totalSize)		return nullptr;	size_t i=first;	for (auto iter = items.begin(); iter != items.end(); iter++, i++)		if( i == which)			return *iter;	return nullptr;}size_t CListBox::getIndexOf(CIntObject *item){	size_t i=first;	for (auto iter = items.begin(); iter != items.end(); iter++, i++)		if(*iter == item)			return i;	return size_t(-1);}void CListBox::scrollTo(size_t which){	//scroll up	if (first > which)		moveToPos(which);	//scroll down	else if (first + items.size() <= which && which < totalSize)		moveToPos(which - items.size() + 1);}void CListBox::moveToPos(size_t which){	//Calculate new position	size_t maxPossible;	if (totalSize > items.size())		maxPossible = totalSize - items.size();	else		maxPossible = 0;	size_t newPos = std::min(which, maxPossible);	//If move distance is 1 (most of calls from Slider) - use faster shifts instead of resetting all items	if (first - newPos == 1)		moveToPrev();	else if (newPos - first == 1)		moveToNext();	else if (newPos != first)	{		first = newPos;		reset();	}}void CListBox::moveToNext(){	//Remove front item and insert new one to end	if (first + items.size() < totalSize)	{		first++;		deleteItem(items.front());		items.pop_front();		items.push_back(createItem(first+items.size()));		updatePositions();	}}void CListBox::moveToPrev(){	//Remove last item and insert new one at start	if (first)	{		first--;		deleteItem(items.back());		items.pop_back();		items.push_front(createItem(first));		updatePositions();	}}size_t CListBox::getPos(){	return first;}const std::list<CIntObject *> &CListBox::getItems(){	return items;}
 |