You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktechlab/src/electronics/components/eckeypad.cpp

200 lines
5.1 KiB

/***************************************************************************
* Copyright (C) 2003,2005 by David Saxton *
* david@bluehaze.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "canvasitemparts.h"
#include "eckeypad.h"
#include "libraryitem.h"
#include "switch.h"
#include "ecnode.h"
#include <tdelocale.h>
Item* ECKeyPad::construct( ItemDocument *itemDocument, bool newItem, const char *id )
{
return new ECKeyPad( (ICNDocument*)itemDocument, newItem, id );
}
LibraryItem* ECKeyPad::libraryItem()
{
return new LibraryItem(
TQString("ec/keypad"),
i18n("Keypad"),
i18n("Switches"),
"keypad.png",
LibraryItem::lit_component,
ECKeyPad::construct );
}
const TQString 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" } };
ECKeyPad::ECKeyPad( ICNDocument *icnDocument, bool newItem, const char *id )
: Component( icnDocument, newItem, (id) ? id : "keypad" )
{
m_name = i18n("Keypad");
m_desc = i18n("Provides a numeric array of Push-to-Make switches, with 4 rows and a configurable number of columns.");
createProperty( "useToggles", Variant::Type::Bool );
property("useToggles")->setCaption( i18n("Use Toggles") );
property("useToggles")->setValue(false);
createProperty( "numCols", Variant::Type::Int );
property("numCols")->setCaption( i18n("Columns") );
property("numCols")->setMinValue(3);
property("numCols")->setMaxValue(9);
property("numCols")->setValue(3);
Variant * v = createProperty( "bounce", Variant::Type::Bool );
v->setCaption("Bounce");
v->setAdvanced(true);
v->setValue(false);
v = createProperty( "bounce_period", Variant::Type::Double );
v->setCaption("Bounce Period");
v->setAdvanced(true);
v->setUnit("s");
v->setValue(5e-3);
for ( int i = 0; i < 4; i++ )
createPin( 0, -32+i*24, 0, TQString("row_%1").arg(TQString::number(i)) );
m_numCols = 0;
}
ECKeyPad::~ECKeyPad()
{
}
TQString ECKeyPad::buttonID( int row, int col ) const
{
return TQString("b_%1_%2").arg(TQString::number(row)).arg(TQString::number(col));
}
int ECKeyPad::sideLength( unsigned numButtons ) const
{
return 8 + 24*numButtons;
}
void ECKeyPad::dataChanged()
{
initPins( dataInt("numCols") );
bool useToggle = dataBool("useToggles");
bool bounce = dataBool("bounce");
int bouncePeriod_ms = int(dataDouble("bounce_period")*1e3);
for ( unsigned i = 0; i < 4; i++ )
{
for ( unsigned j = 0; j < m_numCols; j++ )
{
button( buttonID(i,j) )->setToggle(useToggle);
m_switch[i][j]->setBounce( bounce, bouncePeriod_ms );
}
}
}
void ECKeyPad::initPins( unsigned numCols )
{
if ( numCols < 3 )
numCols = 3;
else if ( numCols > 9 )
numCols = 9;
if ( numCols == m_numCols )
return;
int w = sideLength(numCols);
int h = sideLength(4);
setSize( -int(w/16)*8, -int(h/16)*8, w, h, true );
if ( numCols > m_numCols )
{
// Adding columns
for ( unsigned i = 0; i < 4; i++ )
{
for ( unsigned j = m_numCols; j < numCols; j++ )
addButton( buttonID(i,j), TQRect( 0, 0, 20, 20 ), text[i][j] );
}
ECNode * cols[numCols];
for ( unsigned j = m_numCols; j < numCols; j++ )
cols[j] = createPin( 0, 64, 270, "col_" + TQString::number(j) );
for ( unsigned i = 0; i < 4; i++ )
{
ECNode * row = ecNodeWithID("row_"+TQString::number(i));
for ( unsigned j = m_numCols; j < numCols; j++ )
m_switch[i][j] = createSwitch( cols[j], row, true );
}
}
else
{
// Remove columns
for ( unsigned i = 0; i < 4; i++ )
{
for ( unsigned j = numCols; j < m_numCols; j++ )
removeWidget( buttonID(i,j) );
}
for ( unsigned j = numCols; j < m_numCols; j++ )
removeNode( "col_" + TQString::number(j) );
for ( unsigned i = 0; i < 4; i++ )
{
for ( unsigned j = m_numCols; j < numCols; j++ )
removeSwitch( m_switch[i][j] );
}
}
//BEGIN Update Positions
m_numCols = numCols;
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < int(m_numCols); j++ )
{
widgetWithID( buttonID(i,j) )->setOriginalRect(
TQRect( offsetX() + 6 + 24*j, offsetY() + 6 + 24*i, 20, 20 ) );
}
}
for ( int i = 0; i < 4; i++ )
m_nodeMap["row_" + TQString::number(i)].x = width()+offsetX();
for ( int j = 0; j < int(m_numCols); j++ )
m_nodeMap["col_" + TQString::number(j)].x = 24*j+offsetX()+16;
updateAttachedPositioning();
//END Update Positions
}
void ECKeyPad::buttonStateChanged( const TQString &id, bool state )
{
if ( !id.startsWith("b_") )
return;
TQStringList tags = TQStringList::split( '_', id );
const int i = tags[1].toInt();
const int j = tags[2].toInt();
m_switch[i][j]->setState( state ? Switch::Closed : Switch::Open );
}