Logo Search packages:      
Sourcecode: fbdesk version File versions  Download package

InputField.cc

// InputField.cc for FbDesk
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
// 
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id$

#include "InputField.hh"
#include "EventManager.hh"
#include "App.hh"

#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <assert.h>

namespace {

void setNoResize(FbTk::FbWindow &win) {
    // we don't need to maximize this window
    XSizeHints sh;
    sh.flags = PMaxSize | PMinSize;
    sh.max_width = win.width();
    sh.max_height = win.height();
    sh.min_width = win.width();
    sh.min_height = win.height();
    XSetWMNormalHints(FbTk::App::instance()->display(), win.window(), &sh);

}

};
namespace FbDesk {

InputField::InputField(int screen_num, const FbTk::Font &font, GC gc, const FbTk::Color &bgcolor):
    m_window(screen_num, 0, 0, 100, 32, KeyReleaseMask | ExposureMask),
    m_font(&font),
    m_bgcolor(bgcolor),
    m_text(""),
    m_gc(gc) {
    FbTk::EventManager::instance()->add(*this, m_window);
    m_window.resize(100, m_font->height() + 2);
    m_window.setBackgroundColor(bgcolor);
    setNoResize(m_window);
}

InputField::~InputField() {
    FbTk::EventManager::instance()->remove(m_window);
}

void InputField::exposeEvent(XExposeEvent &event) {
    redrawText();
}

void InputField::keyReleaseEvent(XKeyEvent &event) {
    KeySym ks;
    char keychar[1];
    XLookupString(&event, keychar, 1, &ks, 0);
    if (ks == XK_Escape) {
        hide();
        return; // no more processing
    } else if (ks == XK_Return) {
        if (m_on_enter.get() != 0)
            m_on_enter->execute();
    } else if (ks == XK_BackSpace) {
        if (m_text.size() != 0) { // we can't erase what we don't have ;)
            m_text.erase(m_text.size() - 1);
            redrawText();
        }
    } else if (! IsModifierKey(ks) && !IsCursorKey(ks)) {
        m_text += keychar[0]; // append character
        redrawText(); 
    }
}

void InputField::move(int x, int y) {
    m_window.move(x, y);
}

void InputField::resize(unsigned int width, unsigned int height) {
    m_window.resize(width, height);
}

void InputField::show() {
    m_window.show();
}

void InputField::hide() {
    m_window.hide();
}

void InputField::raise() {
    m_window.raise();
}

void InputField::lower() {
    m_window.lower();
}

void InputField::setFont(const FbTk::Font &font) {
    m_font = &font;
}

void InputField::reconfigure() {
    resize(m_window.width(), m_font->height() + 2);
    redrawText();
}

void InputField::setTitle(const std::string &text) {
    m_window.setName(text.c_str());
}

void InputField::setText(const std::string &text) {
    m_text = text;
    redrawText();
}

void InputField::redrawText() {
    if (m_font == 0)
        return;
    m_window.setBackgroundColor(m_bgcolor);
    m_window.clear();

    assert(m_gc);

    // check right boundary and adjust text drawing
    const char *text = m_text.c_str();
    size_t len = m_text.size();
    size_t text_width = m_font->textWidth(text, len);
    size_t startpos = 0;
    if (text_width > m_window.width()) {
        for (; startpos < len; ++startpos) {
            if (m_font->textWidth(text + startpos, len - startpos) < m_window.width())
                break;
        }         
    }

    m_font->drawText(m_window.window(), 
                     DefaultScreen(FbTk::App::instance()->display()), 
                     m_gc, text + startpos, len - startpos, 
                     0, m_font->height());

}


}; // end namespace FbDesk

Generated by  Doxygen 1.6.0   Back to index