[+] Added ImageListBox

This commit is contained in:
cybermind 2015-03-12 00:07:07 +05:00
parent 757d724302
commit 615bf481a0
8 changed files with 646 additions and 36 deletions

View file

@ -170,7 +170,7 @@ static bool MoveRandomly(CUnit &unit)
// pick random location
Vec2i pos = unit.tilePos;
pos.x += SyncRand(unit.Type->RandomMovementDistance * 2 + 1) - unit.Type->RandomMovementDistance;
pos.x += SyncRand(unit.Type->RandomMovementDistance * 2 + 1) - unit.Type->RandomMovementDistance;
pos.y += SyncRand(unit.Type->RandomMovementDistance * 2 + 1) - unit.Type->RandomMovementDistance;
// restrict to map

View file

@ -114,6 +114,7 @@ public:
void Flip();
void UseDisplayFormat();
void Resize(int w, int h);
void SetOriginalSize();
bool TransparentPixel(int x, int y);
void MakeShadow();

View file

@ -267,6 +267,21 @@ public:
virtual std::string getElementAt(int i) {return list[i];}
};
class ImageListBox : public gcn::ListBox
{
public:
ImageListBox();
ImageListBox(gcn::ListModel *listModel);
virtual void draw(gcn::Graphics *graphics);
virtual void drawBorder(gcn::Graphics *graphics);
void setItemImage(CGraphic *image) { itemImage = image; }
void adjustSize();
void mousePress(int, int y, int button);
void setSelected(int selected);
private:
CGraphic *itemImage;
};
class ListBoxWidget : public gcn::ScrollArea
{
public:
@ -284,6 +299,64 @@ private:
gcn::ListBox listbox;
};
class ImageListBoxWidget : public ListBoxWidget
{
public:
ImageListBoxWidget(unsigned int width, unsigned int height);
void setList(lua_State *lua, lua_Object *lo);
void setSelected(int i);
int getSelected() const;
virtual void setBackgroundColor(const gcn::Color &color);
virtual void setFont(gcn::Font *font);
virtual void addActionListener(gcn::ActionListener *actionListener);
void setItemImage(CGraphic *image) {
itemImage = image;
listbox.setItemImage(image);
}
void setUpButtonImage(CGraphic *image) { upButtonImage = image; }
void setDownButtonImage(CGraphic *image) { downButtonImage = image; }
void setLeftButtonImage(CGraphic *image) { leftButtonImage = image; }
void setRightButtonImage(CGraphic *image) { rightButtonImage = image; }
void setHBarImage(CGraphic *image) {
hBarButtonImage = image;
mScrollbarWidth = std::min<int>(image->getWidth(), image->getHeight());
}
void setVBarImage(CGraphic *image) {
vBarButtonImage = image;
mScrollbarWidth = std::min<int>(image->getWidth(), image->getHeight());
}
void setMarkerImage(CGraphic *image) { markerImage = image; }
virtual void draw(gcn::Graphics *graphics);
virtual void drawBorder(gcn::Graphics *graphics);
virtual gcn::Rectangle getVerticalMarkerDimension();
virtual gcn::Rectangle getHorizontalMarkerDimension();
private:
void adjustSize();
void drawUpButton(gcn::Graphics *graphics);
void drawDownButton(gcn::Graphics *graphics);
void drawLeftButton(gcn::Graphics *graphics);
void drawRightButton(gcn::Graphics *graphics);
void drawHMarker(gcn::Graphics *graphics);
void drawVMarker(gcn::Graphics *graphics);
void drawHBar(gcn::Graphics *graphics);
void drawVBar(gcn::Graphics *graphics);
private:
CGraphic *itemImage;
CGraphic *upButtonImage;
CGraphic *downButtonImage;
CGraphic *leftButtonImage;
CGraphic *rightButtonImage;
CGraphic *hBarButtonImage;
CGraphic *vBarButtonImage;
CGraphic *markerImage;
LuaListModel lualistmodel;
ImageListBox listbox;
};
class DropDownWidget : public gcn::DropDown
{
LuaListModel listmodel;

View file

@ -471,6 +471,10 @@ class ListBox : public Widget
{
};
class ImageListBox : public ListBox
{
};
class ListBoxWidget : public ScrollArea
{
ListBoxWidget(unsigned int width, unsigned int height);
@ -479,6 +483,22 @@ class ListBoxWidget : public ScrollArea
int getSelected();
};
class ImageListBoxWidget : public ListBoxWidget
{
ImageListBoxWidget(unsigned int width, unsigned int height);
void setList(lua_State *lua, lua_Object *lo);
void setSelected (int selected);
int getSelected();
void setItemImage(CGraphic *image);
void setUpButtonImage(CGraphic *image);
void setDownButtonImage(CGraphic *image);
void setLeftButtonImage(CGraphic *image);
void setRightButtonImage(CGraphic *image);
void setHBarImage(CGraphic *image);
void setVBarImage(CGraphic *image);
void setMarkerImage(CGraphic *image);
};
class Window : public BasicContainer
{
Window();

View file

@ -1277,6 +1277,129 @@ void LuaListModel::setList(lua_State *lua, lua_Object *lo)
}
}
/*----------------------------------------------------------------------------
-- ImageListBox
----------------------------------------------------------------------------*/
ImageListBox::ImageListBox() : gcn::ListBox(), itemImage(NULL)
{
}
ImageListBox::ImageListBox(gcn::ListModel *listModel) : gcn::ListBox(listModel), itemImage(NULL)
{
}
void ImageListBox::draw(gcn::Graphics *graphics)
{
if (mListModel == NULL) {
return;
}
graphics->setColor(getForegroundColor());
graphics->setFont(getFont());
int i, fontHeight;
int y = 0;
CGraphic *img = itemImage;
img->Resize(getWidth(), img->getHeight());
fontHeight = std::max<int>(getFont()->getHeight(), img->getHeight());
/**
* @todo Check cliprects so we do not have to iterate over elements in the list model
*/
for (i = 0; i < mListModel->getNumberOfElements(); ++i) {
graphics->drawImage(img, 0, 0, 0, y, getWidth(), img->getHeight());
if (i == mSelected) {
graphics->drawText("~<" + mListModel->getElementAt(i) + "~>", 1, y + (fontHeight - getFont()->getHeight()) / 2);
} else {
graphics->drawText(mListModel->getElementAt(i), 1, y + (fontHeight - getFont()->getHeight()) / 2);
}
y += fontHeight;
}
img->SetOriginalSize();
}
void ImageListBox::drawBorder(gcn::Graphics *graphics)
{
gcn::Color faceColor = getBaseColor();
gcn::Color highlightColor, shadowColor;
int alpha = getBaseColor().a;
int width = getWidth() + getBorderSize() * 2 - 1;
int height = getHeight() + getBorderSize() * 2 - 1;
highlightColor = faceColor + 0x303030;
highlightColor.a = alpha;
shadowColor = faceColor - 0x303030;
shadowColor.a = alpha;
unsigned int i;
for (i = 0; i < getBorderSize(); ++i)
{
graphics->setColor(shadowColor);
graphics->drawLine(i,i, width - i, i);
graphics->drawLine(i,i + 1, i, height - i - 1);
graphics->setColor(highlightColor);
graphics->drawLine(width - i,i + 1, width - i, height - i);
graphics->drawLine(i,height - i, width - i - 1, height - i);
}
}
void ImageListBox::adjustSize()
{
if (mListModel != NULL)
{
setHeight((itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight()) * mListModel->getNumberOfElements());
}
}
void ImageListBox::mousePress(int, int y, int button)
{
if (button == gcn::MouseInput::LEFT && hasMouse())
{
setSelected(y / (itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight()));
generateAction();
}
}
void ImageListBox::setSelected(int selected)
{
if (mListModel == NULL)
{
mSelected = -1;
}
else
{
if (selected < 0)
{
mSelected = -1;
}
else if (selected >= mListModel->getNumberOfElements())
{
mSelected = mListModel->getNumberOfElements() - 1;
}
else
{
mSelected = selected;
}
Widget *par = getParent();
if (par == NULL)
{
return;
}
gcn::ScrollArea* scrollArea = dynamic_cast<gcn::ScrollArea *>(par);
if (scrollArea != NULL)
{
gcn::Rectangle scroll;
scroll.y = (itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight()) * mSelected;
scroll.height = (itemImage ? std::max<int>(getFont()->getHeight(), itemImage->getHeight()) : getFont()->getHeight());
scrollArea->scrollToRectangle(scroll);
}
}
}
/*----------------------------------------------------------------------------
-- ListBoxWidget
@ -1295,6 +1418,19 @@ ListBoxWidget::ListBoxWidget(unsigned int width, unsigned int height)
setBackgroundColor(gcn::Color(128, 128, 128));
}
/**
** ImageListBoxWidget constructor.
**
** @todo Size should be parametrable, maybe remove default constructor?
*/
ImageListBoxWidget::ImageListBoxWidget(unsigned int width, unsigned int height) : ListBoxWidget(width, height),
upButtonImage(NULL), downButtonImage(NULL), leftButtonImage(NULL), rightButtonImage(NULL), hBarButtonImage(NULL),
vBarButtonImage(NULL), markerImage(NULL)
{
setDimension(gcn::Rectangle(0, 0, width, height));
setContent(&listbox);
}
/**
** Set the list
@ -1306,6 +1442,16 @@ void ListBoxWidget::setList(lua_State *lua, lua_Object *lo)
adjustSize();
}
/**
** Set the list
*/
void ImageListBoxWidget::setList(lua_State *lua, lua_Object *lo)
{
lualistmodel.setList(lua, lo);
listbox.setListModel(&lualistmodel);
adjustSize();
}
/**
** Sets the ListModel index of the selected element.
**
@ -1318,6 +1464,18 @@ void ListBoxWidget::setSelected(int selected)
listbox.setSelected(selected);
}
/**
** Sets the ListModel index of the selected element.
**
** @param selected The ListModel index of the selected element.
**
** @see gcn::ListBox
*/
void ImageListBoxWidget::setSelected(int selected)
{
listbox.setSelected(selected);
}
/**
** Gets the ListModel index of the selected element.
**
@ -1330,6 +1488,18 @@ int ListBoxWidget::getSelected() const
return const_cast<gcn::ListBox &>(listbox).getSelected();
}
/**
** Gets the ListModel index of the selected element.
**
** @return The ListModel index of the selected element.
**
** @see gcn::ListBox
*/
int ImageListBoxWidget::getSelected() const
{
return const_cast<ImageListBox &>(listbox).getSelected();
}
/**
** Set background color of the ListBoxWidget.
**
@ -1342,6 +1512,18 @@ void ListBoxWidget::setBackgroundColor(const gcn::Color &color)
listbox.setBackgroundColor(color);
}
/**
** Set background color of the ListBoxWidget.
**
** @param color Color to set.
*/
void ImageListBoxWidget::setBackgroundColor(const gcn::Color &color)
{
ScrollArea::setBackgroundColor(color);
ScrollArea::setBaseColor(color);
listbox.setBackgroundColor(color);
}
/**
** Set font of the ListBox.
**
@ -1354,6 +1536,18 @@ void ListBoxWidget::setFont(gcn::Font *font)
adjustSize();
}
/**
** Set font of the ListBox.
**
** @param font Font to set.
*/
void ImageListBoxWidget::setFont(gcn::Font *font)
{
listbox.setFont(font);
listbox.setWidth(getWidth());
adjustSize();
}
/**
** Adjust size of the listBox.
**
@ -1378,6 +1572,30 @@ void ListBoxWidget::adjustSize()
}
}
/**
** Adjust size of the listBox.
**
** @todo Fix width of the scroll area (depend of v-scroll or not).
*/
void ImageListBoxWidget::adjustSize()
{
int i;
int width;
gcn::ListModel *listmodel;
width = listbox.getWidth();
Assert(listbox.getListModel());
listmodel = listbox.getListModel();
for (i = 0; i < listmodel->getNumberOfElements(); ++i) {
if (width < listbox.getFont()->getWidth(listmodel->getElementAt(i))) {
width = listbox.getFont()->getWidth(listmodel->getElementAt(i));
}
}
if (width != listbox.getWidth()) {
listbox.setWidth(width);
}
}
/**
** Add an action listener
*/
@ -1386,6 +1604,288 @@ void ListBoxWidget::addActionListener(gcn::ActionListener *actionListener)
listbox.addActionListener(actionListener);
}
/**
** Add an action listener
*/
void ImageListBoxWidget::addActionListener(gcn::ActionListener *actionListener)
{
listbox.addActionListener(actionListener);
}
/**
** Draw the list box
**
** @param graphics Graphics to use
*/
void ImageListBoxWidget::draw(gcn::Graphics *graphics)
{
CGraphic *img = NULL;
// Check if we have all required graphics
if (!this->upButtonImage || !this->downButtonImage || !this->leftButtonImage || !this->rightButtonImage
|| !this->markerImage || !this->hBarButtonImage || !this->vBarButtonImage) {
fprintf(stderr, "Not all graphics for ImageListBoxWidget were set\n");
ExitFatal(1);
}
if (mVBarVisible)
{
this->drawUpButton(graphics);
this->drawDownButton(graphics);
this->drawVBar(graphics);
this->drawVMarker(graphics);
}
if (mHBarVisible)
{
this->drawLeftButton(graphics);
this->drawRightButton(graphics);
this->drawHBar(graphics);
this->drawHMarker(graphics);
}
if (mContent)
{
gcn::Rectangle contdim = mContent->getDimension();
graphics->pushClipArea(getContentDimension());
if (mContent->getBorderSize() > 0)
{
img = this->itemImage;
gcn::Rectangle rec = mContent->getDimension();
rec.x -= mContent->getBorderSize();
rec.y -= mContent->getBorderSize();
rec.width += 2 * mContent->getBorderSize();
rec.height += 2 * mContent->getBorderSize();
graphics->pushClipArea(rec);
mContent->drawBorder(graphics);
graphics->popClipArea();
}
graphics->pushClipArea(contdim);
mContent->draw(graphics);
graphics->popClipArea();
graphics->popClipArea();
}
}
/**
** Draw the list box border
**
** @param graphics Graphics to use
*/
void ImageListBoxWidget::drawBorder(gcn::Graphics *graphics)
{
gcn::Color faceColor = getBaseColor();
gcn::Color highlightColor, shadowColor;
int alpha = getBaseColor().a;
int width = getWidth() + getBorderSize() * 2 - 1;
int height = getHeight() + getBorderSize() * 2 - 1;
highlightColor = faceColor + 0x303030;
highlightColor.a = alpha;
shadowColor = faceColor - 0x303030;
shadowColor.a = alpha;
unsigned int i;
for (i = 0; i < getBorderSize(); ++i)
{
graphics->setColor(shadowColor);
graphics->drawLine(i,i, width - i, i);
graphics->drawLine(i,i + 1, i, height - i - 1);
graphics->setColor(highlightColor);
graphics->drawLine(width - i,i + 1, width - i, height - i);
graphics->drawLine(i,height - i, width - i - 1, height - i);
}
}
void ImageListBoxWidget::drawUpButton(gcn::Graphics* graphics)
{
gcn::Rectangle dim = getUpButtonDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = upButtonImage;
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
graphics->popClipArea();
}
void ImageListBoxWidget::drawDownButton(gcn::Graphics* graphics)
{
gcn::Rectangle dim = getDownButtonDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = downButtonImage;
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
graphics->popClipArea();
}
void ImageListBoxWidget::drawLeftButton(gcn::Graphics* graphics)
{
gcn::Rectangle dim = getLeftButtonDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = leftButtonImage;
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
graphics->popClipArea();
}
void ImageListBoxWidget::drawRightButton(gcn::Graphics* graphics)
{
gcn::Rectangle dim = getRightButtonDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = rightButtonImage;
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
graphics->popClipArea();
}
void ImageListBoxWidget::drawHBar(gcn::Graphics *graphics)
{
gcn::Rectangle dim = getHorizontalBarDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = hBarButtonImage;
img->Resize(dim.width, dim.height);
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
img->SetOriginalSize();
graphics->popClipArea();
}
void ImageListBoxWidget::drawVBar(gcn::Graphics *graphics)
{
gcn::Rectangle dim = getVerticalBarDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = vBarButtonImage;
img->Resize(dim.width, dim.height);
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
img->SetOriginalSize();
graphics->popClipArea();
}
void ImageListBoxWidget::drawHMarker(gcn::Graphics *graphics)
{
gcn::Rectangle dim = getHorizontalMarkerDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = markerImage;
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
graphics->popClipArea();
}
void ImageListBoxWidget::drawVMarker(gcn::Graphics *graphics)
{
gcn::Rectangle dim = getVerticalMarkerDimension();
graphics->pushClipArea(dim);
CGraphic *img = NULL;
img = markerImage;
graphics->drawImage(img, 0, 0, 0, 0, img->getWidth(), img->getHeight());
graphics->popClipArea();
}
gcn::Rectangle ImageListBoxWidget::getVerticalMarkerDimension()
{
if (!mVBarVisible)
{
return gcn::Rectangle(0, 0, 0, 0);
}
int length, pos;
gcn::Rectangle barDim = getVerticalBarDimension();
if (mContent && mContent->getHeight() != 0)
{
length = this->markerImage->getHeight();
}
else
{
length = barDim.height;
}
if (length < mScrollbarWidth)
{
length = mScrollbarWidth;
}
if (length > barDim.height)
{
length = barDim.height;
}
if (getVerticalMaxScroll() != 0)
{
pos = ((barDim.height - length) * getVerticalScrollAmount())
/ getVerticalMaxScroll();
}
else
{
pos = 0;
}
return gcn::Rectangle(barDim.x, barDim.y + pos, mScrollbarWidth, length);
}
gcn::Rectangle ImageListBoxWidget::getHorizontalMarkerDimension()
{
if (!mHBarVisible)
{
return gcn::Rectangle(0, 0, 0, 0);
}
int length, pos;
gcn::Rectangle barDim = getHorizontalBarDimension();
if (mContent && mContent->getWidth() != 0)
{
length = this->markerImage->getHeight();
}
else
{
length = barDim.width;
}
if (length < mScrollbarWidth)
{
length = mScrollbarWidth;
}
if (length > barDim.width)
{
length = barDim.width;
}
if (getHorizontalMaxScroll() != 0)
{
pos = ((barDim.width - length) * getHorizontalScrollAmount())
/ getHorizontalMaxScroll();
}
else
{
pos = 0;
}
return gcn::Rectangle(barDim.x + pos, barDim.y, length, mScrollbarWidth);
}
/*----------------------------------------------------------------------------
-- DropDownWidget

View file

@ -758,8 +758,8 @@ static int CclDefineUnitType(lua_State *l)
} else if (!strcmp(value, "SeaUnit")) {
type->SeaUnit = LuaToBoolean(l, -1);
} else if (!strcmp(value, "RandomMovementProbability")) {
type->RandomMovementProbability = LuaToNumber(l, -1);
} else if (!strcmp(value, "RandomMovementDistance")) {
type->RandomMovementProbability = LuaToNumber(l, -1);
} else if (!strcmp(value, "RandomMovementDistance")) {
type->RandomMovementDistance = LuaToNumber(l, -1);
} else if (!strcmp(value, "ClicksToExplode")) {
type->ClicksToExplode = LuaToNumber(l, -1);

View file

@ -564,8 +564,8 @@ bool CUnit::IsAlive() const
int CUnit::GetDrawLevel() const
{
return ((Type->CorpseType && CurrentAction() == UnitActionDie) ?
Type->CorpseType->DrawLevel :
return ((Type->CorpseType && CurrentAction() == UnitActionDie) ?
Type->CorpseType->DrawLevel :
((CurrentAction() == UnitActionDie) ? Type->DrawLevel - 10 : Type->DrawLevel));;
}

View file

@ -1206,37 +1206,7 @@ void CGraphic::Resize(int w, int h)
// Resizing the same image multiple times looks horrible
// If the image has already been resized then get a clean copy first
if (Resized) {
if (Surface) {
FreeSurface(&Surface);
Surface = NULL;
}
delete[] frame_map;
frame_map = NULL;
#if defined(USE_OPENGL) || defined(USE_GLES)
if (!UseOpenGL)
#endif
{
if (SurfaceFlip) {
FreeSurface(&SurfaceFlip);
SurfaceFlip = NULL;
}
delete[] frameFlip_map;
frameFlip_map = NULL;
}
#if defined(USE_OPENGL) || defined(USE_GLES)
if (UseOpenGL && Textures) {
glDeleteTextures(NumTextures, Textures);
delete[] Textures;
Textures = NULL;
}
#endif
this->Width = this->Height = 0;
this->Surface = NULL;
this->Load();
Resized = false;
this->SetOriginalSize();
if (GraphicWidth == w && GraphicHeight == h) {
return;
}
@ -1353,6 +1323,52 @@ void CGraphic::Resize(int w, int h)
GenFramesMap();
}
/**
** Sets the original size for a graphic
**
*/
void CGraphic::SetOriginalSize()
{
Assert(Surface); // can't resize before it's been loaded
if (!Resized) {
return;
}
if (Surface) {
FreeSurface(&Surface);
Surface = NULL;
}
delete[] frame_map;
frame_map = NULL;
#if defined(USE_OPENGL) || defined(USE_GLES)
if (!UseOpenGL)
#endif
{
if (SurfaceFlip) {
FreeSurface(&SurfaceFlip);
SurfaceFlip = NULL;
}
delete[] frameFlip_map;
frameFlip_map = NULL;
}
#if defined(USE_OPENGL) || defined(USE_GLES)
if (UseOpenGL && Textures) {
glDeleteTextures(NumTextures, Textures);
delete[] Textures;
Textures = NULL;
}
#endif
this->Width = this->Height = 0;
this->Surface = NULL;
this->Load();
Resized = false;
}
/**
** Check if a pixel is transparent
**