aboutsummaryrefslogtreecommitdiffstats
path: root/examples/pugl_cairo_demo.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/pugl_cairo_demo.c')
-rw-r--r--examples/pugl_cairo_demo.c81
1 files changed, 66 insertions, 15 deletions
diff --git a/examples/pugl_cairo_demo.c b/examples/pugl_cairo_demo.c
index 0a4ddd9..6608bab 100644
--- a/examples/pugl_cairo_demo.c
+++ b/examples/pugl_cairo_demo.c
@@ -17,6 +17,10 @@
typedef struct {
PuglWorld* world;
PuglTestOptions opts;
+ double currentMouseX;
+ double currentMouseY;
+ double lastDrawnMouseX;
+ double lastDrawnMouseY;
unsigned framesDrawn;
int quit;
bool entered;
@@ -24,6 +28,11 @@ typedef struct {
} PuglTestApp;
typedef struct {
+ double x;
+ double y;
+} ViewScale;
+
+typedef struct {
int x;
int y;
int w;
@@ -37,6 +46,15 @@ static const Button buttons[] = {{128, 128, 64, 64, "1"},
{384, 384, 64, 64, "4"},
{0, 0, 0, 0, NULL}};
+static ViewScale
+getScale(const PuglView* const view)
+{
+ const PuglRect frame = puglGetFrame(view);
+ const ViewScale scale = {(frame.width - (512.0 / frame.width)) / 512.0,
+ (frame.height - (512.0 / frame.height)) / 512.0};
+ return scale;
+}
+
static void
roundedBox(cairo_t* cr, double x, double y, double w, double h)
{
@@ -93,18 +111,14 @@ buttonDraw(PuglTestApp* app, cairo_t* cr, const Button* but, const double time)
static void
postButtonRedisplay(PuglView* view)
{
- const PuglRect frame = puglGetFrame(view);
- const double width = frame.width;
- const double height = frame.height;
- const double scaleX = (width - (512 / width)) / 512.0;
- const double scaleY = (height - (512 / height)) / 512.0;
+ const ViewScale scale = getScale(view);
for (const Button* b = buttons; b->label; ++b) {
const double span = sqrt(b->w * b->w + b->h * b->h);
- const PuglRect rect = {(PuglCoord)((b->x - span) * scaleX),
- (PuglCoord)((b->y - span) * scaleY),
- (PuglSpan)ceil(span * 2.0 * scaleX),
- (PuglSpan)ceil(span * 2.0 * scaleY)};
+ const PuglRect rect = {(PuglCoord)((b->x - span) * scale.x),
+ (PuglCoord)((b->y - span) * scale.y),
+ (PuglSpan)ceil(span * 2.0 * scale.x),
+ (PuglSpan)ceil(span * 2.0 * scale.y)};
puglPostRedisplayRect(view, rect);
}
@@ -119,9 +133,6 @@ onDisplay(PuglTestApp* app, PuglView* view, const PuglExposeEvent* event)
cairo_clip_preserve(cr);
// Draw background
- const PuglRect frame = puglGetFrame(view);
- const double width = frame.width;
- const double height = frame.height;
if (app->entered) {
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
} else {
@@ -130,9 +141,8 @@ onDisplay(PuglTestApp* app, PuglView* view, const PuglExposeEvent* event)
cairo_fill(cr);
// Scale to view size
- const double scaleX = (width - (512 / width)) / 512.0;
- const double scaleY = (height - (512 / height)) / 512.0;
- cairo_scale(cr, scaleX, scaleY);
+ const ViewScale scale = getScale(view);
+ cairo_scale(cr, scale.x, scale.y);
// Draw button
for (const Button* b = buttons; b->label; ++b) {
@@ -140,6 +150,17 @@ onDisplay(PuglTestApp* app, PuglView* view, const PuglExposeEvent* event)
app, cr, b, app->opts.continuous ? puglGetTime(app->world) : 0.0);
}
+ // Draw mouse cursor
+ const double mouseX = app->currentMouseX / scale.x;
+ const double mouseY = app->currentMouseY / scale.y;
+ cairo_set_line_width(cr, 2.0);
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ cairo_move_to(cr, mouseX - 8.0, mouseY);
+ cairo_line_to(cr, mouseX + 8.0, mouseY);
+ cairo_move_to(cr, mouseX, mouseY - 8.0);
+ cairo_line_to(cr, mouseX, mouseY + 8.0);
+ cairo_stroke(cr);
+
++app->framesDrawn;
}
@@ -151,6 +172,20 @@ onClose(PuglView* view)
app->quit = 1;
}
+static PuglRect
+mouseCursorViewBounds(const PuglView* const view,
+ const double mouseX,
+ const double mouseY)
+{
+ const ViewScale scale = getScale(view);
+ const PuglRect rect = {(PuglCoord)floor(mouseX - (10.0 * scale.x)),
+ (PuglCoord)floor(mouseY - (10.0 * scale.y)),
+ (PuglSpan)ceil(20.0 * scale.x),
+ (PuglSpan)ceil(20.0 * scale.y)};
+
+ return rect;
+}
+
static PuglStatus
onEvent(PuglView* view, const PuglEvent* event)
{
@@ -172,6 +207,22 @@ onEvent(PuglView* view, const PuglEvent* event)
app->mouseDown = false;
postButtonRedisplay(view);
break;
+ case PUGL_MOTION:
+ // Redisplay to clear the old cursor position
+ puglPostRedisplayRect(
+ view,
+ mouseCursorViewBounds(view, app->lastDrawnMouseX, app->lastDrawnMouseY));
+
+ // Redisplay to show the new cursor position
+ app->currentMouseX = event->motion.x;
+ app->currentMouseY = event->motion.y;
+ puglPostRedisplayRect(
+ view,
+ mouseCursorViewBounds(view, app->currentMouseX, app->currentMouseY));
+
+ app->lastDrawnMouseX = app->currentMouseX;
+ app->lastDrawnMouseY = app->currentMouseY;
+ break;
case PUGL_POINTER_IN:
app->entered = true;
puglPostRedisplay(view);