HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

A simple analog clock using FLTK

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simpleusingclockfltkanalog

Problem

I'm implementing a graphical representation of an "analog clock" with moving hands (seconds, minutes and hours), using mainly2 FLTK facilities and the function Sleep(miliseconds):

main.cpp:

#include "iostream"
#include "GUI.h"
#include "Window.h"
using namespace Graph_lib;

#include "AnalogClock.h"

int main () 
try {

    Analog_clock ac (Point (700,30), "Analog clock"); 
    return gui_main ();

} catch (exception &e) {

    cerr << e.what () << endl;
    getchar();

}


AnalogClock.h:

```
#pragma once
#define PI 3.14159265

/*
class Analog_clock
It creates a GUI representing an analog clock
with three indicators: hour, minute, second
and a fancy dial.
*/
class Analog_clock: public Window {
public:
Analog_clock (Point xy, const string &label);

private:
// background image
Image clock_dial;

// data representing second, minute and hour
Line* second_indicator;
Line* minute_indicator;
Line* hour_indicator;

// helper functions
Point rotate (Point initial, Point pivot, double angle);
void set_clock ();
void run_clock ();

// action functions
void increment_second ();
void increment_minute ();
void increment_hour ();

// callback functions
/*
typedef void* Address;

template W& reference_to (Address pw) {
return *static_cast(pw);
}
*/

static void cb_seconds (Address, Address pw) { reference_to(pw).increment_second (); }
static void cb_minutes (Address, Address pw) { reference_to(pw).increment_minute (); }
static void cb_hours (Address, Address pw) { reference_to(pw).increment_hour (); }
};

//------------------------------------------------------------------------------------------------------------------------
// class member implementations
/*
class constructor: Analog_clock()
It initializes a window containing
an image (dial) and three lines
(indicators), together with a
function that runs the clock utilizing
the machine clock.

Solution

you shouldn't be using an infinite loop and sleep in a gui, instead use the timer functionality of FLTK using Fl::add_timeout and Fl::repeat_timeout

void timer_callback(void* window){
    reinterpret_cast(window)->increment_second();
    Fl::repeat_timeout(1, timer_callback, window);
}

void Analog_clock::run_clock () {
    Fl::add_timeout(1, timer_callback, this);
}

Analog_clock::increment_second(){

    //will also handle seconds overflow so minute and hour hand can be updated
}


Many gui libraries use a single thread and callbacks to manage events and draws, if you block in one of the callbacks then it can't handle any other event while it is blocking. This was the reason redraw didn't work.

repeat_timeout is like add_timeout except that it adds t (the time until callback should happen) to the time the current callback (should have) happened instead of now(). This way the time between timer_callback getting called and it calling repeat_timeout is not a factor.

Code Snippets

void timer_callback(void* window){
    reinterpret_cast<Analog_clock*>(window)->increment_second();
    Fl::repeat_timeout(1, timer_callback, window);
}

void Analog_clock::run_clock () {
    Fl::add_timeout(1, timer_callback, this);
}

Analog_clock::increment_second(){

    //will also handle seconds overflow so minute and hour hand can be updated
}

Context

StackExchange Code Review Q#111101, answer score: 2

Revisions (0)

No revisions yet.