2024-02-14 09:12:29 +00:00
|
|
|
/*
|
|
|
|
* mui_mui_about.c
|
|
|
|
*
|
2024-02-15 10:45:46 +00:00
|
|
|
* Copyright (C) 2024 Michel Pollet <buserror@gmail.com>
|
2024-02-14 09:12:29 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "mui.h"
|
2024-05-13 15:31:58 +00:00
|
|
|
#include "mii_icon64.h"
|
2024-02-14 09:12:29 +00:00
|
|
|
|
2024-02-14 20:23:11 +00:00
|
|
|
extern const unsigned char mui_geneva_font_data[];
|
|
|
|
extern const unsigned int mui_geneva_font_size;
|
2024-02-14 09:12:29 +00:00
|
|
|
|
|
|
|
enum {
|
|
|
|
MII_ABOUT_WINDOW_ID = FCC('a','b','o','t'),
|
|
|
|
MII_ABOUT_OK = FCC('O','K','!',' '),
|
|
|
|
};
|
|
|
|
|
2024-02-14 20:23:11 +00:00
|
|
|
struct mui_drawable_control_t;
|
2024-02-14 09:12:29 +00:00
|
|
|
typedef struct mii_mui_about_t {
|
|
|
|
mui_window_t win;
|
2024-02-15 10:45:46 +00:00
|
|
|
mui_control_t * text;
|
2024-02-14 20:23:11 +00:00
|
|
|
uint8_t timer_id;
|
|
|
|
bool terminate;
|
2024-02-14 09:12:29 +00:00
|
|
|
} mii_mui_about_t;
|
|
|
|
|
2024-02-14 20:23:11 +00:00
|
|
|
static mui_time_t
|
|
|
|
mui_about_timer_cb(
|
2024-02-15 10:45:46 +00:00
|
|
|
struct mui_t * mui,
|
|
|
|
mui_time_t now,
|
|
|
|
void * param)
|
2024-02-14 20:23:11 +00:00
|
|
|
{
|
|
|
|
mii_mui_about_t * m = (mii_mui_about_t*)param;
|
|
|
|
|
|
|
|
if (m->terminate) {
|
|
|
|
mui_window_dispose(&m->win);
|
|
|
|
return 0;
|
|
|
|
}
|
2024-02-15 10:45:46 +00:00
|
|
|
mui_drawable_t * dr = mui_drawable_control_get_drawable(m->text);
|
2024-02-14 20:23:11 +00:00
|
|
|
|
|
|
|
dr->origin.y++;
|
2024-02-15 10:45:46 +00:00
|
|
|
int height = dr->pix.size.y + c2_rect_height(&m->text->frame);
|
2024-02-14 20:23:11 +00:00
|
|
|
if (dr->origin.y > dr->pix.size.y)
|
|
|
|
dr->origin.y -= height;
|
2024-02-15 10:45:46 +00:00
|
|
|
mui_control_inval(m->text);
|
2024-02-14 20:23:11 +00:00
|
|
|
return MUI_TIME_SECOND / 30;
|
|
|
|
}
|
|
|
|
|
2024-02-14 09:12:29 +00:00
|
|
|
|
|
|
|
static int
|
2024-02-14 20:23:11 +00:00
|
|
|
_mii_about_button_cb(
|
2024-02-14 09:12:29 +00:00
|
|
|
mui_control_t * c,
|
|
|
|
void * cb_param, // mii_mui_about_t
|
|
|
|
uint32_t what,
|
|
|
|
void * param) // not used
|
|
|
|
{
|
2024-05-13 15:31:58 +00:00
|
|
|
// printf("%s %4.4s\n", __func__, (char*)&what);
|
2024-02-14 09:12:29 +00:00
|
|
|
mii_mui_about_t * m = cb_param;
|
|
|
|
uint32_t uid = mui_control_get_uid(c);
|
|
|
|
|
|
|
|
switch (what) {
|
|
|
|
case MUI_CONTROL_ACTION_SELECT:
|
2024-02-15 10:45:46 +00:00
|
|
|
// printf("%s control %4.4s\n", __func__, (char*)&uid);
|
2024-02-14 09:12:29 +00:00
|
|
|
switch (uid) {
|
|
|
|
case MII_ABOUT_OK: {
|
2024-02-14 20:23:11 +00:00
|
|
|
m->terminate = true;
|
2024-02-14 09:12:29 +00:00
|
|
|
} break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-02-15 10:45:46 +00:00
|
|
|
static int
|
|
|
|
_mii_about_action_cb(
|
|
|
|
mui_window_t * w,
|
|
|
|
void * cb_param,
|
|
|
|
uint32_t what,
|
|
|
|
void * param) // not used
|
|
|
|
{
|
2024-05-13 15:31:58 +00:00
|
|
|
// printf("%s %4.4s\n", __func__, (char*)&what);
|
2024-02-15 10:45:46 +00:00
|
|
|
mii_mui_about_t * m = cb_param;
|
|
|
|
|
|
|
|
switch (what) {
|
|
|
|
case MUI_WINDOW_ACTION_CLOSE:
|
|
|
|
mui_timer_reset(w->ui, m->timer_id, mui_about_timer_cb, 0);
|
|
|
|
m->terminate = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2024-02-14 20:23:11 +00:00
|
|
|
|
|
|
|
#ifndef MII_VERSION
|
|
|
|
#define MII_VERSION "0.0.0"
|
|
|
|
#endif
|
|
|
|
static const char * about =
|
|
|
|
"\n"
|
|
|
|
"The MII " MUI_GLYPH_IIE " Emulator\n"
|
2024-03-13 08:45:11 +00:00
|
|
|
"" MII_VERSION "\n"
|
2024-02-14 20:23:11 +00:00
|
|
|
"Built " __DATE__ " " __TIME__ "\n"
|
|
|
|
"© Michel Pollet 2023-2024\n\n"
|
|
|
|
"Thanks to:\n"
|
|
|
|
;
|
|
|
|
static const char * thanksto =
|
|
|
|
"Steve Wozniak\n"
|
|
|
|
"Bill Atkinson\n"
|
|
|
|
"Andy Hertzfeld\n"
|
|
|
|
"Randy Wigginton\n"
|
|
|
|
"Jef Raskin\n"
|
|
|
|
"Susan Kare\n"
|
|
|
|
"Thierry Magniez\n"
|
2024-02-15 10:45:46 +00:00
|
|
|
"Matthew Bloch\n"
|
2024-02-14 20:23:11 +00:00
|
|
|
"Charles \"regnips\" Springer\n"
|
|
|
|
"Jeroen \"Sprite_tm\" Domburg\n"
|
|
|
|
"Claude \"Claude\" Schwarz\n"
|
|
|
|
"... and many others"
|
|
|
|
;
|
|
|
|
|
2024-02-14 09:12:29 +00:00
|
|
|
struct mui_window_t *
|
|
|
|
mii_mui_about(
|
|
|
|
struct mui_t *mui )
|
|
|
|
{
|
|
|
|
mui_t *ui = mui;
|
|
|
|
float base_size = mui_font_find(ui, "main")->size;
|
|
|
|
float margin = base_size * 0.7;
|
|
|
|
mui_window_t *w = mui_window_get_by_id(mui, MII_ABOUT_WINDOW_ID);
|
|
|
|
if (w) {
|
|
|
|
mui_window_select(w);
|
|
|
|
return w;
|
|
|
|
}
|
2024-05-13 15:31:58 +00:00
|
|
|
// printf("%s version: '%s'\n", __func__, MII_VERSION);
|
2024-02-14 09:12:29 +00:00
|
|
|
c2_pt_t where = {};
|
2024-03-13 08:45:11 +00:00
|
|
|
c2_rect_t wpos = C2_RECT_WH(where.x, where.y, 500, 255);
|
2024-02-14 09:12:29 +00:00
|
|
|
if (where.x == 0 && where.y == 0)
|
|
|
|
c2_rect_offset(&wpos,
|
|
|
|
(ui->screen_size.x / 2) - (c2_rect_width(&wpos) / 2),
|
|
|
|
(ui->screen_size.y * 0.4) - (c2_rect_height(&wpos) / 2));
|
|
|
|
w = mui_window_create(mui, wpos, NULL, MUI_WINDOW_LAYER_MODAL,
|
|
|
|
"About the MII " MUI_GLYPH_IIE " Emulator",
|
|
|
|
sizeof(mii_mui_about_t));
|
|
|
|
mui_window_set_id(w, MII_ABOUT_WINDOW_ID);
|
2024-02-15 10:45:46 +00:00
|
|
|
mui_window_set_action(w, _mii_about_action_cb, w);
|
2024-02-14 20:23:11 +00:00
|
|
|
|
2024-02-14 09:12:29 +00:00
|
|
|
mii_mui_about_t * m = (mii_mui_about_t*)w;
|
|
|
|
|
2024-02-14 20:23:11 +00:00
|
|
|
mui_control_t * c = NULL, *ok = NULL;
|
2024-02-14 09:12:29 +00:00
|
|
|
c2_rect_t cf;
|
|
|
|
cf = C2_RECT_WH(0, 0, base_size * 4, base_size * 1.4);
|
|
|
|
c2_rect_left_of(&cf, c2_rect_width(&w->content), margin);
|
|
|
|
c2_rect_top_of(&cf, c2_rect_height(&w->content), margin);
|
2024-02-14 20:23:11 +00:00
|
|
|
ok = c = mui_button_new(w,
|
2024-02-14 09:12:29 +00:00
|
|
|
cf, MUI_BUTTON_STYLE_DEFAULT,
|
|
|
|
"OK", MII_ABOUT_OK);
|
|
|
|
c->key_equ = MUI_KEY_EQU(0, 13);
|
2024-02-14 20:23:11 +00:00
|
|
|
mui_control_set_action(c, _mii_about_button_cb, w);
|
|
|
|
|
|
|
|
/*
|
|
|
|
Icon
|
|
|
|
*/
|
2024-02-15 10:45:46 +00:00
|
|
|
cf = C2_RECT_WH(margin, margin, mii_icon64[0], mii_icon64[1]);
|
|
|
|
mui_drawable_t *dr = mui_drawable_new(
|
|
|
|
C2_PT(mii_icon64[0], mii_icon64[1]),
|
|
|
|
32, NULL, 0);
|
2024-02-14 20:23:11 +00:00
|
|
|
/*
|
2024-02-15 10:45:46 +00:00
|
|
|
* Silly icon is in 64bpp, due to xorg requiring 'unsigned long' pixels.
|
|
|
|
* We need to convert it to 32bpp
|
2024-02-14 20:23:11 +00:00
|
|
|
*/
|
|
|
|
for (int y = 0; y < dr->pix.size.y; y++) {
|
|
|
|
for (int x = 0; x < dr->pix.size.x; x++) {
|
|
|
|
uint32_t *p = (uint32_t*)dr->pix.pixels;
|
|
|
|
p += y * dr->pix.size.x + x;
|
2024-02-15 10:45:46 +00:00
|
|
|
*p = mii_icon64[2 + y * dr->pix.size.x + x];
|
2024-02-14 20:23:11 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-15 10:45:46 +00:00
|
|
|
c = mui_drawable_control_new(w, cf, dr, NULL, 0);
|
2024-02-14 20:23:11 +00:00
|
|
|
/*
|
|
|
|
* Text in two parts
|
|
|
|
*/
|
|
|
|
cf = C2_RECT_WH(cf.r + margin, 10,
|
|
|
|
c2_rect_width(&w->frame) - cf.r - margin*2,
|
|
|
|
ok->frame.t - margin);
|
|
|
|
c2_rect_t tbox = cf;
|
|
|
|
c2_rect_offset(&tbox, -tbox.l, -tbox.t);
|
|
|
|
tbox.b = 1000;
|
|
|
|
mui_font_t *font = mui_font_find(ui, "main");
|
|
|
|
mui_font_t *geneva = mui_font_find(ui, "geneva");
|
|
|
|
if (!geneva) {
|
|
|
|
geneva = mui_font_from_mem(ui, "geneva", 24,
|
|
|
|
mui_geneva_font_data, mui_geneva_font_size);
|
|
|
|
}
|
|
|
|
mui_glyph_line_array_t lines_about = {};
|
2024-03-13 08:45:11 +00:00
|
|
|
mui_font_measure(font, tbox, about, 0, &lines_about,
|
|
|
|
MUI_TEXT_ALIGN_CENTER);
|
2024-02-14 20:23:11 +00:00
|
|
|
|
|
|
|
c2_rect_t about_frame = tbox;
|
|
|
|
about_frame.b = 0;
|
|
|
|
for (int li = 0; li < (int)lines_about.count; li++) {
|
|
|
|
mui_glyph_array_t * line = &lines_about.e[li];
|
|
|
|
about_frame.b = line->y;
|
|
|
|
}
|
|
|
|
mui_glyph_line_array_t lines_thanks = {};
|
2024-02-15 10:45:46 +00:00
|
|
|
mui_font_measure(geneva, tbox, thanksto, 0, &lines_thanks,
|
|
|
|
MUI_TEXT_ALIGN_CENTER);
|
2024-02-14 20:23:11 +00:00
|
|
|
c2_rect_t frame_thanks = tbox;
|
|
|
|
frame_thanks.b = 0;
|
|
|
|
for (int li = 0; li < (int)lines_thanks.count; li++) {
|
|
|
|
mui_glyph_array_t * line = &lines_thanks.e[li];
|
|
|
|
frame_thanks.b = line->y;
|
|
|
|
}
|
2024-03-13 08:45:11 +00:00
|
|
|
c2_rect_offset(&frame_thanks, 0, about_frame.b + 4);
|
2024-02-14 20:23:11 +00:00
|
|
|
|
|
|
|
tbox.b = frame_thanks.b + 2;
|
2024-02-15 10:45:46 +00:00
|
|
|
dr = mui_drawable_new(
|
|
|
|
C2_PT(c2_rect_width(&tbox), c2_rect_height(&tbox)),
|
|
|
|
32, NULL, 0);
|
|
|
|
memset(dr->pix.pixels, 0, dr->pix.size.y * dr->pix.row_bytes);
|
|
|
|
m->text = c = mui_drawable_control_new(w, cf, dr, NULL, 0);
|
2024-02-14 20:23:11 +00:00
|
|
|
|
|
|
|
mui_color_t text_color = MUI_COLOR(0x000000ff);
|
|
|
|
mui_font_measure_draw(font, dr, tbox, &lines_about,
|
|
|
|
text_color, MUI_TEXT_ALIGN_CENTER);
|
|
|
|
mui_font_measure_draw(geneva, dr, frame_thanks, &lines_thanks,
|
|
|
|
text_color, MUI_TEXT_ALIGN_CENTER);
|
2024-02-15 10:45:46 +00:00
|
|
|
mui_font_measure_clear(&lines_about);
|
|
|
|
mui_font_measure_clear(&lines_thanks);
|
2024-02-14 09:12:29 +00:00
|
|
|
|
2024-02-14 20:23:11 +00:00
|
|
|
m->timer_id = mui_timer_register(ui,
|
|
|
|
mui_about_timer_cb, m, MUI_TIME_SECOND);
|
2024-02-14 09:12:29 +00:00
|
|
|
return w;
|
|
|
|
}
|