From 6b742e903b6cacb72d810c6aacb1ccc983b18ebe Mon Sep 17 00:00:00 2001 From: bitplane Date: Thu, 30 Aug 2007 19:07:26 +0000 Subject: [PATCH] added password option for edit box. removed some credits as requested git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@885 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 1 + include/IGUIEditBox.h | 9 ++++ source/Irrlicht/CGUIEditBox.cpp | 93 +++++++++++++++++++++++++-------- source/Irrlicht/CGUIEditBox.h | 12 ++++- source/Irrlicht/CGUIListBox.cpp | 17 ------ source/Irrlicht/CGUIListBox.h | 7 --- 6 files changed, 93 insertions(+), 46 deletions(-) diff --git a/changes.txt b/changes.txt index b8e76f87..340288fc 100644 --- a/changes.txt +++ b/changes.txt @@ -170,6 +170,7 @@ GUI: setWordWrap/isWordWrapEnabled, to split words on to the next line. setMultiLine and isMultiLineEnabled, inserts a newline instead of sending EGET_EDITBOX_ENTER events. + setPasswordBox/isPasswordBox to use the edit box for password input. setTextAlignment, to align the text to left, right, top, bottom and centers setAutoScroll, to enable and disable automatic scrolling with the cursor diff --git a/include/IGUIEditBox.h b/include/IGUIEditBox.h index 864f06a2..abee7d39 100644 --- a/include/IGUIEditBox.h +++ b/include/IGUIEditBox.h @@ -84,6 +84,15 @@ namespace gui //! \return true if automatic scrolling is enabled, false if not virtual bool isAutoScrollEnabled() = 0; + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*') = 0; + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox() = 0; + //! Gets the size area of the text in the edit box //! \return Returns the size in pixels of the text virtual core::dimension2di getTextDimension() = 0; diff --git a/source/Irrlicht/CGUIEditBox.cpp b/source/Irrlicht/CGUIEditBox.cpp index fe22dfb5..1761427b 100644 --- a/source/Irrlicht/CGUIEditBox.cpp +++ b/source/Irrlicht/CGUIEditBox.cpp @@ -17,9 +17,9 @@ todo: optional scrollbars ctrl+left/right to select word - double click/ctrl click: word select + drag to select whole words - optional dragging selected text - optional triple click to select line + double click/ctrl click: word select + drag to select whole words, triple click to select line + optional? dragging selected text + numerical */ namespace irr @@ -35,7 +35,8 @@ CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* envi Border(border), OverrideColorEnabled(false), MarkBegin(0), MarkEnd(0), OverrideColor(video::SColor(101,255,255,255)), OverrideFont(0), LastBreakFont(0), CursorPos(0), HScrollPos(0), VScrollPos(0), Max(0), - WordWrap(false), MultiLine(false), AutoScroll(true), + WordWrap(false), MultiLine(false), AutoScroll(true), PasswordBox(false), + PasswordChar(L'*'), HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER) { @@ -137,6 +138,23 @@ bool CGUIEditBox::isMultiLineEnabled() return MultiLine; } +void CGUIEditBox::setPasswordBox(bool passwordBox, wchar_t passwordChar) +{ + PasswordBox = passwordBox; + if (PasswordBox) + { + PasswordChar = passwordChar; + setMultiLine(false); + setWordWrap(false); + BrokenText.clear(); + } +} + +bool CGUIEditBox::isPasswordBox() +{ + return PasswordBox; +} + //! Sets text justification void CGUIEditBox::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) { @@ -194,7 +212,7 @@ bool CGUIEditBox::processKey(const SEvent& event) break; case KEY_KEY_C: // copy to clipboard - if (Operator && MarkBegin != MarkEnd) + if (!PasswordBox && Operator && MarkBegin != MarkEnd) { s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; @@ -206,7 +224,7 @@ bool CGUIEditBox::processKey(const SEvent& event) break; case KEY_KEY_X: // cut to the clipboard - if (Operator && MarkBegin != MarkEnd) + if (!PasswordBox && Operator && MarkBegin != MarkEnd) { s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; @@ -666,11 +684,12 @@ void CGUIEditBox::draw() core::stringw s, s2; // get mark position + bool ml = (!PasswordBox && (WordWrap || MultiLine)); s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; - s32 hlineStart = (WordWrap || MultiLine) ? getLineFromPos(realmbgn) : 0; - s32 hlineCount = (WordWrap || MultiLine) ? getLineFromPos(realmend) - hlineStart + 1 : 1; - s32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1; + s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0; + s32 hlineCount = ml ? getLineFromPos(realmend) - hlineStart + 1 : 1; + s32 lineCount = ml ? BrokenText.size() : 1; // Save the override color information. // Then, alter it if the edit box is disabled. @@ -679,10 +698,10 @@ void CGUIEditBox::draw() if (Text.size()) { - if ( !this->IsEnabled && !OverrideColorEnabled ) + if (!IsEnabled && !OverrideColorEnabled) { OverrideColorEnabled = true; - OverrideColor = skin->getColor( EGDC_GRAY_TEXT ); + OverrideColor = skin->getColor(EGDC_GRAY_TEXT); } for (s32 i=0; i < lineCount; ++i) @@ -696,8 +715,30 @@ void CGUIEditBox::draw() continue; // get current line - txtLine = (WordWrap || MultiLine) ? &BrokenText[i] : &Text; - startPos = (WordWrap || MultiLine) ? BrokenTextPositions[i] : 0; + if (PasswordBox) + { + if (BrokenText.size() != 1) + { + BrokenText.clear(); + BrokenText.push_back(core::stringw()); + } + if (BrokenText[0].size() != Text.size()) + { + BrokenText[0] = Text; + for (u32 q = 0; q < Text.size(); ++q) + { + BrokenText[0] [q] = PasswordChar; + } + } + txtLine = &BrokenText[0]; + startPos = 0; + } + else + { + txtLine = ml ? &BrokenText[i] : &Text; + startPos = ml ? BrokenTextPositions[i] : 0; + } + // draw normal text font->draw(txtLine->c_str(), CurrentTextRect, @@ -1249,15 +1290,19 @@ void CGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWr { // IGUIEditBox::serializeAttributes(out,options); - out->addBool ("OverrideColorEnabled", OverrideColorEnabled ); - out->addColor ("OverrideColor", OverrideColor); + out->addBool ("OverrideColorEnabled",OverrideColorEnabled ); + out->addColor ("OverrideColor", OverrideColor); // out->addFont("OverrideFont",OverrideFont); - out->addInt ("MaxChars", Max); - out->addBool ("WordWrap", WordWrap); - out->addBool ("MultiLine", MultiLine); - out->addBool ("AutoScroll", AutoScroll); - out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); - out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + out->addInt ("MaxChars", Max); + out->addBool ("WordWrap", WordWrap); + out->addBool ("MultiLine", MultiLine); + out->addBool ("AutoScroll", AutoScroll); + out->addBool ("PasswordBox", PasswordBox); + core::stringw ch = L" "; + ch[0] = PasswordChar; + out->addString("PasswordChar", ch.c_str()); + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); IGUIEditBox::serializeAttributes(out,options); } @@ -1273,6 +1318,12 @@ void CGUIEditBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadW setWordWrap(in->getAttributeAsBool("WordWrap")); setMultiLine(in->getAttributeAsBool("MultiLine")); setAutoScroll(in->getAttributeAsBool("AutoScroll")); + core::stringw ch = in->getAttributeAsStringW("PasswordChar"); + + if (!ch.size()) + setPasswordBox(in->getAttributeAsBool("PasswordBox")); + else + setPasswordBox(in->getAttributeAsBool("PasswordBox"), ch[0]); setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames), (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames)); diff --git a/source/Irrlicht/CGUIEditBox.h b/source/Irrlicht/CGUIEditBox.h index 9a5934a3..53c7e09d 100644 --- a/source/Irrlicht/CGUIEditBox.h +++ b/source/Irrlicht/CGUIEditBox.h @@ -88,6 +88,15 @@ namespace gui //! Returns maximum amount of characters, previously set by setMax(); virtual s32 getMax(); + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*'); + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox(); + //! Updates the absolute position, splits text if required virtual void updateAbsolutePosition(); @@ -128,7 +137,8 @@ namespace gui s32 HScrollPos, VScrollPos; // scroll position in characters s32 Max; - bool WordWrap, MultiLine, AutoScroll; + bool WordWrap, MultiLine, AutoScroll, PasswordBox; + wchar_t PasswordChar; EGUI_ALIGNMENT HAlign, VAlign; core::array< core::stringw > BrokenText; diff --git a/source/Irrlicht/CGUIListBox.cpp b/source/Irrlicht/CGUIListBox.cpp index c1418d7d..994bbe3d 100644 --- a/source/Irrlicht/CGUIListBox.cpp +++ b/source/Irrlicht/CGUIListBox.cpp @@ -649,9 +649,6 @@ void CGUIListBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWr out->addBool ("MoveOverSelect", MoveOverSelect); out->addBool ("AutoScroll", AutoScroll); - // MICHA, StarSonata - // I also don't know yet how to handle icons, but added some text+color serialization now - // I did it the same way it's done for the context menus out->addInt("ItemCount", Items.size()); u32 i; for (i=0;igetAttributeAsInt("ItemCount"); for (s32 i=0; i<(s32)count; ++i) { @@ -722,7 +716,6 @@ void CGUIListBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadW } } -// MICHA, StarSonata void CGUIListBox::recalculateItemWidth(s32 icon) { if (IconBank && icon > -1 && @@ -739,7 +732,6 @@ void CGUIListBox::recalculateItemWidth(s32 icon) } } -// MICHA, StarSonata void CGUIListBox::setItem(s32 index, const wchar_t* text, s32 icon) { if ( index < 0 || index >= (s32)Items.size() ) @@ -752,7 +744,6 @@ void CGUIListBox::setItem(s32 index, const wchar_t* text, s32 icon) recalculateItemWidth(icon); } -// MICHA, StarSonata //! Insert the item at the given index //! Return the index on success or -1 on failure. s32 CGUIListBox::insertItem(s32 index, const wchar_t* text, s32 icon) @@ -770,7 +761,6 @@ s32 CGUIListBox::insertItem(s32 index, const wchar_t* text, s32 icon) return index; } -// MICHA, StarSonata void CGUIListBox::swapItems(s32 index1, s32 index2) { if ( index1 < 0 || index2 < 0 || index1 >= (s32)Items.size() || index2 >= (s32)Items.size() ) @@ -781,7 +771,6 @@ void CGUIListBox::swapItems(s32 index1, s32 index2) Items[index2] = dummmy; } -// MICHA, StarSonata void CGUIListBox::setItemOverrideColor(s32 index, const video::SColor &color) { for ( s32 c=0; c < (s32)EGUI_LBC_COUNT; ++c ) @@ -791,7 +780,6 @@ void CGUIListBox::setItemOverrideColor(s32 index, const video::SColor &color) } } -// MICHA, StarSonata void CGUIListBox::setItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType, const video::SColor &color) { if ( index < 0 || index >= (s32)Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) @@ -801,7 +789,6 @@ void CGUIListBox::setItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType, Items[index].OverrideColors[colorType].Color = color; } -// MICHA, StarSonata void CGUIListBox::clearItemOverrideColor(s32 index) { for (s32 c=0; c < (s32)EGUI_LBC_COUNT; ++c ) @@ -810,7 +797,6 @@ void CGUIListBox::clearItemOverrideColor(s32 index) } } -// MICHA, StarSonata void CGUIListBox::clearItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType) { if ( index < 0 || index >= (s32)Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) @@ -819,7 +805,6 @@ void CGUIListBox::clearItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType Items[index].OverrideColors[colorType].Use = false; } -// MICHA, StarSonata bool CGUIListBox::hasItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType) { if ( index < 0 || index >= (s32)Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) @@ -828,7 +813,6 @@ bool CGUIListBox::hasItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType) return Items[index].OverrideColors[colorType].Use; } -// MICHA, StarSonata video::SColor CGUIListBox::getItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR colorType) { if ( index < 0 || index >= (s32)Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) @@ -837,7 +821,6 @@ video::SColor CGUIListBox::getItemOverrideColor(s32 index, EGUI_LISTBOX_COLOR co return Items[index].OverrideColors[colorType].Color; } -// MICHA, StarSonata video::SColor CGUIListBox::getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) { IGUISkin* skin = Environment->getSkin(); diff --git a/source/Irrlicht/CGUIListBox.h b/source/Irrlicht/CGUIListBox.h index 8bba1c2b..8b1c62ff 100644 --- a/source/Irrlicht/CGUIListBox.h +++ b/source/Irrlicht/CGUIListBox.h @@ -88,7 +88,6 @@ namespace gui //! Reads attributes of the element virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); - // MICHA, StarSonata, multicolor support //! set all item colors at given index to color virtual void setItemOverrideColor(s32 index, const video::SColor &color); @@ -110,16 +109,13 @@ namespace gui //! return the default color which is used for the given colorType virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType); - // MICHA, StarSonata //! set the item at the given index virtual void setItem(s32 index, const wchar_t* text, s32 icon); - // MICHA, StarSonata //! Insert the item at the given index //! Return the index on success or -1 on failure. virtual s32 insertItem(s32 index, const wchar_t* text, s32 icon); - // MICHA, StarSonata //! Swap the items at the given indices virtual void swapItems(s32 index1, s32 index2); @@ -133,7 +129,6 @@ namespace gui core::stringw text; s32 icon; - // MICHA, StarSonata // A multicolor extension struct ListItemOverrideColor { @@ -148,11 +143,9 @@ namespace gui void selectNew(s32 ypos, bool onlyHover=false); void recalculateScrollPos(); - // MICHA, StarSonata // extracted that function to avoid copy&paste code void recalculateItemWidth(s32 icon); - // MICHA, StarSonata // get labels used for serialization bool getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel);