--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief QT-based widget for keyboard emulation (implementation)
+ */
+
+#include "emulkbd.h"
+#include "emul.h"
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qsizepolicy.h>
+#include <qsize.h>
+#include <qrect.h>
+#include <qlayout.h>
+#include <qobjectlist.h>
+
+
+EmulKey::EmulKey(EmulKbd *kbd, const char *label, int _keycode, int _row, int _col) :
+ QPushButton(label, kbd),
+ row(_row), col(_col),
+ keycode(_keycode)
+{
+ // don't let the widget get focus
+ setFocusPolicy(QWidget::NoFocus);
+
+ // unused
+ connect(this, SIGNAL(pressed()), this, SLOT(keyPressed()));
+ connect(this, SIGNAL(released()), this, SLOT(keyReleased()));
+}
+
+
+EmulKey::~EmulKey()
+{
+ // nop
+}
+
+
+/**
+ * \reimp
+ * Override standad QButton behaviour: we must also emit the signals
+ */
+// unused
+void EmulKey::setDown(bool enable)
+{
+ // let our superclass do everything else
+ QPushButton::setDown(enable);
+
+ if (enable)
+ emit pressed();
+ else
+ emit released();
+}
+
+
+// unused
+void EmulKey::keyPressed(void)
+{
+ static_cast<EmulKbd *>(parent())->setKey(row, col, true);
+}
+
+
+// unused
+void EmulKey::keyReleased(void)
+{
+ static_cast<EmulKbd *>(parent())->setKey(row, col, false);
+}
+
+
+EmulKbd::EmulKbd(QWidget *parent, const char *name, WFlags f) :
+ QFrame(parent, name, WRepaintNoErase | WResizeNoErase | f),
+ layout(new QGridLayout(this, 4, 4, 4)),
+ active_row(0)
+{
+ setFrameStyle(QFrame::Box | QFrame::Sunken);
+ setLineWidth(1);
+ setFocusPolicy(StrongFocus);
+ frame_width = frameWidth();
+}
+
+
+EmulKbd::~EmulKbd()
+{
+ delete layout;
+}
+
+
+QSizePolicy EmulKbd::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
+}
+
+
+void EmulKbd::resizeEvent(QResizeEvent * event)
+{
+ // Let our superclass process the event first
+ QFrame::resizeEvent(event);
+}
+
+
+// handle key presses for all keys in keyboard
+bool EmulKbd::event(QEvent * _e)
+{
+ switch (_e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ QKeyEvent *e = static_cast<QKeyEvent *>(_e);
+ int keycode = e->key();
+ EmulKey *key;
+
+ // ignore repeated keys
+ if (!e->isAutoRepeat())
+ {
+ // scan all children
+ for (QObjectListIt it(*children()); *it; ++it)
+ {
+ // only keys, not other children!
+ if ((*it)->metaObject() == EmulKey::staticMetaObject())
+ // if ((key = dynamic_cast<EmulKey *>(*it)))
+ {
+ key = static_cast<EmulKey *>(*it);
+
+ // same key?
+ if (key->keycode == keycode)
+ {
+ // yes, tell key to go down (or up)
+ key->setDown(_e->type() == QEvent::KeyPress);
+ break;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ default:
+ // let superclass process this event
+ return QFrame::event(_e);
+
+ } // end switch(_e->type())
+}
+
+
+void EmulKbd::addKey(const char *label, int keycode, int row, int col, int matrix_row, int matrix_col)
+{
+ if (matrix_row == -1)
+ matrix_row = row;
+ if (matrix_col == -1)
+ matrix_col = col;
+
+ layout->addWidget(new EmulKey(this, label, keycode, matrix_row, matrix_col), row, col);
+}
+
+
+// unused
+void EmulKbd::setKey(int /*row*/, int /*col*/, bool /*on*/)
+{
+}
+
+
+void EmulKbd::setRow(int r)
+{
+ active_row = r;
+}
+
+int EmulKbd::readCols(void)
+{
+ QLayoutItem *item;
+ EmulKey *key;
+ int cols = 0;
+
+ for(QLayoutIterator it(layout->iterator()); (item = it.current()); ++it)
+ {
+ key = static_cast<EmulKey *>(item->widget());
+ if (key->row == active_row)
+ {
+ if (key->isDown())
+ cols |= (1<<key->col);
+ }
+ }
+ return cols;
+}
+
+extern "C" void emul_kbdSetRows(int r)
+{
+ emul->emulKbd->setRow(r);
+}
+
+
+extern "C" int emul_kbdReadCols(void)
+{
+ return emul->emulKbd->readCols();
+}
+
+#include "emulkbd_moc.cpp"
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief QT-based widget for leyboard emulation (interface)
+ */
+
+#if !defined(EMULKBD_H)
+#define EMULKBD_H
+
+#if defined (_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <qframe.h>
+
+// fwd decl
+class QGridLayout;
+class EmulKey;
+
+class EmulKbd : public QFrame
+{
+ Q_OBJECT
+
+// Data members
+protected:
+ QGridLayout *layout;
+ int frame_width;
+ int active_row;
+
+// Construction
+public:
+ EmulKbd(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ virtual ~EmulKbd();
+
+// Public methods
+ void addKey(const char *label, int keycode, int row, int col, int matrix_row = -1, int matrix_col = -1);
+ void setRow(int row);
+ int readCols(void);
+
+// Protected methods
+protected:
+ void setKey(int row, int col, bool on);
+
+// Base class overrides
+protected:
+ virtual QSizePolicy sizePolicy() const;
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual bool event(QEvent *e);
+
+// Friends
+ friend class EmulKey;
+};
+
+
+// Private helper class for EmulKbd
+// NOTE: with protected inheritance, dynamic_cast<> does not work (gcc 2.96)
+#include <qpushbutton.h>
+class EmulKey : public QPushButton
+{
+ Q_OBJECT
+
+// Data members
+protected:
+ int row, col;
+ int keycode;
+
+// Construction
+public:
+ EmulKey(EmulKbd *parent, const char *label, int keycode, int _row, int _col);
+ virtual ~EmulKey();
+
+// superclass overrides
+ void setDown(bool enable);
+
+protected slots:
+ void keyPressed(void);
+ void keyReleased(void);
+
+// Friends
+public:
+ friend class EmulKbd;
+};
+
+#endif // !defined(EMULKBD_H)
+
/*#*
*#* $Log$
+ *#* Revision 1.3 2006/02/15 09:11:17 bernie
+ *#* Add keyboard emulator.
+ *#*
*#* Revision 1.2 2006/01/16 03:51:51 bernie
*#* Fix boilerplate.
*#*
#include <drv/lcd_gfx_qt.h>
#include <emul/emul.h>
+#include <emul/emulkbd.h>
#include <cassert>
#include <qlayout.h>
#include <qtimer.h>
#include <qapplication.h>
-EmulWin::EmulWin(Emulator *e) : QMainWindow(0, "SarfEmul", WDestructiveClose)
+EmulWin::EmulWin(Emulator *e) : QMainWindow(0, "DevLibEmul", WDestructiveClose)
{
// "File" menu
QPopupMenu * file = new QPopupMenu(this);
// LCD
QHBoxLayout *lay_lcd = new QHBoxLayout(box_right, 4);
lay_lcd->addWidget(e->emulLCD = new EmulLCD(central));
+
+ // Keyboard
+ QHBoxLayout *lay_kbd = new QHBoxLayout(box_right, 4);
+ lay_kbd->addWidget(e->emulKbd = new EmulKbd(central));
+
+ // Setup keyboard: Label Keycode Row Col MRow MCol
+ e->emulKbd->addKey("^", Key_Up, 0, 0, 0, 0);
+ e->emulKbd->addKey("v", Key_Down, 1, 0, 0, 1);
+ e->emulKbd->addKey("OK", Key_Return, 0, 1, 0, 2);
+ e->emulKbd->addKey("ESC", Key_Escape, 1, 1, 0, 3);
}