File indexing completed on 2024-05-05 05:46:05

0001 /***************************************************************************
0002  *   Copyright (C) 2003,2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "eckeypad.h"
0012 #include "canvasitemparts.h"
0013 #include "libraryitem.h"
0014 #include "switch.h"
0015 
0016 #include "ecnode.h"
0017 #include <KLocalizedString>
0018 
0019 Item *ECKeyPad::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0020 {
0021     return new ECKeyPad(static_cast<ICNDocument *>(itemDocument), newItem, id);
0022 }
0023 
0024 LibraryItem *ECKeyPad::libraryItem()
0025 {
0026     return new LibraryItem(QStringList(QString("ec/keypad")), i18n("Keypad"), i18n("Switches"), "keypad.png", LibraryItem::lit_component, ECKeyPad::construct);
0027 }
0028 
0029 const QString text[4][9] = {{"1", "2", "3", "A", "E", "I", "M", "Q", "U"}, {"4", "5", "6", "B", "F", "J", "N", "R", "V"}, {"7", "8", "9", "C", "G", "K", "O", "S", "W"}, {"*", "0", "#", "D", "H", "L", "P", "T", "X"}};
0030 
0031 ECKeyPad::ECKeyPad(ICNDocument *icnDocument, bool newItem, const char *id)
0032     : Component(icnDocument, newItem, id ? id : "keypad")
0033 {
0034     m_name = i18n("Keypad");
0035 
0036     createProperty("useToggles", Variant::Type::Bool);
0037     property("useToggles")->setCaption(i18n("Use Toggles"));
0038     property("useToggles")->setValue(false);
0039 
0040     createProperty("numCols", Variant::Type::Int);
0041     property("numCols")->setCaption(i18n("Columns"));
0042     property("numCols")->setMinValue(3);
0043     property("numCols")->setMaxValue(9);
0044     property("numCols")->setValue(3);
0045 
0046     Variant *v = createProperty("bounce", Variant::Type::Bool);
0047     v->setCaption("Bounce");
0048     v->setAdvanced(true);
0049     v->setValue(false);
0050 
0051     v = createProperty("bounce_period", Variant::Type::Double);
0052     v->setCaption("Bounce Period");
0053     v->setAdvanced(true);
0054     v->setUnit("s");
0055     v->setValue(5e-3);
0056 
0057     for (int i = 0; i < 4; i++)
0058         createPin(0, -32 + i * 24, 0, QString("row_%1").arg(QString::number(i)));
0059 
0060     m_numCols = 0;
0061 }
0062 
0063 ECKeyPad::~ECKeyPad()
0064 {
0065 }
0066 
0067 QString ECKeyPad::buttonID(int row, int col) const
0068 {
0069     return QString("b_%1_%2").arg(QString::number(row)).arg(QString::number(col));
0070 }
0071 
0072 int ECKeyPad::sideLength(unsigned numButtons) const
0073 {
0074     return 8 + 24 * numButtons;
0075 }
0076 
0077 void ECKeyPad::dataChanged()
0078 {
0079     initPins(dataInt("numCols"));
0080 
0081     bool useToggle = dataBool("useToggles");
0082     bool bounce = dataBool("bounce");
0083     int bouncePeriod_ms = int(dataDouble("bounce_period") * 1e3);
0084 
0085     for (unsigned i = 0; i < 4; i++) {
0086         for (unsigned j = 0; j < m_numCols; j++) {
0087             button(buttonID(i, j))->setToggle(useToggle);
0088             m_switch[i][j]->setBounce(bounce, bouncePeriod_ms);
0089         }
0090     }
0091 }
0092 
0093 void ECKeyPad::initPins(unsigned numCols)
0094 {
0095     if (numCols < 3)
0096         numCols = 3;
0097     else if (numCols > 9)
0098         numCols = 9;
0099 
0100     if (numCols == m_numCols)
0101         return;
0102 
0103     int w = sideLength(numCols);
0104     int h = sideLength(4);
0105     setSize(-int(w / 16) * 8, -int(h / 16) * 8, w, h, true);
0106 
0107     if (numCols > m_numCols) {
0108         // Adding columns
0109 
0110         for (unsigned i = 0; i < 4; i++) {
0111             for (unsigned j = m_numCols; j < numCols; j++)
0112                 addButton(buttonID(i, j), QRect(0, 0, 20, 20), text[i][j]);
0113         }
0114 
0115         ECNode *cols[9];
0116 
0117         for (unsigned j = m_numCols; j < numCols; j++)
0118             cols[j] = createPin(0, 64, 270, "col_" + QString::number(j));
0119 
0120         for (unsigned i = 0; i < 4; i++) {
0121             ECNode *row = ecNodeWithID("row_" + QString::number(i));
0122             for (unsigned j = m_numCols; j < numCols; j++)
0123                 m_switch[i][j] = createSwitch(cols[j], row, true);
0124         }
0125     } else {
0126         // Remove columns
0127 
0128         for (unsigned i = 0; i < 4; i++) {
0129             for (unsigned j = numCols; j < m_numCols; j++)
0130                 removeWidget(buttonID(i, j));
0131         }
0132 
0133         for (unsigned j = numCols; j < m_numCols; j++)
0134             removeNode("col_" + QString::number(j));
0135 
0136         for (unsigned i = 0; i < 4; i++) {
0137             for (unsigned j = m_numCols; j < numCols; j++)
0138                 removeSwitch(m_switch[i][j]);
0139         }
0140     }
0141 
0142     // BEGIN Update Positions
0143     m_numCols = numCols;
0144 
0145     for (int i = 0; i < 4; i++) {
0146         for (int j = 0; j < int(m_numCols); j++) {
0147             widgetWithID(buttonID(i, j))->setOriginalRect(QRect(offsetX() + 6 + 24 * j, offsetY() + 6 + 24 * i, 20, 20));
0148         }
0149     }
0150 
0151     for (int i = 0; i < 4; i++)
0152         m_nodeMap["row_" + QString::number(i)].x = width() + offsetX();
0153 
0154     for (int j = 0; j < int(m_numCols); j++)
0155         m_nodeMap["col_" + QString::number(j)].x = 24 * j + offsetX() + 16;
0156 
0157     updateAttachedPositioning();
0158     // END Update Positions
0159 }
0160 
0161 void ECKeyPad::buttonStateChanged(const QString &id, bool state)
0162 {
0163     if (!id.startsWith("b_"))
0164         return;
0165 
0166     QStringList tags = id.split('_', Qt::SkipEmptyParts); // QStringList::split( '_', id ); // 2018.12.01
0167     const int i = tags[1].toInt();
0168     const int j = tags[2].toInt();
0169     m_switch[i][j]->setState(state ? Switch::Closed : Switch::Open);
0170 }