diff --git a/code/nel/include/nel/gui/view_bitmap_combo.h b/code/nel/include/nel/gui/view_bitmap_combo.h new file mode 100644 index 000000000..5a992a588 --- /dev/null +++ b/code/nel/include/nel/gui/view_bitmap_combo.h @@ -0,0 +1,174 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + + + +#ifndef NL_VIEW_BITMAP_COMBO_H +#define NL_VIEW_BITMAP_COMBO_H + +#include "nel/misc/cdb.h" +#include "nel/gui/view_base.h" +#include "nel/3d/u_texture.h" +#include +#include + +namespace NLGUI +{ + + /** Description of a combo box, this can be parsed from an xml node + * The bitmap layout is as follow : + * + * I W I W I W + * t G t G t G + * e a e a e a + * m p m p m p + * W S W W + * i e i i + * d l d d + * t e t t + * h c h h + * t + * e + * d + * +----+---+----+---+---+---+---+--... + * |ssss| |****| |***| |***| + * ItemHeight |ssss| |****| |***| |*** + * +----+---+----+---+---+---+---+--... + * | | | | | | | | + * HGapSeleted | | | | | | | | + * +----+---+----+---+---+---+---+--... + * |****| |****| |***| |***| + * ItemHeight |****| |****| |***| |***| + * +----+---+----+---+---+---+---+--... + * | | | | | | | | + * HGap | | | | | | | | + * +----+---+----+---+---+---+---+--... + * |****| |****| |***| |***| + * ItemHeight |****| |****| |***| |***| + * . . . . . . . . + * . . . . . . . . + * s : selected item. . . . . . . + * * : where bitmap are displayed + */ + + + struct CComboBoxDesc + { + bool parse(xmlNodePtr cur, CInterfaceElement *owner); + void addObserver(NLMISC::ICDBNode::IPropertyObserver *obs); + void getGridSize(uint &numRow,uint &numCol) const; + void getDimensions(uint &width, uint &height) const; + CInterfaceProperty NumRow; + CInterfaceProperty NumCol; + CInterfaceProperty CurrSelected; + CInterfaceProperty ItemWidth; + CInterfaceProperty ItemHeight; + CInterfaceProperty Unrolled; + CInterfaceProperty WGapSelected; + CInterfaceProperty WGap; + CInterfaceProperty HGapSelected; + CInterfaceProperty HGap; + CInterfaceProperty NumSel; + CInterfaceProperty Align; + + }; + + + + + /** + * A combo box with several bitmaps in it + * \author Nicolas Vizerie + * \author Nevrax France + * \date 2002 + */ + class CViewBitmapCombo : public CViewBase, public NLMISC::ICDBNode::IPropertyObserver + { + public: + typedef std::vector TIdArray; + typedef std::vector TStringArray; + typedef std::vector TColorArray; + public: + /// ctor + CViewBitmapCombo(const TCtorParam ¶m); + /** + * parse an xml node and initialize the base view members. Must call CViewBase::parse + * \param cur : pointer to the xml node to be parsed + * \param parentGroup : the parent group of the view + * \partam id : a refence to the string that will receive the view ID + * \return true if success + */ + bool parse(xmlNodePtr cur,CInterfaceGroup * parentGroup); + virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } + /** + * draw the view + */ + void draw(); + + // access to texture & colors + const TStringArray &getTexs() const { return _Texs; } + const TStringArray &getTexsOver() const { return _TexsOver; } + const TStringArray &getTexsPushed() const { return _TexsPushed; } + // + const TColorArray &getColors() const { return _Col; } + const TColorArray &getColorsOver() const { return _ColOver; } + const TColorArray &getColorsPushed() const { return _ColPushed; } + // + void setTexs(const char * const tex[], uint numTex); + void setTexsOver(const char * const tex[], uint numTex); + void setTexsPushed(const char * const tex[], uint numTex); + // + void setColors(const NLMISC::CRGBA colors[], uint numColors); + void setColorsOver(const NLMISC::CRGBA colors[], uint numColors); + void setColorsPushed(const NLMISC::CRGBA colors[], uint numColors); + + + + + + + + /////////////////////////////////////////////////////////////////////////////////// + private: + // + TStringArray _Texs; + TStringArray _TexsOver; + TStringArray _TexsPushed; + TIdArray _TexsId; + TIdArray _TexsOverId; + TIdArray _TexsPushedId; + TColorArray _Col; + TColorArray _ColOver; + TColorArray _ColPushed; + CComboBoxDesc _CD; + CInterfaceElement *_Owner; + private: + void parseTexList(const std::string &names, TStringArray &dest); + void parseColList(const std::string &names, TColorArray &dest); + void setupSize(); + void getDimensions(uint &numRow, uint &numCol); + // From ICDBNode::IPropertyObserver + void update(NLMISC::ICDBNode *leaf); + // Return a color from the array, or white if it is empty + static NLMISC::CRGBA getCol(const TColorArray &array, uint index); + static const std::string *getTex(const TStringArray &array, uint index); + static sint32 getTexId(const TIdArray &array, uint index); + }; + +} + +#endif diff --git a/code/nel/src/gui/view_bitmap_combo.cpp b/code/nel/src/gui/view_bitmap_combo.cpp new file mode 100644 index 000000000..a13bf9364 --- /dev/null +++ b/code/nel/src/gui/view_bitmap_combo.cpp @@ -0,0 +1,585 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "nel/gui/view_bitmap_combo.h" +#include "nel/misc/xml_auto_ptr.h" +#include "nel/gui/db_manager.h" +#include "nel/gui/view_renderer.h" +#include "nel/gui/widget_manager.h" +#include "nel/gui/view_pointer_base.h" +#include "nel/gui/interface_group.h" + +using namespace NLMISC; + +namespace NLGUI +{ + + //======================================================================================= + bool CComboBoxDesc::parse(xmlNodePtr cur, CInterfaceElement*owner) + { + nlassert(owner); + const std::string &ownerId = owner->getId(); + CXMLAutoPtr prop; + // + prop = xmlGetProp(cur, (const xmlChar *) "selected"); + if (!prop) + { + nlwarning((ownerId + " : Couldn't read 'selected' field").c_str()); + return false; + } + owner->relativeSInt64Read(CurrSelected, "selected", prop, "0"); + // + prop = xmlGetProp(cur, (const xmlChar *) "num_row"); + owner->relativeSInt64Read(NumRow, "num_row", prop, "1"); + // + prop = xmlGetProp(cur, (const xmlChar *) "num_col"); + owner->relativeSInt64Read(NumCol, "num_col", prop, "1"); + // + prop = xmlGetProp(cur, (const xmlChar *) "itemw"); + owner->relativeSInt64Read(ItemWidth, "itemw", prop, "32"); + // + prop = xmlGetProp(cur, (const xmlChar *) "itemh"); + owner->relativeSInt64Read(ItemHeight, "itemh", prop, "32"); + // + prop = xmlGetProp(cur, (const xmlChar *) "unrolled"); + owner->relativeBoolRead(Unrolled, "unrolled", prop, "false"); + // + prop = xmlGetProp(cur, (xmlChar *) "wgap"); + owner->relativeSInt64Read(WGap, "wgap", prop, "0"); + // + prop = xmlGetProp(cur, (xmlChar *) "hgap"); + owner->relativeSInt64Read(HGap, "hgap", prop, "0"); + // + prop = xmlGetProp(cur, (xmlChar *) "wgap_selected"); + owner->relativeSInt64Read(WGapSelected, "wgap_selected", prop, "0"); + // + prop = xmlGetProp(cur, (xmlChar *) "hgap_selected"); + owner->relativeSInt64Read(HGapSelected, "hgap_selected", prop, "0"); + // + // + prop = xmlGetProp(cur, (xmlChar *) "num_sel"); + owner->relativeSInt64Read(NumSel, "num_sel", prop, "1"); + // + prop = (char*) xmlGetProp (cur, (xmlChar*)"align"); + Align.readSInt32 ("0", ownerId + ":align"); + if (prop) + { + const char *seekPtr = prop.getDatas(); + while (*seekPtr != 0) + { + if ((*seekPtr=='l')||(*seekPtr=='L')) + { + Align.setSInt32 (Align.getSInt32()&(~1)); + } + if ((*seekPtr=='r')||(*seekPtr=='R')) + { + Align.setSInt32 (Align.getSInt32()|1); + } + if ((*seekPtr=='b')||(*seekPtr=='B')) + { + Align.setSInt32 (Align.getSInt32()&(~2)); + } + if ((*seekPtr=='t')||(*seekPtr=='T')) + { + Align.setSInt32 (Align.getSInt32()|2); + } + ++seekPtr; + } + } + // + return true; + } + + + //========================================================================================= + void CComboBoxDesc::addObserver(ICDBNode::IPropertyObserver *obs) + { + // Add observers on dimensions + if (NumRow.getNodePtr()) + { + ICDBNode::CTextId textId; + NumRow.getNodePtr()->addObserver(obs, textId); + } + if (NumCol.getNodePtr()) + { + ICDBNode::CTextId textId; + NumCol.getNodePtr()->addObserver(obs, textId); + } + if (ItemWidth.getNodePtr()) + { + ICDBNode::CTextId textId; + ItemWidth.getNodePtr()->addObserver(obs, textId); + } + if (ItemHeight.getNodePtr()) + { + ICDBNode::CTextId textId; + ItemHeight.getNodePtr()->addObserver(obs, textId); + } + if (Unrolled.getNodePtr()) + { + ICDBNode::CTextId textId; + Unrolled.getNodePtr()->addObserver(obs, textId); + } + } + + //======================================================================================= + void CComboBoxDesc::getGridSize(uint &numRow, uint &numCol) const + { + numRow = NumRow.getSInt32(); + numCol = NumCol.getSInt32(); + if (numRow == 0 || numCol == 0) return; + if (!Unrolled.getBool()) + { + numRow = numCol = 1; + } + } + + //======================================================================================= + void CComboBoxDesc::getDimensions(uint &w, uint &h) const + { + uint numRow, numCol; + getGridSize(numRow, numCol); + w = numCol * (ItemWidth.getSInt32() + WGap.getSInt32()); + h = numRow * (ItemHeight.getSInt32() + HGap.getSInt32()); + // + if (numCol == 1) w -= WGap.getSInt32(); + else w += WGapSelected.getSInt32() - WGap.getSInt32(); + // + if (numRow == 1) h -= HGap.getSInt32(); + else h += HGapSelected.getSInt32() - HGap.getSInt32(); + } + + //======================================================================================= + NLMISC_REGISTER_OBJECT(CViewBase, CViewBitmapCombo, std::string, "bitmap_combo"); + + CViewBitmapCombo::CViewBitmapCombo(const TCtorParam ¶m) : CViewBase(param) + { + } + + + //======================================================================================= + bool CViewBitmapCombo::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) + { + if (! CViewBase::parse(cur, parentGroup) ) + { + parseError(parentGroup); + return false; + } + + CXMLAutoPtr prop; + + std::string texs; + prop = xmlGetProp(cur, (xmlChar *)"tx_normal"); + if (prop) texs = (const char*)prop; + std::string texsOver; + prop = xmlGetProp(cur, (xmlChar *)"tx_over"); + if (prop) texsOver = (const char*)prop; + std::string texsPushed; + prop = xmlGetProp(cur, (xmlChar *)"tx_pushed"); + if (prop) texsPushed = (const char*)prop; + // + // for colors, an empty strings means all colors are white + // + std::string col; + prop = xmlGetProp(cur, (xmlChar *)"col_normal"); + if (prop) col = (const char*)prop; + std::string colOver; + prop = xmlGetProp(cur, (xmlChar *)"col_over"); + if (prop) colOver = (const char*)prop; + std::string colPushed; + prop = xmlGetProp(cur, (xmlChar *)"col_pushed"); + if (prop) colPushed = (const char*)prop; + + /* if (texs.empty() || texsOver.empty() || texsPushed.empty()) + { + parseError(parentGroup, "Cannot read tx_normal, tx_over, or tx_pushed"); + return false; + }*/ + + parseTexList(texs, _Texs); + parseTexList(texsOver, _TexsOver); + parseTexList(texsPushed, _TexsPushed); + + parseColList(col, _Col); + parseColList(colOver, _ColOver); + parseColList(colPushed, _ColPushed); + // + /* if (_Texs.size() != _TexsOver.size() || _TexsOver.size() != _TexsPushed.size()) + { + parseError(parentGroup, "Texture names arrays do not have the same size"); + return false; + } + // + uint numCols = NLMISC::maxof(_Col.size(), _ColOver.size(), _ColPushed.size()); + if (! + ( + (_Col.empty() || _Col.size() == numCols) + && (_ColOver.empty() || _ColOver.size() == numCols) + && (_ColPushed.empty() || _ColPushed.size() == numCols) + ) + ) + { + parseError(parentGroup, "Color names arrays do not have the same size (note an empty array is valid, means all color are 255 255 255"); + return false; + }*/ + // + if (!_CD.parse(cur, this)) + { + return false; + } + // + setupSize(); + // + _CD.addObserver(this); + + return true; + } + + //======================================================================================= + NLMISC::CRGBA CViewBitmapCombo::getCol(const CViewBitmapCombo::TColorArray &array,uint index) + { + if (array.empty()) return CRGBA::White; + return array[index % array.size()]; + } + + //======================================================================================= + const std::string *CViewBitmapCombo::getTex(const TStringArray &array,uint index) + { + if (array.empty()) return NULL; + return &array[index % array.size()]; + } + + //======================================================================================= + sint32 CViewBitmapCombo::getTexId(const TIdArray &array, uint index) + { + if (array.empty()) return -1; + return array[index % array.size()]; + } + + //======================================================================================= + void CViewBitmapCombo::draw() + { + if (_Texs.empty()) return; + uint numRow, numCol; + _CD.getGridSize(numRow, numCol); + if (numRow == 0 || numCol == 0) return; + + sint32 mx = 0, my = 0; + CViewRenderer &rVR = *CViewRenderer::getInstance(); + const std::vector &rVB = CWidgetManager::getInstance()->getViewsUnderPointer(); + if (!CWidgetManager::getInstance()->getPointer()) return; + CWidgetManager::getInstance()->getPointer()->getPointerDispPos(mx, my); + bool over = false; + uint32 i; + for (i = 0; i < rVB.size(); ++i) + { + if (rVB[i] == this) + { + over = true; + break; + } + } + + if (_TexsId.size() == 0) + { + for (i = 0; i < _Texs.size(); ++i) + _TexsId.push_back(rVR.getTextureIdFromName(_Texs[i])); + for (i = 0; i < _TexsOver.size(); ++i) + _TexsOverId.push_back(rVR.getTextureIdFromName(_TexsOver[i])); + for (i = 0; i < _TexsPushed.size(); ++i) + _TexsPushedId.push_back(rVR.getTextureIdFromName(_TexsPushed[i])); + } + + sint32 textId; + CRGBA color; + uint selectedTexIndex = _CD.CurrSelected.getSInt32(); + uint itemw = _CD.ItemWidth.getSInt32() + _CD.WGap.getSInt32(); + uint itemh = _CD.ItemHeight.getSInt32() + _CD.HGap.getSInt32(); + uint counter = 0; + + bool overItem = false; + for(uint x = 0; x < numCol; ++x) + { + for(uint y = 0; y < numRow; ++y) + { + uint texIndex = counter; + if (counter != 0) + { + if (counter == selectedTexIndex) + { + texIndex = 0; + } + sint px; + sint py; + // get the right position depending on alignment + if (_CD.Align.getSInt32() & 1) // right align ? + { + px = _XReal + _WReal - (x + 1) * itemw; + } + else + { + px = _XReal + x * itemw; + } + // top align ? + if (_CD.Align.getSInt32() & 2) + { + py = _YReal + _HReal - (y + 1) * itemh; + } + else + { + py = _YReal + y * itemh; + } + + if (x != 0) + { + if (_CD.Align.getSInt32() & 1) + px -= _CD.WGapSelected.getSInt32() - _CD.WGap.getSInt32(); + else px += _CD.WGapSelected.getSInt32() - _CD.WGap.getSInt32(); + } + if (y != 0) + { + if (_CD.Align.getSInt32() & 2) + py -= _CD.HGapSelected.getSInt32() - _CD.HGap.getSInt32(); + else py += _CD.HGapSelected.getSInt32() - _CD.HGap.getSInt32(); + } + // is the mouse on current item ? + if (over + && mx >= px + && my >= py + && mx < px + (sint32) itemw + && my < py + (sint32) itemh) + { + overItem = true; + if ( CWidgetManager::getInstance()->getPointer()->getButtonState() & NLMISC::leftButton) + { + textId = getTexId(_TexsPushedId, texIndex); + color = getCol(_ColPushed, texIndex); + } + else + { + textId = getTexId(_TexsOverId, texIndex); + color = getCol(_ColOver, texIndex); + } + } + else + { + textId = getTexId(_TexsId, texIndex); + color = getCol(_Col, texIndex); + } + CViewRenderer::getInstance()->drawRotFlipBitmap (_RenderLayer, px, py, itemw, itemh, 0, false, + textId, + color); + } + ++counter; + if ((sint32) counter == _CD.NumSel.getSInt32()) + break; + } + } + + if ((sint32) selectedTexIndex >= _CD.NumSel.getSInt32()) + { + return; + } + + // draw current selection + sint32 px; + sint32 py; + // + if (_CD.Align.getSInt32() & 1) + { + px = _XReal + _WReal - itemw; + } + else + { + px = _XReal; + } + // + if (_CD.Align.getSInt32() & 2) + { + py = _YReal + _HReal - itemh; + } + else + { + py = _YReal; + } + // + if (_CD.Unrolled.getBool()) + { + if (overItem && CWidgetManager::getInstance()->getPointer()->getButtonState() & NLMISC::leftButton) + { + textId = getTexId(_TexsId, selectedTexIndex); + color = getCol(_Col, selectedTexIndex); + } + else + { + textId = getTexId(_TexsPushedId, selectedTexIndex); + color = getCol(_ColPushed, selectedTexIndex); + } + } + else + { + if (over + && mx >= px + && my >= py + && mx < px + (sint32) itemw + && my < py + (sint32) itemh + ) + { + if ( CWidgetManager::getInstance()->getPointer()->getButtonState() & NLMISC::leftButton) + { + textId = getTexId(_TexsPushedId, selectedTexIndex); + color = getCol(_ColPushed, selectedTexIndex); + } + else + { + textId = getTexId(_TexsOverId, selectedTexIndex); + color = getCol(_ColOver, selectedTexIndex); + } + } + else + { + textId = getTexId(_TexsId, selectedTexIndex); + color = getCol(_Col, selectedTexIndex); + } + } + + CViewRenderer::getInstance()->drawRotFlipBitmap (_RenderLayer, px, py, itemw, itemh, 0, false, + textId, + color); + } + + //======================================================================================= + void CViewBitmapCombo::parseTexList(const std::string &names, TStringArray &dest) + { + static const char sep[] = " ,\t"; + std::string::size_type pos = 0, nextPos; + dest.clear(); + do + { + nextPos = names.find_first_of(sep, pos); + if (pos != nextPos) + { + dest.push_back(names.substr(pos, nextPos - pos)); + } + pos = names.find_first_not_of(sep, nextPos); + } + while (pos != std::string::npos); + } + + //======================================================================================= + void CViewBitmapCombo::parseColList(const std::string &names,TColorArray &dest) + { + static const char sep[] = ",\t"; + std::string::size_type pos = 0, nextPos; + dest.clear(); + std::string col; + do + { + nextPos = names.find_first_of(sep, pos); + if (pos != nextPos) + { + col = names.substr(pos, nextPos - pos); + int r = 0, g = 0, b = 0, a = 255; + sscanf (col.c_str(), "%d %d %d %d", &r, &g, &b, &a); + NLMISC::clamp (r, 0, 255); + NLMISC::clamp (g, 0, 255); + NLMISC::clamp (b, 0, 255); + NLMISC::clamp (a, 0, 255); + dest.push_back(NLMISC::CRGBA((uint8) r, (uint8) g, (uint8) b, (uint8) a)); + } + pos = names.find_first_not_of(sep, nextPos); + } + while (pos != std::string::npos); + } + + //======================================================================================= + void CViewBitmapCombo::setupSize() + { + uint w, h; + _CD.getDimensions(w, h); + setW(w); + setH(h); + invalidateCoords(); + } + + //======================================================================================= + void CViewBitmapCombo::update(ICDBNode * /* leaf */) + { + setupSize(); + } + + + //======================================================================================= + /** copy an array of char * into an array of strings + */ + static void copyStrArrayFromChar(CViewBitmapCombo::TStringArray &dest, const char * const src[], uint numColor) + { + dest.resize(numColor); + for(uint k = 0; k < numColor; ++k) + { + dest[k] = src[k]; + } + } + + + static void copyRGBAVectorFromRGBAArray(CViewBitmapCombo::TColorArray &dest, const NLMISC::CRGBA src[], uint numColor) + { + dest.resize(numColor); + std::copy(src, src + numColor, dest.begin()); + } + + + //======================================================================================= + void CViewBitmapCombo::setTexs(const char * const tex[], uint numTex) + { + copyStrArrayFromChar(_Texs, tex, numTex); + } + + //======================================================================================= + void CViewBitmapCombo::setTexsOver(const char * const tex[], uint numTex) + { + copyStrArrayFromChar(_TexsOver, tex, numTex); + } + + + //======================================================================================= + void CViewBitmapCombo::setTexsPushed(const char * const tex[], uint numTex) + { + copyStrArrayFromChar(_TexsPushed, tex, numTex); + } + + //======================================================================================= + void CViewBitmapCombo::setColors(const NLMISC::CRGBA colors[], uint numColors) + { + copyRGBAVectorFromRGBAArray(_Col, colors, numColors); + } + + + //======================================================================================= + void CViewBitmapCombo::setColorsOver(const NLMISC::CRGBA colors[], uint numColors) + { + copyRGBAVectorFromRGBAArray(_ColOver, colors, numColors); + } + + + //======================================================================================= + void CViewBitmapCombo::setColorsPushed(const NLMISC::CRGBA colors[], uint numColors) + { + copyRGBAVectorFromRGBAArray(_ColPushed, colors, numColors); + } + +} + diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 65e7b6d2d..e9fbab649 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -49,7 +49,7 @@ #include "nel/gui/view_bitmap.h" //#include "view_bitmap_progress.h" #include "view_bitmap_faber_mp.h" -#include "view_bitmap_combo.h" +#include "nel/gui/view_bitmap_combo.h" #include "nel/gui/view_text.h" #include "nel/gui/view_text_id.h" #include "nel/gui/view_text_formated.h" diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp index d593b1000..1203d66b4 100644 --- a/code/ryzom/client/src/interface_v3/interface_parser.cpp +++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp @@ -38,7 +38,7 @@ // View #include "nel/gui/view_bitmap.h" #include "view_bitmap_faber_mp.h" -#include "view_bitmap_combo.h" +#include "nel/gui/view_bitmap_combo.h" #include "nel/gui/view_text.h" #include "nel/gui/view_text_formated.h" #include "nel/gui/view_text_id.h" diff --git a/code/ryzom/client/src/interface_v3/view_bitmap_combo.cpp b/code/ryzom/client/src/interface_v3/view_bitmap_combo.cpp deleted file mode 100644 index c4f230129..000000000 --- a/code/ryzom/client/src/interface_v3/view_bitmap_combo.cpp +++ /dev/null @@ -1,579 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "view_bitmap_combo.h" -#include "nel/misc/xml_auto_ptr.h" -#include "nel/gui/db_manager.h" -#include "nel/gui/view_renderer.h" -#include "nel/gui/widget_manager.h" -#include "nel/gui/view_pointer_base.h" -#include "nel/gui/interface_group.h" - -using namespace NLMISC; - -//======================================================================================= -bool CComboBoxDesc::parse(xmlNodePtr cur, CInterfaceElement*owner) -{ - nlassert(owner); - const std::string &ownerId = owner->getId(); - CXMLAutoPtr prop; - // - prop = xmlGetProp(cur, (const xmlChar *) "selected"); - if (!prop) - { - nlwarning((ownerId + " : Couldn't read 'selected' field").c_str()); - return false; - } - owner->relativeSInt64Read(CurrSelected, "selected", prop, "0"); - // - prop = xmlGetProp(cur, (const xmlChar *) "num_row"); - owner->relativeSInt64Read(NumRow, "num_row", prop, "1"); - // - prop = xmlGetProp(cur, (const xmlChar *) "num_col"); - owner->relativeSInt64Read(NumCol, "num_col", prop, "1"); - // - prop = xmlGetProp(cur, (const xmlChar *) "itemw"); - owner->relativeSInt64Read(ItemWidth, "itemw", prop, "32"); - // - prop = xmlGetProp(cur, (const xmlChar *) "itemh"); - owner->relativeSInt64Read(ItemHeight, "itemh", prop, "32"); - // - prop = xmlGetProp(cur, (const xmlChar *) "unrolled"); - owner->relativeBoolRead(Unrolled, "unrolled", prop, "false"); - // - prop = xmlGetProp(cur, (xmlChar *) "wgap"); - owner->relativeSInt64Read(WGap, "wgap", prop, "0"); - // - prop = xmlGetProp(cur, (xmlChar *) "hgap"); - owner->relativeSInt64Read(HGap, "hgap", prop, "0"); - // - prop = xmlGetProp(cur, (xmlChar *) "wgap_selected"); - owner->relativeSInt64Read(WGapSelected, "wgap_selected", prop, "0"); - // - prop = xmlGetProp(cur, (xmlChar *) "hgap_selected"); - owner->relativeSInt64Read(HGapSelected, "hgap_selected", prop, "0"); - // - // - prop = xmlGetProp(cur, (xmlChar *) "num_sel"); - owner->relativeSInt64Read(NumSel, "num_sel", prop, "1"); - // - prop = (char*) xmlGetProp (cur, (xmlChar*)"align"); - Align.readSInt32 ("0", ownerId + ":align"); - if (prop) - { - const char *seekPtr = prop.getDatas(); - while (*seekPtr != 0) - { - if ((*seekPtr=='l')||(*seekPtr=='L')) - { - Align.setSInt32 (Align.getSInt32()&(~1)); - } - if ((*seekPtr=='r')||(*seekPtr=='R')) - { - Align.setSInt32 (Align.getSInt32()|1); - } - if ((*seekPtr=='b')||(*seekPtr=='B')) - { - Align.setSInt32 (Align.getSInt32()&(~2)); - } - if ((*seekPtr=='t')||(*seekPtr=='T')) - { - Align.setSInt32 (Align.getSInt32()|2); - } - ++seekPtr; - } - } - // - return true; -} - - -//========================================================================================= -void CComboBoxDesc::addObserver(ICDBNode::IPropertyObserver *obs) -{ - // Add observers on dimensions - if (NumRow.getNodePtr()) - { - ICDBNode::CTextId textId; - NumRow.getNodePtr()->addObserver(obs, textId); - } - if (NumCol.getNodePtr()) - { - ICDBNode::CTextId textId; - NumCol.getNodePtr()->addObserver(obs, textId); - } - if (ItemWidth.getNodePtr()) - { - ICDBNode::CTextId textId; - ItemWidth.getNodePtr()->addObserver(obs, textId); - } - if (ItemHeight.getNodePtr()) - { - ICDBNode::CTextId textId; - ItemHeight.getNodePtr()->addObserver(obs, textId); - } - if (Unrolled.getNodePtr()) - { - ICDBNode::CTextId textId; - Unrolled.getNodePtr()->addObserver(obs, textId); - } -} - -//======================================================================================= -void CComboBoxDesc::getGridSize(uint &numRow, uint &numCol) const -{ - numRow = NumRow.getSInt32(); - numCol = NumCol.getSInt32(); - if (numRow == 0 || numCol == 0) return; - if (!Unrolled.getBool()) - { - numRow = numCol = 1; - } -} - -//======================================================================================= -void CComboBoxDesc::getDimensions(uint &w, uint &h) const -{ - uint numRow, numCol; - getGridSize(numRow, numCol); - w = numCol * (ItemWidth.getSInt32() + WGap.getSInt32()); - h = numRow * (ItemHeight.getSInt32() + HGap.getSInt32()); - // - if (numCol == 1) w -= WGap.getSInt32(); - else w += WGapSelected.getSInt32() - WGap.getSInt32(); - // - if (numRow == 1) h -= HGap.getSInt32(); - else h += HGapSelected.getSInt32() - HGap.getSInt32(); -} - -//======================================================================================= -NLMISC_REGISTER_OBJECT(CViewBase, CViewBitmapCombo, std::string, "bitmap_combo"); - -CViewBitmapCombo::CViewBitmapCombo(const TCtorParam ¶m) : CViewBase(param) -{ -} - - -//======================================================================================= -bool CViewBitmapCombo::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) -{ - if (! CViewBase::parse(cur, parentGroup) ) - { - parseError(parentGroup); - return false; - } - - CXMLAutoPtr prop; - - std::string texs; - prop = xmlGetProp(cur, (xmlChar *)"tx_normal"); - if (prop) texs = (const char*)prop; - std::string texsOver; - prop = xmlGetProp(cur, (xmlChar *)"tx_over"); - if (prop) texsOver = (const char*)prop; - std::string texsPushed; - prop = xmlGetProp(cur, (xmlChar *)"tx_pushed"); - if (prop) texsPushed = (const char*)prop; - // - // for colors, an empty strings means all colors are white - // - std::string col; - prop = xmlGetProp(cur, (xmlChar *)"col_normal"); - if (prop) col = (const char*)prop; - std::string colOver; - prop = xmlGetProp(cur, (xmlChar *)"col_over"); - if (prop) colOver = (const char*)prop; - std::string colPushed; - prop = xmlGetProp(cur, (xmlChar *)"col_pushed"); - if (prop) colPushed = (const char*)prop; - -/* if (texs.empty() || texsOver.empty() || texsPushed.empty()) - { - parseError(parentGroup, "Cannot read tx_normal, tx_over, or tx_pushed"); - return false; - }*/ - - parseTexList(texs, _Texs); - parseTexList(texsOver, _TexsOver); - parseTexList(texsPushed, _TexsPushed); - - parseColList(col, _Col); - parseColList(colOver, _ColOver); - parseColList(colPushed, _ColPushed); - // -/* if (_Texs.size() != _TexsOver.size() || _TexsOver.size() != _TexsPushed.size()) - { - parseError(parentGroup, "Texture names arrays do not have the same size"); - return false; - } - // - uint numCols = NLMISC::maxof(_Col.size(), _ColOver.size(), _ColPushed.size()); - if (! - ( - (_Col.empty() || _Col.size() == numCols) - && (_ColOver.empty() || _ColOver.size() == numCols) - && (_ColPushed.empty() || _ColPushed.size() == numCols) - ) - ) - { - parseError(parentGroup, "Color names arrays do not have the same size (note an empty array is valid, means all color are 255 255 255"); - return false; - }*/ - // - if (!_CD.parse(cur, this)) - { - return false; - } - // - setupSize(); - // - _CD.addObserver(this); - - return true; -} - -//======================================================================================= -NLMISC::CRGBA CViewBitmapCombo::getCol(const CViewBitmapCombo::TColorArray &array,uint index) -{ - if (array.empty()) return CRGBA::White; - return array[index % array.size()]; -} - -//======================================================================================= -const std::string *CViewBitmapCombo::getTex(const TStringArray &array,uint index) -{ - if (array.empty()) return NULL; - return &array[index % array.size()]; -} - -//======================================================================================= -sint32 CViewBitmapCombo::getTexId(const TIdArray &array, uint index) -{ - if (array.empty()) return -1; - return array[index % array.size()]; -} - -//======================================================================================= -void CViewBitmapCombo::draw() -{ - if (_Texs.empty()) return; - uint numRow, numCol; - _CD.getGridSize(numRow, numCol); - if (numRow == 0 || numCol == 0) return; - - sint32 mx = 0, my = 0; - CViewRenderer &rVR = *CViewRenderer::getInstance(); - const std::vector &rVB = CWidgetManager::getInstance()->getViewsUnderPointer(); - if (!CWidgetManager::getInstance()->getPointer()) return; - CWidgetManager::getInstance()->getPointer()->getPointerDispPos(mx, my); - bool over = false; - uint32 i; - for (i = 0; i < rVB.size(); ++i) - { - if (rVB[i] == this) - { - over = true; - break; - } - } - - if (_TexsId.size() == 0) - { - for (i = 0; i < _Texs.size(); ++i) - _TexsId.push_back(rVR.getTextureIdFromName(_Texs[i])); - for (i = 0; i < _TexsOver.size(); ++i) - _TexsOverId.push_back(rVR.getTextureIdFromName(_TexsOver[i])); - for (i = 0; i < _TexsPushed.size(); ++i) - _TexsPushedId.push_back(rVR.getTextureIdFromName(_TexsPushed[i])); - } - - sint32 textId; - CRGBA color; - uint selectedTexIndex = _CD.CurrSelected.getSInt32(); - uint itemw = _CD.ItemWidth.getSInt32() + _CD.WGap.getSInt32(); - uint itemh = _CD.ItemHeight.getSInt32() + _CD.HGap.getSInt32(); - uint counter = 0; - - bool overItem = false; - for(uint x = 0; x < numCol; ++x) - { - for(uint y = 0; y < numRow; ++y) - { - uint texIndex = counter; - if (counter != 0) - { - if (counter == selectedTexIndex) - { - texIndex = 0; - } - sint px; - sint py; - // get the right position depending on alignment - if (_CD.Align.getSInt32() & 1) // right align ? - { - px = _XReal + _WReal - (x + 1) * itemw; - } - else - { - px = _XReal + x * itemw; - } - // top align ? - if (_CD.Align.getSInt32() & 2) - { - py = _YReal + _HReal - (y + 1) * itemh; - } - else - { - py = _YReal + y * itemh; - } - - if (x != 0) - { - if (_CD.Align.getSInt32() & 1) - px -= _CD.WGapSelected.getSInt32() - _CD.WGap.getSInt32(); - else px += _CD.WGapSelected.getSInt32() - _CD.WGap.getSInt32(); - } - if (y != 0) - { - if (_CD.Align.getSInt32() & 2) - py -= _CD.HGapSelected.getSInt32() - _CD.HGap.getSInt32(); - else py += _CD.HGapSelected.getSInt32() - _CD.HGap.getSInt32(); - } - // is the mouse on current item ? - if (over - && mx >= px - && my >= py - && mx < px + (sint32) itemw - && my < py + (sint32) itemh) - { - overItem = true; - if ( CWidgetManager::getInstance()->getPointer()->getButtonState() & NLMISC::leftButton) - { - textId = getTexId(_TexsPushedId, texIndex); - color = getCol(_ColPushed, texIndex); - } - else - { - textId = getTexId(_TexsOverId, texIndex); - color = getCol(_ColOver, texIndex); - } - } - else - { - textId = getTexId(_TexsId, texIndex); - color = getCol(_Col, texIndex); - } - CViewRenderer::getInstance()->drawRotFlipBitmap (_RenderLayer, px, py, itemw, itemh, 0, false, - textId, - color); - } - ++counter; - if ((sint32) counter == _CD.NumSel.getSInt32()) - break; - } - } - - if ((sint32) selectedTexIndex >= _CD.NumSel.getSInt32()) - { - return; - } - - // draw current selection - sint32 px; - sint32 py; - // - if (_CD.Align.getSInt32() & 1) - { - px = _XReal + _WReal - itemw; - } - else - { - px = _XReal; - } - // - if (_CD.Align.getSInt32() & 2) - { - py = _YReal + _HReal - itemh; - } - else - { - py = _YReal; - } - // - if (_CD.Unrolled.getBool()) - { - if (overItem && CWidgetManager::getInstance()->getPointer()->getButtonState() & NLMISC::leftButton) - { - textId = getTexId(_TexsId, selectedTexIndex); - color = getCol(_Col, selectedTexIndex); - } - else - { - textId = getTexId(_TexsPushedId, selectedTexIndex); - color = getCol(_ColPushed, selectedTexIndex); - } - } - else - { - if (over - && mx >= px - && my >= py - && mx < px + (sint32) itemw - && my < py + (sint32) itemh - ) - { - if ( CWidgetManager::getInstance()->getPointer()->getButtonState() & NLMISC::leftButton) - { - textId = getTexId(_TexsPushedId, selectedTexIndex); - color = getCol(_ColPushed, selectedTexIndex); - } - else - { - textId = getTexId(_TexsOverId, selectedTexIndex); - color = getCol(_ColOver, selectedTexIndex); - } - } - else - { - textId = getTexId(_TexsId, selectedTexIndex); - color = getCol(_Col, selectedTexIndex); - } - } - - CViewRenderer::getInstance()->drawRotFlipBitmap (_RenderLayer, px, py, itemw, itemh, 0, false, - textId, - color); -} - -//======================================================================================= -void CViewBitmapCombo::parseTexList(const std::string &names, TStringArray &dest) -{ - static const char sep[] = " ,\t"; - std::string::size_type pos = 0, nextPos; - dest.clear(); - do - { - nextPos = names.find_first_of(sep, pos); - if (pos != nextPos) - { - dest.push_back(names.substr(pos, nextPos - pos)); - } - pos = names.find_first_not_of(sep, nextPos); - } - while (pos != std::string::npos); -} - -//======================================================================================= -void CViewBitmapCombo::parseColList(const std::string &names,TColorArray &dest) -{ - static const char sep[] = ",\t"; - std::string::size_type pos = 0, nextPos; - dest.clear(); - std::string col; - do - { - nextPos = names.find_first_of(sep, pos); - if (pos != nextPos) - { - col = names.substr(pos, nextPos - pos); - int r = 0, g = 0, b = 0, a = 255; - sscanf (col.c_str(), "%d %d %d %d", &r, &g, &b, &a); - NLMISC::clamp (r, 0, 255); - NLMISC::clamp (g, 0, 255); - NLMISC::clamp (b, 0, 255); - NLMISC::clamp (a, 0, 255); - dest.push_back(NLMISC::CRGBA((uint8) r, (uint8) g, (uint8) b, (uint8) a)); - } - pos = names.find_first_not_of(sep, nextPos); - } - while (pos != std::string::npos); -} - -//======================================================================================= -void CViewBitmapCombo::setupSize() -{ - uint w, h; - _CD.getDimensions(w, h); - setW(w); - setH(h); - invalidateCoords(); -} - -//======================================================================================= -void CViewBitmapCombo::update(ICDBNode * /* leaf */) -{ - setupSize(); -} - - -//======================================================================================= -/** copy an array of char * into an array of strings - */ -static void copyStrArrayFromChar(CViewBitmapCombo::TStringArray &dest, const char * const src[], uint numColor) -{ - dest.resize(numColor); - for(uint k = 0; k < numColor; ++k) - { - dest[k] = src[k]; - } -} - - -static void copyRGBAVectorFromRGBAArray(CViewBitmapCombo::TColorArray &dest, const NLMISC::CRGBA src[], uint numColor) -{ - dest.resize(numColor); - std::copy(src, src + numColor, dest.begin()); -} - - -//======================================================================================= -void CViewBitmapCombo::setTexs(const char * const tex[], uint numTex) -{ - copyStrArrayFromChar(_Texs, tex, numTex); -} - -//======================================================================================= -void CViewBitmapCombo::setTexsOver(const char * const tex[], uint numTex) -{ - copyStrArrayFromChar(_TexsOver, tex, numTex); -} - - -//======================================================================================= -void CViewBitmapCombo::setTexsPushed(const char * const tex[], uint numTex) -{ - copyStrArrayFromChar(_TexsPushed, tex, numTex); -} - -//======================================================================================= -void CViewBitmapCombo::setColors(const NLMISC::CRGBA colors[], uint numColors) -{ - copyRGBAVectorFromRGBAArray(_Col, colors, numColors); -} - - -//======================================================================================= -void CViewBitmapCombo::setColorsOver(const NLMISC::CRGBA colors[], uint numColors) -{ - copyRGBAVectorFromRGBAArray(_ColOver, colors, numColors); -} - - -//======================================================================================= -void CViewBitmapCombo::setColorsPushed(const NLMISC::CRGBA colors[], uint numColors) -{ - copyRGBAVectorFromRGBAArray(_ColPushed, colors, numColors); -} diff --git a/code/ryzom/client/src/interface_v3/view_bitmap_combo.h b/code/ryzom/client/src/interface_v3/view_bitmap_combo.h deleted file mode 100644 index 1d4c34a0b..000000000 --- a/code/ryzom/client/src/interface_v3/view_bitmap_combo.h +++ /dev/null @@ -1,170 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - - - -#ifndef NL_VIEW_BITMAP_COMBO_H -#define NL_VIEW_BITMAP_COMBO_H - -#include "nel/misc/cdb.h" -#include "nel/gui/view_base.h" -#include "nel/3d/u_texture.h" -#include -#include - - -/** Description of a combo box, this can be parsed from an xml node - * The bitmap layout is as follow : - * - * I W I W I W - * t G t G t G - * e a e a e a - * m p m p m p - * W S W W - * i e i i - * d l d d - * t e t t - * h c h h - * t - * e - * d - * +----+---+----+---+---+---+---+--... - * |ssss| |****| |***| |***| - * ItemHeight |ssss| |****| |***| |*** - * +----+---+----+---+---+---+---+--... - * | | | | | | | | - * HGapSeleted | | | | | | | | - * +----+---+----+---+---+---+---+--... - * |****| |****| |***| |***| - * ItemHeight |****| |****| |***| |***| - * +----+---+----+---+---+---+---+--... - * | | | | | | | | - * HGap | | | | | | | | - * +----+---+----+---+---+---+---+--... - * |****| |****| |***| |***| - * ItemHeight |****| |****| |***| |***| - * . . . . . . . . - * . . . . . . . . - * s : selected item. . . . . . . - * * : where bitmap are displayed - */ - - -struct CComboBoxDesc -{ - bool parse(xmlNodePtr cur, CInterfaceElement *owner); - void addObserver(NLMISC::ICDBNode::IPropertyObserver *obs); - void getGridSize(uint &numRow,uint &numCol) const; - void getDimensions(uint &width, uint &height) const; - CInterfaceProperty NumRow; - CInterfaceProperty NumCol; - CInterfaceProperty CurrSelected; - CInterfaceProperty ItemWidth; - CInterfaceProperty ItemHeight; - CInterfaceProperty Unrolled; - CInterfaceProperty WGapSelected; - CInterfaceProperty WGap; - CInterfaceProperty HGapSelected; - CInterfaceProperty HGap; - CInterfaceProperty NumSel; - CInterfaceProperty Align; - -}; - - - - -/** - * A combo box with several bitmaps in it - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2002 - */ -class CViewBitmapCombo : public CViewBase, public NLMISC::ICDBNode::IPropertyObserver -{ -public: - typedef std::vector TIdArray; - typedef std::vector TStringArray; - typedef std::vector TColorArray; -public: - /// ctor - CViewBitmapCombo(const TCtorParam ¶m); - /** - * parse an xml node and initialize the base view members. Must call CViewBase::parse - * \param cur : pointer to the xml node to be parsed - * \param parentGroup : the parent group of the view - * \partam id : a refence to the string that will receive the view ID - * \return true if success - */ - bool parse(xmlNodePtr cur,CInterfaceGroup * parentGroup); - virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } - /** - * draw the view - */ - void draw(); - - // access to texture & colors - const TStringArray &getTexs() const { return _Texs; } - const TStringArray &getTexsOver() const { return _TexsOver; } - const TStringArray &getTexsPushed() const { return _TexsPushed; } - // - const TColorArray &getColors() const { return _Col; } - const TColorArray &getColorsOver() const { return _ColOver; } - const TColorArray &getColorsPushed() const { return _ColPushed; } - // - void setTexs(const char * const tex[], uint numTex); - void setTexsOver(const char * const tex[], uint numTex); - void setTexsPushed(const char * const tex[], uint numTex); - // - void setColors(const NLMISC::CRGBA colors[], uint numColors); - void setColorsOver(const NLMISC::CRGBA colors[], uint numColors); - void setColorsPushed(const NLMISC::CRGBA colors[], uint numColors); - - - - - - - -/////////////////////////////////////////////////////////////////////////////////// -private: - // - TStringArray _Texs; - TStringArray _TexsOver; - TStringArray _TexsPushed; - TIdArray _TexsId; - TIdArray _TexsOverId; - TIdArray _TexsPushedId; - TColorArray _Col; - TColorArray _ColOver; - TColorArray _ColPushed; - CComboBoxDesc _CD; - CInterfaceElement *_Owner; -private: - void parseTexList(const std::string &names, TStringArray &dest); - void parseColList(const std::string &names, TColorArray &dest); - void setupSize(); - void getDimensions(uint &numRow, uint &numCol); - // From ICDBNode::IPropertyObserver - void update(NLMISC::ICDBNode *leaf); - // Return a color from the array, or white if it is empty - static NLMISC::CRGBA getCol(const TColorArray &array, uint index); - static const std::string *getTex(const TStringArray &array, uint index); - static sint32 getTexId(const TIdArray &array, uint index); -}; - -#endif