kcalc_bitset.cpp 4.78 KB
Newer Older
1
/*
2
3
Copyright (C) 2012 - 2013 Evan Teran
                          evan.teran@gmail.com
4

5
6
Copyright (C) 2006        Michel Marti
                          mma@objectxp.com
7

8
9
10
11
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.
12

13
14
15
16
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
17

18
19
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
*/

David Johnson's avatar
David Johnson committed
22
#include "kcalc_bitset.h"
23
#include "bitbutton.h"
David Johnson's avatar
David Johnson committed
24

Evan Teran's avatar
Evan Teran committed
25
#include <QButtonGroup>
Laurent Montel's avatar
Laurent Montel committed
26
27
#include <QGridLayout>
#include <QHBoxLayout>
Evan Teran's avatar
Evan Teran committed
28
#include <QLabel>
29
#include <QPainter>
30
#include <KLocalizedString>
31

32

33

34
35
36
37
// TODO: I think it would actually be appropriate to use a std::bitset<64>
//       for the internal representation of this class perhaps
//       the only real caveat is the conversion to/from quint64

38
//------------------------------------------------------------------------------
39
// Name: paintEvent
40
41
42
// Desc: draws the button
//------------------------------------------------------------------------------
void BitButton::paintEvent(QPaintEvent *) {
43

44
	uint8_t alpha = 0x60;
45
	QPainter painter(this);
46
	painter.setRenderHint(QPainter::Antialiasing, true);
47
	QPen pen(palette().text(), 1);
48
49
	pen.setJoinStyle(Qt::MiterJoin);
	painter.setPen(pen);
50

51
52
	if (on_) {
		painter.setBrush(palette().text());
53
		alpha = 0xB0;
54
55
56
	} else {
		painter.setBrush(palette().base());
	}
57

58
59
60
61
62
63
64
	if (over_) {
		painter.setBrush(QColor(palette().text().color().red(),
					palette().text().color().green(),
					palette().text().color().blue(),
					alpha));
	}

65
	painter.drawRect(rect().adjusted(1, 1, -1, -1));
66
67
}

68
//------------------------------------------------------------------------------
69
// Name: KCalcBitset
70
// Desc: constructor
71
//------------------------------------------------------------------------------
72
KCalcBitset::KCalcBitset(QWidget *parent) : QFrame(parent), bit_button_group_(new QButtonGroup(this)), value_(0) {
73
74

	setFrameStyle(QFrame::Panel | QFrame::Sunken);
75

Laurent Montel's avatar
Laurent Montel committed
76
	connect(bit_button_group_, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &KCalcBitset::slotToggleBit);
77
78
79
80
81
82
83
84
85

	// smaller label font
	QFont fnt = font();
	if (fnt.pointSize() > 6) {
		fnt.setPointSize(fnt.pointSize() - 1);
	}

	// main layout
	QGridLayout *layout = new QGridLayout(this);
Laurent Montel's avatar
Laurent Montel committed
86
    layout->setContentsMargins(2, 2, 2, 2);
87
88
89
90
91
92
93
94
	layout->setSpacing(0);

	// create bits
	int bitCounter = 63;
	for (int rows = 0; rows < 2; rows++) {
		for (int cols = 0; cols < 4; cols++) {
			// two rows of four words
			QHBoxLayout *const wordlayout = new QHBoxLayout();
Laurent Montel's avatar
Laurent Montel committed
95
            wordlayout->setContentsMargins(2, 2, 2, 2);
96
97
98
99
100
			wordlayout->setSpacing(2);
			layout->addLayout(wordlayout, rows, cols);

			for (int bit = 0; bit < 8; bit++) {
				BitButton *const tmpBitButton = new BitButton(this);
101
				tmpBitButton->setToolTip(i18n("Bit %1 = %2", bitCounter, 1ULL << bitCounter));
102
103
104
105
106
107
108
109
110
111
112
113
				wordlayout->addWidget(tmpBitButton);
				bit_button_group_->addButton(tmpBitButton, bitCounter);
				bitCounter--;
			}

			// label word
			QLabel *label = new QLabel(this);
			label->setText(QString::number(bitCounter + 1));
			label->setFont(fnt);
			wordlayout->addWidget(label);
		}
	}
114
115
}

116
//------------------------------------------------------------------------------
117
// Name: setValue
118
// Desc: set the value of the bitset based on an unsigned 64-bit number
119
//------------------------------------------------------------------------------
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
void KCalcBitset::setValue(quint64 value) {

	if (value_ == value) {
		// don't waste time if there was no change..
		return;
	}

	value_ = value;
	
	// set each bit button
	for (int i = 0; i < 64; i++) {	
		if(BitButton *bb = qobject_cast<BitButton*>(bit_button_group_->button(i))) {
			bb->setOn(value & 1);
		}
		value >>= 1;
	}
136
137
}

138
//------------------------------------------------------------------------------
139
// Name: getValue
140
// Desc: returns the bitset value as an unsigned 64-bit number
141
//------------------------------------------------------------------------------
142
quint64 KCalcBitset::getValue() const {
143
    return value_;
144
145
}

146
//------------------------------------------------------------------------------
147
// Name: slotToggleBit
148
// Desc: inverts the value of a single bit
149
//------------------------------------------------------------------------------
Laurent Montel's avatar
Laurent Montel committed
150
151
152
153
154
155
156
157
void KCalcBitset::slotToggleBit(QAbstractButton *button) {

    if (button) {
        const int bit = bit_button_group_->id(button);
        const quint64 nv = getValue() ^(1LL << bit);
        setValue(nv);
        emit valueChanged(value_);
    }
158
159
}