registerwidget.cpp
411 lines
| 10.6 KiB
| text/x-c
|
CppLexer
/ src / registerwidget.cpp
Jeandet Alexis
|
r5 | #include "registerwidget.h" | ||
#include <QPaintEvent> | ||||
#include <QPainter> | ||||
registerWidget::registerWidget(const QString &name, qint32 address, QObject *parent) : | ||||
QObject(parent) | ||||
{ | ||||
p_address = address; | ||||
p_value = 0; | ||||
Jeandet Alexis
|
r8 | p_addressEl = new regWidgetElement(QString("0x%1").arg((uint)p_address,8,16).replace(" ","0"),QFont("Utopia", 12),10,4); | ||
p_fieldsEl = new bitfieldsElement(QString("%1").arg((uint)p_value,32,2).replace(" ","0"),QFont("Utopia", 12),4,4); | ||||
Jeandet Alexis
|
r5 | p_nameEl = new regWidgetElement(name,QFont("Utopia", 12,QFont::Bold),4,4); | ||
p_xMargins = 4; | ||||
r9 | p_yMargins = 6; | |||
Jeandet Alexis
|
r5 | updateBoundingRect(); | ||
} | ||||
registerWidget::~registerWidget() | ||||
{ | ||||
delete p_addressEl; | ||||
delete p_fieldsEl; | ||||
delete p_nameEl; | ||||
} | ||||
int registerWidget::contains(const QPointF &point) | ||||
{ | ||||
return p_boundingRect.contains(point.x(),point.y()); | ||||
} | ||||
QPoint registerWidget::paint(QPainter* painter, QPoint offset) | ||||
{ | ||||
painter->save(); | ||||
painter->translate(offset); | ||||
p_boundingRect.moveTopLeft(offset); | ||||
painter->translate(p_addressEl->paint(painter)); | ||||
painter->translate(p_fieldsEl->paint(painter)); | ||||
p_nameEl->paint(painter); | ||||
painter->restore(); | ||||
return QPoint(0,p_boundingRect.height()+p_boundingRect.y()+p_yMargins); | ||||
} | ||||
QRect registerWidget::boundingRect() | ||||
{ | ||||
return p_boundingRect; | ||||
} | ||||
uint registerWidget::cursorIndex() | ||||
{ | ||||
return p_fieldsEl->cursorIndex(); | ||||
} | ||||
uint registerWidget::cursorIndex(int xPos) | ||||
{ | ||||
if(xPos>p_addressEl->boundingRect().width() && xPos<(p_addressEl->boundingRect().width()+p_fieldsEl->boundingRect().width())) | ||||
{ | ||||
return p_fieldsEl->cursorIndex(xPos-p_addressEl->boundingRect().width()); | ||||
} | ||||
r9 | return 0; | |||
} | ||||
void registerWidget::updateSelection(int index) | ||||
{ | ||||
p_fieldsEl->updateSelection(index); | ||||
emit this->repaint(); | ||||
Jeandet Alexis
|
r5 | } | ||
qint32 registerWidget::address() | ||||
{ | ||||
return p_address; | ||||
} | ||||
qint32 registerWidget::value() | ||||
{ | ||||
return p_value; | ||||
} | ||||
Jeandet Alexis
|
r11 | void registerWidget::setBitFieldAttribute(uint startIndex, uint stopIndex, const QString &name, const QString &description, bool rw) | ||
{ | ||||
if(startIndex<=stopIndex && stopIndex<32) | ||||
{ | ||||
int index= p_fieldsEl->addAttribute(name,description,rw ); | ||||
for(uint i=startIndex;i<=stopIndex;i++) | ||||
{ | ||||
p_fieldsEl->setAttribute(i,index); | ||||
} | ||||
} | ||||
} | ||||
QString registerWidget::bitFieldDesc(int bitIndex) | ||||
{ | ||||
if(bitIndex>=0 && bitIndex<32) | ||||
{ | ||||
return p_fieldsEl->description(bitIndex); | ||||
} | ||||
return QString("Out of range"); | ||||
} | ||||
QString registerWidget::bitFieldName(int bitIndex) | ||||
{ | ||||
if(bitIndex>=0 && bitIndex<32) | ||||
{ | ||||
return p_fieldsEl->name(bitIndex); | ||||
} | ||||
return QString("Out of range"); | ||||
} | ||||
QString registerWidget::bitFieldToHex(int bitIndex) | ||||
{ | ||||
if(bitIndex>=0 && bitIndex<32) | ||||
{ | ||||
return p_fieldsEl->valueHex(bitIndex); | ||||
} | ||||
return QString("Out of range"); | ||||
} | ||||
QString registerWidget::bitFieldToDec(int bitIndex) | ||||
{ | ||||
if(bitIndex>=0 && bitIndex<32) | ||||
{ | ||||
return p_fieldsEl->valueDec(bitIndex); | ||||
} | ||||
return QString("Out of range"); | ||||
} | ||||
QString registerWidget::bitFieldToBin(int bitIndex) | ||||
{ | ||||
Jeandet Alexis
|
r13 | if(bitIndex>=0 && bitIndex<32) | ||
{ | ||||
// TODO do the convertion | ||||
return p_fieldsEl->valueDec(bitIndex); | ||||
} | ||||
return QString("Out of range"); | ||||
Jeandet Alexis
|
r11 | } | ||
r14 | void registerWidget::setValue(qint32 value, bool updated) | |||
Jeandet Alexis
|
r5 | { | ||
this->p_value = value; | ||||
this->p_fieldsEl->setValue(QString("%1").arg((uint)p_value,32,2).replace(" ","0")); | ||||
r14 | this->p_fieldsEl->setUpdated(updated); | |||
Jeandet Alexis
|
r5 | emit this->repaint(); | ||
} | ||||
void registerWidget::blinkCursor() | ||||
{ | ||||
p_fieldsEl->blinkCursor(); | ||||
//repaint(); | ||||
} | ||||
void registerWidget::moveCursorLeft(int count) | ||||
{ | ||||
p_fieldsEl->moveCursorLeft(count); | ||||
p_fieldsEl->blinkCursor(); | ||||
} | ||||
void registerWidget::moveCursorRight(int count) | ||||
{ | ||||
p_fieldsEl->moveCursorRight(count); | ||||
p_fieldsEl->blinkCursor(); | ||||
} | ||||
void registerWidget::enter(int index) | ||||
{ | ||||
p_fieldsEl->enter(index); | ||||
} | ||||
void registerWidget::leave() | ||||
{ | ||||
p_fieldsEl->leave(); | ||||
} | ||||
void registerWidget::clear(int index) | ||||
{ | ||||
r14 | if(!this->p_fieldsEl->readonly(index)) | |||
{ | ||||
qint32 old = p_value; | ||||
p_value &= ~(1<<index); | ||||
if(old!=p_value) | ||||
p_fieldsEl->setUpdated(false); | ||||
this->p_fieldsEl->setValue(QString("%1").arg((uint)p_value,32,2).replace(" ","0")); | ||||
emit this->repaint(); | ||||
} | ||||
Jeandet Alexis
|
r5 | } | ||
void registerWidget::set(int index) | ||||
{ | ||||
Jeandet Alexis
|
r7 | if(!this->p_fieldsEl->readonly(index)) | ||
{ | ||||
r14 | qint32 old = p_value; | |||
Jeandet Alexis
|
r7 | p_value |= 1<<index; | ||
r14 | if(old!=p_value) | |||
p_fieldsEl->setUpdated(false); | ||||
Jeandet Alexis
|
r7 | this->p_fieldsEl->setValue(QString("%1").arg((uint)p_value,32,2).replace(" ","0")); | ||
emit this->repaint(); | ||||
} | ||||
Jeandet Alexis
|
r5 | } | ||
void registerWidget::updateBoundingRect() | ||||
{ | ||||
p_boundingRect.setHeight(p_fieldsEl->boundingRect().height()+(p_yMargins*2)); | ||||
p_boundingRect.setWidth(p_fieldsEl->boundingRect().width()+p_addressEl->boundingRect().width()+p_nameEl->boundingRect().width()+(p_xMargins*2)); | ||||
} | ||||
bitfieldsElement::bitfieldsElement(const QString &value, QFont font, int xMargin, int yMargin) | ||||
:regWidgetElement(value,font,xMargin,yMargin) | ||||
{ | ||||
Jeandet Alexis
|
r11 | this->attributesLUT.append(new bitFieldAttribute(false,"UNSUSED","UNSUSED")); | ||
Jeandet Alexis
|
r5 | for(int i=0;i<32;i++) | ||
{ | ||||
Jeandet Alexis
|
r7 | attributesIndex[i] = 0; | ||
Jeandet Alexis
|
r5 | } | ||
r9 | p_startSelectionIndex = -1; | |||
p_stopSelectionIndex = -1; | ||||
p_cursorIndex = -1; | ||||
p_dx=QFontMetrics(p_font).width("0")+4; | ||||
Jeandet Alexis
|
r5 | p_blinkTextBgColor = QColor(Qt::black); | ||
p_blinkTextColor = QColor(Qt::white); | ||||
r14 | p_outdated = QColor(Qt::red); | |||
Jeandet Alexis
|
r5 | p_cursorBlinkEnable = false; | ||
r14 | p_changed = false; | |||
r9 | updateBoundingRect(); | |||
Jeandet Alexis
|
r5 | } | ||
QPoint bitfieldsElement::paint(QPainter *painter) | ||||
{ | ||||
painter->fillRect(4,4,p_boundingRec.width(),p_boundingRec.height(),Qt::darkGray); | ||||
painter->fillRect(0,0,p_boundingRec.width(),p_boundingRec.height(),Qt::white); | ||||
painter->setFont(p_font); | ||||
r9 | int lastAttributeIndex = attributesIndex[31]; | |||
Jeandet Alexis
|
r5 | int xpos=p_xMargins; | ||
for(int i=0;i<(32/4);i++) | ||||
{ | ||||
for(int l = 0;l<4;l++) | ||||
{ | ||||
Jeandet Alexis
|
r13 | if(p_cursorBlinkEnable == false || (31-(int)p_cursorIndex) != ((i*4)+l)) | ||
Jeandet Alexis
|
r5 | { | ||
Jeandet Alexis
|
r13 | if((int)p_startSelectionIndex!=-1 && (int)p_stopSelectionIndex!=-1 && p_startSelectionIndex <=(uint)31-(uint)((i*4)+l) && p_stopSelectionIndex >=(uint)31-(uint)((i*4)+l)) | ||
Jeandet Alexis
|
r5 | { | ||
r9 | QPen svg = painter->pen(); | |||
painter->setPen(p_blinkTextColor); | ||||
painter->fillRect(xpos-1,0,p_dx,p_boundingRec.height(),Qt::blue); | ||||
painter->drawText(xpos,QFontMetrics(p_font).ascent()+p_yMargins,p_valueStr.at((i*4)+l)); | ||||
painter->setPen(svg); | ||||
Jeandet Alexis
|
r5 | } | ||
else | ||||
{ | ||||
r9 | if(attributesLUT[attributesIndex[31-((i*4)+l)]]->rw==false) | |||
{ | ||||
painter->fillRect(xpos-1,0,p_dx,p_boundingRec.height(),Qt::lightGray); | ||||
} | ||||
else | ||||
{ | ||||
painter->fillRect(xpos-1,0,p_dx,p_boundingRec.height(),Qt::white); | ||||
} | ||||
painter->drawText(xpos,QFontMetrics(p_font).ascent()+p_yMargins,p_valueStr.at((i*4)+l)); | ||||
Jeandet Alexis
|
r5 | } | ||
} | ||||
else | ||||
{ | ||||
QPen svg = painter->pen(); | ||||
painter->setPen(p_blinkTextColor); | ||||
painter->fillRect(xpos-1,0,p_dx,p_boundingRec.height(),p_blinkTextBgColor); | ||||
painter->drawText(xpos,QFontMetrics(p_font).ascent()+p_yMargins,p_valueStr.at((i*4)+l)); | ||||
painter->setPen(svg); | ||||
} | ||||
r9 | if(lastAttributeIndex!=attributesIndex[31-((i*4)+l)]) | |||
painter->drawLine(xpos-(p_xMargins/2),0,xpos-(p_xMargins/2),p_boundingRec.height()); | ||||
lastAttributeIndex=attributesIndex[31-((i*4)+l)]; | ||||
Jeandet Alexis
|
r5 | xpos+=p_dx; | ||
} | ||||
if(i==3) | ||||
r9 | painter->drawLine(xpos+(p_xMargins/2),p_boundingRec.height()-6,xpos+(p_xMargins/2),p_boundingRec.height()+12); | |||
Jeandet Alexis
|
r5 | else if(i<7) | ||
r9 | painter->drawLine(xpos+(p_xMargins/2),p_boundingRec.height()-6,xpos+(p_xMargins/2),p_boundingRec.height()+6); | |||
Jeandet Alexis
|
r5 | xpos+=p_xMargins; | ||
} | ||||
r14 | QPen svg = painter->pen(); | |||
if(p_changed) | ||||
{ | ||||
painter->setPen(p_outdated); | ||||
} | ||||
Jeandet Alexis
|
r5 | painter->drawRect(0,0,p_boundingRec.width(),p_boundingRec.height()); | ||
r14 | painter->setPen(svg); | |||
Jeandet Alexis
|
r5 | return QPoint(p_boundingRec.width()+4+p_xMargins,0); | ||
} | ||||
void bitfieldsElement::updateBoundingRect() | ||||
{ | ||||
p_boundingRec.setHeight(QFontMetrics(p_font).boundingRect(p_valueStr).height()+(p_yMargins*2)); | ||||
r9 | int width = (((4*(p_dx)) + p_xMargins) * 8) + (p_xMargins); | |||
Jeandet Alexis
|
r5 | p_boundingRec.setWidth(width); | ||
} | ||||
void bitfieldsElement::setValue(const QString &value) | ||||
{ | ||||
p_valueStr = value; | ||||
updateBoundingRect(); | ||||
} | ||||
void bitfieldsElement::blinkCursor() | ||||
{ | ||||
p_cursorBlinkEnable = !p_cursorBlinkEnable; | ||||
} | ||||
void bitfieldsElement::moveCursorLeft(int count) | ||||
{ | ||||
p_cursorIndex+=count; | ||||
if(31<p_cursorIndex) | ||||
{ | ||||
p_cursorIndex = 31; | ||||
} | ||||
r9 | p_startSelectionIndex = p_cursorIndex; | |||
p_stopSelectionIndex = p_cursorIndex; | ||||
Jeandet Alexis
|
r5 | |||
} | ||||
void bitfieldsElement::moveCursorRight(int count) | ||||
{ | ||||
p_cursorIndex -= count; | ||||
if(31<p_cursorIndex) | ||||
{ | ||||
p_cursorIndex = 0; | ||||
} | ||||
r9 | p_startSelectionIndex = p_cursorIndex; | |||
p_stopSelectionIndex = p_cursorIndex; | ||||
Jeandet Alexis
|
r5 | } | ||
void bitfieldsElement::enter(int index) | ||||
{ | ||||
p_cursorIndex = index; | ||||
p_cursorBlinkEnable = true; | ||||
r9 | p_startSelectionIndex = -1; | |||
p_stopSelectionIndex = -1; | ||||
Jeandet Alexis
|
r5 | } | ||
void bitfieldsElement::leave() | ||||
{ | ||||
p_cursorBlinkEnable = false; | ||||
r9 | p_cursorIndex = -1; | |||
p_startSelectionIndex = -1; | ||||
p_stopSelectionIndex = -1; | ||||
Jeandet Alexis
|
r5 | } | ||
uint bitfieldsElement::cursorIndex() | ||||
{ | ||||
return p_cursorIndex; | ||||
} | ||||
uint bitfieldsElement::cursorIndex(int xPos) | ||||
{ | ||||
uint index=0; | ||||
xPos-=p_xMargins; | ||||
if(xPos<p_boundingRec.width()) | ||||
{ | ||||
index = 31 - ((4*xPos)/((4*p_dx)+p_xMargins)); | ||||
} | ||||
return index; | ||||
} | ||||
void bitfieldsElement::setFont(QFont font) | ||||
{ | ||||
p_font = font; | ||||
p_dx=QFontMetrics(p_font).width("0")+2; | ||||
updateBoundingRect(); | ||||
} | ||||
r9 | ||||
void bitfieldsElement::updateSelection(int index) | ||||
{ | ||||
Jeandet Alexis
|
r13 | if((int)p_cursorIndex!=-1) | ||
r9 | { | |||
Jeandet Alexis
|
r13 | if((int)p_startSelectionIndex!=-1 && (int)p_stopSelectionIndex!= -1) | ||
r9 | { | |||
Jeandet Alexis
|
r13 | if((uint)index>=p_stopSelectionIndex) | ||
r9 | { | |||
p_stopSelectionIndex = index; | ||||
p_cursorIndex = index; | ||||
} | ||||
else | ||||
{ | ||||
p_startSelectionIndex = index; | ||||
p_cursorIndex = index; | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
Jeandet Alexis
|
r13 | if((uint)index>p_cursorIndex) | ||
r9 | { | |||
p_startSelectionIndex = p_cursorIndex; | ||||
p_stopSelectionIndex = index; | ||||
} | ||||
else | ||||
{ | ||||
p_startSelectionIndex = index; | ||||
p_stopSelectionIndex = p_cursorIndex; | ||||
} | ||||
} | ||||
} | ||||
} | ||||