Files
Upsilon/apps/shared/round_cursor_view.cpp
2020-07-13 10:36:47 +02:00

80 lines
2.5 KiB
C++

#include "round_cursor_view.h"
namespace Shared {
void RoundCursorView::drawRect(KDContext * ctx, KDRect rect) const {
KDRect r = bounds();
KDColor cursorWorkingBuffer[Dots::LargeDotDiameter*Dots::LargeDotDiameter];
#ifdef GRAPH_CURSOR_SPEEDUP
/* Beware that only the pixels of the intersection of rect with KDContext's
* clipping rect are pulled. All other pixels are left unaltered. Indeed
* nothing outside the clipping rect should be redrawn and hence was not
* dirty.
*/
ctx->getPixels(r, m_underneathPixelBuffer);
m_underneathPixelBufferLoaded = true;
#endif
ctx->blendRectWithMask(r, m_color, (const uint8_t *)Dots::LargeDotMask, cursorWorkingBuffer);
}
KDSize RoundCursorView::minimalSizeForOptimalDisplay() const {
return KDSize(k_cursorSize, k_cursorSize);
}
void RoundCursorView::setColor(KDColor color) {
m_color = color;
#ifdef GRAPH_CURSOR_SPEEDUP
eraseCursorIfPossible();
#endif
markRectAsDirty(bounds());
}
void RoundCursorView::setCursorFrame(KDRect f, bool force) {
#ifdef GRAPH_CURSOR_SPEEDUP
/* TODO This is quite dirty (we are out of the dirty tracking and we assume
* the cursor is the upmost view) but it works well. */
if (m_frame == f && !force) {
return;
}
/* We want to avoid drawing the curve just because the cursor has been
* repositioned, as it is very slow for non cartesian curves.*/
if (eraseCursorIfPossible()) {
// Set the frame
m_frame = f;
markRectAsDirty(bounds());
return;
}
#endif
CursorView::setCursorFrame(f, force);
}
void RoundCursorView::markRectAsDirty(KDRect rect) {
/* The CursorView class inherits from TransparentView, so does
* RoundCursorView. The method markRectAsDirty is thus overriden to avoid
* marking as dirty the background of the RoundCursorView in its superview.
*/
View::markRectAsDirty(rect);
}
#ifdef GRAPH_CURSOR_SPEEDUP
bool RoundCursorView::eraseCursorIfPossible() {
if (!m_underneathPixelBufferLoaded) {
return false;
}
const KDRect currentFrame = absoluteVisibleFrame();
if (currentFrame.isEmpty()) {
return false;
}
// Erase the cursor
KDColor cursorWorkingBuffer[k_cursorSize * k_cursorSize];
KDContext * ctx = KDIonContext::sharedContext();
ctx->setOrigin(absoluteOrigin());
ctx->setClippingRect(currentFrame);
KDSize cursorSize = KDSize(k_cursorSize, k_cursorSize);
ctx->fillRectWithPixels(KDRect(0, 0, cursorSize), m_underneathPixelBuffer, cursorWorkingBuffer);
// TODO Restore the context to previous values?
return true;
}
#endif
}