例: カウントダウンタイマー
スクリーンショット
プロジェクトレイアウト
countdown_timer/ ├── CMakeLists.txt └── main.cpp
CMakeファイル
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(countdown_timer LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(FLTK 1.4 REQUIRED CONFIG)
add_executable(countdown_timer main.cpp)
target_link_libraries(countdown_timer PRIVATE fltk::fltk)
プログラムのソースコード
main.cpp:
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>
#include <format>
#include <string>
struct AppContext {
int start = 10;
int count = 0;
Fl_Box *digits;
Fl_Button *start_button;
Fl_Button *reset_button;
std::string sbuf;
};
AppContext *as_app_context(void *ptr) { return static_cast<AppContext *>(ptr); }
void update_digits_label(AppContext *ctx) {
ctx->sbuf.clear();
std::format_to(std::back_inserter(ctx->sbuf), "{}", ctx->count);
ctx->digits->label(ctx->sbuf.c_str());
}
void timeout_cb(void *data) {
auto ctx = as_app_context(data);
if (ctx->count <= 0) {
// Finished
ctx->start_button->label("スタート");
return;
}
--ctx->count;
update_digits_label(ctx);
Fl::repeat_timeout(1.0, timeout_cb, ctx);
}
void start_button_cb(Fl_Widget *w, void *data) {
if (!Fl::has_timeout(timeout_cb, data)) {
// Start button pressed
Fl::add_timeout(1.0, timeout_cb, data);
w->label("一時停止");
} else {
// Pause button pressed
Fl::remove_timeout(timeout_cb, data);
w->label("スタート");
}
}
void reset_button_cb(Fl_Widget *w, void *data) {
auto ctx = as_app_context(data);
ctx->count = ctx->start;
update_digits_label(ctx);
}
int main() {
auto window = new Fl_Window(300, 300, "Countdown Timer");
auto digits = new Fl_Box(10, 10, 280, 240);
digits->box(FL_DOWN_BOX);
digits->labelfont(FL_BOLD);
digits->labelsize(80);
digits->labeltype(FL_SHADOW_LABEL);
auto start_button = new Fl_Button(10, 260, 140, 30, "スタート");
auto reset_button = new Fl_Button(150, 260, 140, 30, "リセット");
int const countdown_start = 10;
AppContext ctx{
.start = countdown_start,
.count = countdown_start,
.digits = digits,
.start_button = start_button,
.reset_button = reset_button,
};
update_digits_label(&ctx);
start_button->callback(start_button_cb, &ctx);
reset_button->callback(reset_button_cb, &ctx);
window->end();
window->show();
return Fl::run();
}