//============================================================================ // // SSSS tt lll lll // SS SS tt ll ll // SS tttttt eeee ll ll aaaa // SSSS tt ee ee ll ll aa // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" // SS SS tt ee ll ll aa aa // SSSS ttt eeeee llll llll aaaaa // // Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony // and the Stella Team // // See the file "License.txt" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ #include "bspf.hxx" #include "Dialog.hxx" #include "DialogContainer.hxx" #include "EditTextWidget.hxx" #include "GuiObject.hxx" #include "OSystem.hxx" #include "FrameBuffer.hxx" #include "FBSurface.hxx" #include "Font.hxx" #include "Widget.hxx" #include "InputTextDialog.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& font, const StringList& labels) : Dialog(boss->instance(), boss->parent()), CommandSender(boss), myEnableCenter(false), myErrorFlag(false), myXOrig(0), myYOrig(0) { initialize(font, font, labels); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, const StringList& labels) : Dialog(boss->instance(), boss->parent()), CommandSender(boss), myEnableCenter(false), myErrorFlag(false), myXOrig(0), myYOrig(0) { initialize(lfont, nfont, labels); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont, const StringList& labels) { const int fontWidth = lfont.getMaxCharWidth(), fontHeight = lfont.getFontHeight(), lineHeight = lfont.getLineHeight(); uInt32 xpos, ypos, i, lwidth = 0, maxIdx = 0; WidgetArray wid; // Calculate real dimensions _w = fontWidth * 41; _h = lineHeight * 4 + int(labels.size()) * (lineHeight + 5); // Determine longest label for(i = 0; i < labels.size(); ++i) { if(labels[i].length() > lwidth) { lwidth = int(labels[i].length()); maxIdx = i; } } lwidth = lfont.getStringWidth(labels[maxIdx]); // Create editboxes for all labels ypos = lineHeight; for(i = 0; i < labels.size(); ++i) { xpos = 10; new StaticTextWidget(this, lfont, xpos, ypos + 2, lwidth, fontHeight, labels[i], TextAlign::Left); xpos += lwidth + fontWidth; EditTextWidget* w = new EditTextWidget(this, nfont, xpos, ypos, _w - xpos - 10, lineHeight, ""); wid.push_back(w); myInput.push_back(w); ypos += lineHeight + 5; } xpos = 10; myTitle = new StaticTextWidget(this, lfont, xpos, ypos, _w - 2*xpos, fontHeight, "", TextAlign::Left); myTitle->setTextColor(kTextColorEm); addToFocusList(wid); // Add OK and Cancel buttons wid.clear(); addOKCancelBGroup(wid, lfont); addBGroupToFocusList(wid); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::show() { myEnableCenter = true; open(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::show(uInt32 x, uInt32 y) { myXOrig = x; myYOrig = y; myEnableCenter = false; open(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::center() { if(!myEnableCenter) { // Make sure the menu is exactly where it should be, in case the image // offset has changed const GUI::Rect& image = instance().frameBuffer().imageRect(); uInt32 x = image.x() + myXOrig; uInt32 y = image.y() + myYOrig; uInt32 tx = image.x() + image.width(); uInt32 ty = image.y() + image.height(); if(x + _w > tx) x -= (x + _w - tx); if(y + _h > ty) y -= (y + _h - ty); surface().setDstPos(x, y); } else Dialog::center(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::setTitle(const string& title) { myTitle->setLabel(title); myErrorFlag = true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const string& InputTextDialog::getResult(int idx) { if(uInt32(idx) < myInput.size()) return myInput[idx]->getText(); else return EmptyString; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::setText(const string& str, int idx) { if(uInt32(idx) < myInput.size()) myInput[idx]->setText(str); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::setTextFilter(const EditableWidget::TextFilter& f, int idx) { if(uInt32(idx) < myInput.size()) myInput[idx]->setTextFilter(f); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::setFocus(int idx) { if(uInt32(idx) < myInput.size()) Dialog::setFocus(getFocusList()[idx]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) { switch(cmd) { case GuiObject::kOKCmd: case EditableWidget::kAcceptCmd: { // Send a signal to the calling class that a selection has been made // Since we aren't derived from a widget, we don't have a 'data' or 'id' if(myCmd) sendCommand(myCmd, 0, 0); // We don't close, but leave the parent to do it // If the data isn't valid, the parent may wait until it is break; } case EditableWidget::kChangedCmd: // Erase the invalid message once editing is restarted if(myErrorFlag) { myTitle->setLabel(""); myErrorFlag = false; } break; case EditableWidget::kCancelCmd: Dialog::handleCommand(sender, GuiObject::kCloseCmd, data, id); break; default: Dialog::handleCommand(sender, cmd, data, id); break; } }