1 #include "historypane.h"
2
3 #include "tundo.h"
4 #include "historytypes.h"
5
6 #include <QApplication>
7 #include <QPainter>
8 #include <QScrollBar>
9 #include <QFrame>
10 #include <QPaintEvent>
11 #include <QVBoxLayout>
12
13 #include <QMutex>
14
15 const int HISTORY_ITEM_HEIGHT = 20;
16
17 namespace {
18
19 const struct {
20 int historyType;
21 const char *pixmapFilename;
22 } historyTypeInfo[] = {
23 {HistoryType::Unidentified, "history_normal"},
24 {HistoryType::BrushTool, "history_brush"},
25 {HistoryType::EraserTool, "history_eraser"},
26 {HistoryType::FillTool, "history_fill"},
27 {HistoryType::PaintBrushTool, "history_paintbrush"},
28 {HistoryType::AutocloseTool, "history_autoclose"},
29 {HistoryType::GeometricTool, "history_geometric"},
30 {HistoryType::ControlPointEditorTool, "history_controlpointeditor"},
31 {HistoryType::EditTool_Move, "history_move"},
32 {HistoryType::FingerTool, "history_finger"},
33 //{HistoryType::PickTool, "history_pick"},
34 {HistoryType::Palette, "history_palette"},
35 {HistoryType::Fx, "history_fx"},
36 {HistoryType::Schematic, "history_schematic"},
37 {HistoryType::Xsheet, "history_xsheet"},
38 {HistoryType::FilmStrip, "history_filmstrip"},
39
40 {0, 0}};
41 };
42
43 class HistoryPixmapManager { // singleton
44
45 std::map<int, QPixmap> m_pms;
46
HistoryPixmapManager()47 HistoryPixmapManager() {}
48
49 public:
instance()50 static HistoryPixmapManager *instance() {
51 static HistoryPixmapManager _instance;
52 return &_instance;
53 }
54
getHistoryPm(int type)55 const QPixmap &getHistoryPm(int type) {
56 std::map<int, QPixmap>::iterator it;
57 it = m_pms.find(type);
58 if (it != m_pms.end()) return it->second;
59
60 int i;
61 for (i = 0; historyTypeInfo[i].pixmapFilename; i++)
62 if (type == historyTypeInfo[i].historyType) {
63 QString path =
64 QString(":Resources/") + historyTypeInfo[i].pixmapFilename + ".png";
65 it = m_pms.insert(std::make_pair(type, QPixmap(path))).first;
66 return it->second;
67 }
68
69 static const QPixmap standardCursorPixmap("history_unidentified.png");
70 it = m_pms.insert(std::make_pair(type, standardCursorPixmap)).first;
71 return it->second;
72 }
73 };
74 //-----------------------------------------------------------------------------
75 #if QT_VERSION >= 0x050500
HistoryField(QScrollArea * parent,Qt::WindowFlags flags)76 HistoryField::HistoryField(QScrollArea *parent, Qt::WindowFlags flags)
77 #else
78 HistoryField::HistoryField(QScrollArea *parent, Qt::WFlags flags)
79 #endif
80 : QFrame(parent, flags), m_scrollArea(parent) {
81 setObjectName("filmStripFrames");
82 setFrameStyle(QFrame::StyledPanel);
83
84 setFocusPolicy(Qt::StrongFocus); /*-- KeyboadでもTabキーでもFocusされる --*/
85
86 setFixedHeight(parentWidget()->height());
87 setMinimumWidth(std::max(parentWidget()->width(), 600));
88 }
89 //-----------------------------------------------------------------------------
90
updateContentHeight(int minimumHeight)91 void HistoryField::updateContentHeight(int minimumHeight) {
92 if (minimumHeight < 0)
93 minimumHeight = visibleRegion().boundingRect().bottom();
94 int contentHeight =
95 TUndoManager::manager()->getHistoryCount() * HISTORY_ITEM_HEIGHT;
96 if (contentHeight < minimumHeight) contentHeight = minimumHeight;
97 int parentHeight = parentWidget()->height();
98 if (contentHeight < parentHeight) contentHeight = parentHeight;
99 if (contentHeight != height()) setFixedHeight(contentHeight);
100 }
101
102 //-----------------------------------------------------------------------------
103
paintEvent(QPaintEvent * evt)104 void HistoryField::paintEvent(QPaintEvent *evt) {
105 QPainter p(this);
106
107 QRect clipRect = evt->rect();
108
109 int i0 = y2index(clipRect.top());
110 int i1 = y2index(clipRect.bottom());
111
112 int currentHistoryIndex = TUndoManager::manager()->getCurrentHistoryIndex();
113 int currentHistoryCount = TUndoManager::manager()->getHistoryCount();
114
115 QRect undoChipRect(0, 0, width(), HISTORY_ITEM_HEIGHT);
116 QRect undoIconRect(7, 2, 17, 17);
117
118 for (int i = i0; i <= i1; i++) {
119 if (0 <= i && i <= currentHistoryCount) {
120 QRect tmpRect = undoChipRect.translated(0, HISTORY_ITEM_HEIGHT * (i - 1));
121
122 bool isCurrent = (i == currentHistoryIndex);
123 bool isFuture = (i > currentHistoryIndex);
124
125 p.setPen(QColor(64, 64, 64));
126 p.setBrush((isFuture) ? QColor(150, 150, 150) : QColor(192, 192, 192));
127 if (isCurrent) p.setBrush(QColor(0, 0, 128));
128 p.drawRect(tmpRect);
129
130 // draw text
131 QFont fon = p.font();
132 fon.setItalic(isFuture);
133 p.setFont(fon);
134
135 p.setPen((isFuture) ? QColor(64, 64, 64) : Qt::black);
136 if (isCurrent) p.setPen(Qt::white);
137
138 tmpRect.adjust(30, 0, 0, 0);
139
140 TUndo *tmpUndo = TUndoManager::manager()->getUndoItem(i);
141 p.drawText(tmpRect, Qt::AlignLeft | Qt::AlignVCenter,
142 tmpUndo->getHistoryString());
143
144 QRect tmpIconRect = undoIconRect.translated(0, 20 * (i - 1));
145 p.drawPixmap(tmpIconRect, HistoryPixmapManager::instance()->getHistoryPm(
146 tmpUndo->getHistoryType()));
147 }
148 }
149 }
150
151 //-----------------------------------------------------------------------------
152
y2index(int y) const153 int HistoryField::y2index(int y) const { return y / HISTORY_ITEM_HEIGHT + 1; }
154
155 //-----------------------------------------------------------------------------
156
index2y(int index) const157 int HistoryField::index2y(int index) const {
158 return (index - 1) * HISTORY_ITEM_HEIGHT;
159 }
160
161 //-----------------------------------------------------------------------------
162
mousePressEvent(QMouseEvent * event)163 void HistoryField::mousePressEvent(QMouseEvent *event) {
164 int index = y2index(event->pos().y());
165 int historyCount = TUndoManager::manager()->getHistoryCount();
166
167 if (index > historyCount || index <= 0) return;
168
169 int currentIndex = TUndoManager::manager()->getCurrentHistoryIndex();
170
171 if (index == currentIndex) return;
172
173 if (index < currentIndex) // undo
174 {
175 for (int i = 0; i < (currentIndex - index); i++)
176 TUndoManager::manager()->undo();
177 } else // redo
178 {
179 for (int i = 0; i < (index - currentIndex); i++)
180 TUndoManager::manager()->redo();
181 }
182 }
183
184 //-----------------------------------------------------------------------------
185
exposeCurrent()186 void HistoryField::exposeCurrent() {
187 int currentIndex = TUndoManager::manager()->getCurrentHistoryIndex();
188
189 m_scrollArea->ensureVisible(0, index2y(currentIndex) + 10, 50, 10);
190 }
191
192 //-----------------------------------------------------------------------------
193 //-----------------------------------------------------------------------------
194 #if QT_VERSION >= 0x050500
HistoryPane(QWidget * parent,Qt::WindowFlags flags)195 HistoryPane::HistoryPane(QWidget *parent, Qt::WindowFlags flags)
196 #else
197 HistoryPane::HistoryPane(QWidget *parent, Qt::WFlags flags)
198 #endif
199 : QWidget(parent) {
200 m_frameArea = new QScrollArea(this);
201 m_field = new HistoryField(m_frameArea);
202
203 m_frameArea->setObjectName("filmScrollArea");
204 m_frameArea->setFrameStyle(QFrame::StyledPanel);
205 m_frameArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
206 m_frameArea->verticalScrollBar()->setObjectName("LevelStripScrollBar");
207
208 m_frameArea->setWidget(m_field);
209
210 // layout
211 QVBoxLayout *mainLayout = new QVBoxLayout();
212 mainLayout->setMargin(0);
213 { mainLayout->addWidget(m_frameArea, 1); }
214 setLayout(mainLayout);
215
216 setFocusProxy(m_field);
217 }
218 //-----------------------------------------------------------------------------
219
onHistoryChanged()220 void HistoryPane::onHistoryChanged() {
221 m_field->updateContentHeight();
222 m_field->exposeCurrent();
223 update();
224 }
225
226 //-----------------------------------------------------------------------------
227
resizeEvent(QResizeEvent * e)228 void HistoryPane::resizeEvent(QResizeEvent *e) {
229 m_field->updateContentHeight();
230 m_field->setFixedWidth(std::max(width(), 600));
231 }
232
233 //-----------------------------------------------------------------------------
234
showEvent(QShowEvent *)235 void HistoryPane::showEvent(QShowEvent *) {
236 connect(TUndoManager::manager(), SIGNAL(historyChanged()), this,
237 SLOT(onHistoryChanged()));
238 onHistoryChanged();
239 }
240
241 //-----------------------------------------------------------------------------
242
hideEvent(QHideEvent *)243 void HistoryPane::hideEvent(QHideEvent *) {
244 disconnect(TUndoManager::manager(), SIGNAL(historyChanged()), this,
245 SLOT(onHistoryChanged()));
246 }