/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * lineedit.cc * * Sun Oct 9 13:01:52 CEST 2011 * Copyright 2011 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * DrumGizmo 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "lineedit.h" #include #include #define BORDER 10 namespace GUI { LineEdit::LineEdit(Widget *parent) : Widget(parent) { setReadOnly(false); } LineEdit::~LineEdit() { } void LineEdit::setReadOnly(bool ro) { readonly = ro; } bool LineEdit::readOnly() { return readonly; } void LineEdit::setText(const std::string& text) { _text = text; pos = text.size(); visibleText = _text; offsetPos = 0; redraw(); textChanged(); } std::string LineEdit::getText() { return _text; } void LineEdit::buttonEvent(ButtonEvent *buttonEvent) { if(readOnly()) { return; } // Ignore everything except left clicks. if(buttonEvent->button != MouseButton::left) { return; } if(buttonEvent->direction == Direction::down) { for(int i = 0; i < (int)visibleText.length(); ++i) { int textWidth = font.textWidth(visibleText.substr(0, i)); if(buttonEvent->x < (textWidth + BORDER)) { pos = i + offsetPos; break; } } redraw(); } } void LineEdit::keyEvent(KeyEvent *keyEvent) { if(readOnly()) { return; } bool change = false; if(keyEvent->direction == Direction::down) { switch(keyEvent->keycode) { case Key::left: if(pos == 0) { return; } pos--; if(offsetPos >= pos) { walkstate = WalkLeft; } break; case Key::right: if(pos == _text.length()) { return; } pos++; if((pos < _text.length()) && ((offsetPos + visibleText.length()) <= pos)) { walkstate = WalkRight; } break; case Key::home: pos = 0; visibleText = _text; offsetPos = 0; break; case Key::end: pos = _text.length(); visibleText = _text; offsetPos = 0; break; case Key::deleteKey: if(pos < _text.length()) { std::string t = _text.substr(0, pos); t += _text.substr(pos + 1, std::string::npos); _text = t; change = true; } break; case Key::backspace: if(pos > 0) { std::string t = _text.substr(0, pos - 1); t += _text.substr(pos, std::string::npos); _text = t; pos--; change = true; } break; case Key::character: { std::string pre = _text.substr(0, pos); std::string post = _text.substr(pos, std::string::npos); _text = pre + keyEvent->text + post; change = true; pos++; } break; case Key::enter: enterPressedNotifier(); break; default: break; } redraw(); } if(change) { textChanged(); } } void LineEdit::repaintEvent(RepaintEvent *repaintEvent) { Painter p(*this); int w = width(); int h = height(); if((w == 0) || (h == 0)) { return; } box.setSize(w, h); p.drawImage(0, 0, box); p.setColour(Colour(183.0f/255.0f, 219.0f/255.0f, 255.0f/255.0f, 1.0f)); switch(walkstate) { case WalkLeft: visibleText = _text.substr(pos, std::string::npos); offsetPos = pos; break; case WalkRight: { int delta = (offsetPos < _text.length()) ? 1 : 0; visibleText = _text.substr(offsetPos + delta); offsetPos = offsetPos + delta; } break; case Noop: visibleText = _text; offsetPos = 0; break; } while(true) { int textWidth = font.textWidth(visibleText); if(textWidth <= std::max(w - BORDER - 4 + 3, 0)) { break; } switch(walkstate) { case WalkLeft: visibleText = visibleText.substr(0, visibleText.length() - 1); break; case WalkRight: visibleText = visibleText.substr(0, visibleText.length() - 1); break; case Noop: if(offsetPos < pos) { visibleText = visibleText.substr(1); offsetPos++; } else { visibleText = visibleText.substr(0, visibleText.length() - 1); } break; } } walkstate = Noop; p.drawText(BORDER - 4 + 3, height() / 2 + 5 + 1 + 1 + 1, font, visibleText); if(readOnly()) { return; } if(hasKeyboardFocus()) { size_t px = font.textWidth(visibleText.substr(0, pos - offsetPos)); p.drawLine(px + BORDER - 1 - 4 + 3, 6, px + BORDER - 1 - 4 + 3, height() - 7); } } } // GUI::