/* Generated by: https://www.npmjs.com/package/jsfx-preprocessor */ @init uix_round = 1; /* temp */ //uix_hassetup = 0; //uix_screenstack = 0; uix_screenstack_step = 10 + 1/*UI_SCREEN: ID*/; // header + 10 vars uix_screenstack_layercount = 10; //uix_screenstack_currentlayer = 0; //uix_drawconfig = 0; uix_drawconfig_step = 27/*uix_DRAWCONFIG: RED, GREEN, BLUE, ALPHA, FONTBOLD, FONTITALIC, FONTINDEX, FONTFACE, FONTSIZE, RETINA_SCALING, CLIP_SCREEN, CLIP_LEFT, CLIP_WIDTH, CLIP_TOP, CLIP_HEIGHT, CLIP_ALPHA, LEFT, TOP, WIDTH, HEIGHT, HALIGN, VALIGN, HPADDING, VPADDING, SPLIT_DIRECTION, SPLIT_HEIGHT, SPLIT_WIDTH*/; uix_drawconfig_count = 100; //uix_drawconfig_current = 0; //uix_drawconfig_currentindex = -1; //uix_screen_reservations = 0; //uix_reserved_end = 0; //uix_mousecap_prev = 0; uix_mouseblocked = 0; uix_doubleclicktime = 0.2; uix_draglimit = 10; uix_click1count = uix_click2count = uix_click64count = 0; uix_click1 = uix_click2 = uix_click64 = 0; uix_unclick1 = uix_unclick2 = uix_unclick64 = 0; uix_click1_x = uix_click1_y = uix_click1_t = 0; // Left uix_click2_x = uix_click2_y = uix_click2_t = 0; // Right uix_click64_x = uix_click64_y = uix_click64_t = 0; // Middle uix_mouse_x = uix_prev_mouse_x = 0; uix_mouse_y = uix_prev_mouse_y = 0; uix_scroll_y = uix_scroll_x = 0; uix_scroll_scale = 5000; uix_drag_scale = 200; uix_interacted = 0; uix_default_fontsize = 16; uix_default_fontface = "Arial"; uix_font_dirty = 0; uix_latestchar = 0; uix_char_consumed = 0; // Used to work around what I think might be a JSFX bug, where srate is sometimes = 0 in @init, but only if @gfx is defined, the UI is displaying, *and* an earlier effect has set latency with pdc_delay. uix_prev_srate = 44100; uix_error = 0; function uix_clamp255(v) ( min(255, max(0, floor(v + 0.5))); ); function uix_setgfxcolorrgba(r, g, b, a) local(m, s) ( // Instead of per-channel clamp, we maintain hue at the expense of saturation and brightness m = min(min(0, r), min(g, b)); r -= m; g -= m; b -= m; s = max(max(255, r), max(g, b)); gfx_r = r/s; gfx_g = g/s; gfx_b = b/s; gfx_a = min(1, max(0, a)); 0; ); function uix_setgfxcolor() ( uix_setgfxcolorrgba( uix_drawconfig_current[0/*uix_DRAWCONFIG:RED*/], uix_drawconfig_current[1/*uix_DRAWCONFIG:GREEN*/], uix_drawconfig_current[2/*uix_DRAWCONFIG:BLUE*/], uix_drawconfig_current[3/*uix_DRAWCONFIG:ALPHA*/] ); ); function uix_clearcolor(r, g, b) ( uix_clamp255(r) + 256*uix_clamp255(g) + 65536*uix_clamp255(b); ); function uix_fontflags() local(bold, italic) ( bold = uix_drawconfig_current[4/*uix_DRAWCONFIG:FONTBOLD*/]; italic = uix_drawconfig_current[5/*uix_DRAWCONFIG:FONTITALIC*/]; bold ? ( italic ? 'bi' : 'b'; ) : ( italic ? 'i' : ''; ); ); function uix_setgfxfont() ( uix_font_dirty || gfx_getfont() != uix_drawconfig_current[6/*uix_DRAWCONFIG:FONTINDEX*/] ? ( uix_font_dirty = 0; uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/] == "bitmap" ? ( gfx_setfont(0); ) : ( gfx_setfont( uix_drawconfig_current[6/*uix_DRAWCONFIG:FONTINDEX*/], uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/], uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/], uix_fontflags() ); ); ); ); function uix_click_block() ( uix_mouseblocked = 1; uix_click1count = uix_click2count = uix_click64count = 0; uix_click1 = uix_click2 = uix_click64 = 0; uix_unclick1 = uix_unclick2 = uix_unclick64 = 0; uix_click1_x = uix_click1_y = uix_click1_t = 0; // Left uix_click2_x = uix_click2_y = uix_click2_t = 0; // Right uix_click64_x = uix_click64_y = uix_click64_t = 0; // Middle ); function uix_key_clear() ( while ( gfx_getchar() > 0; ); ); function ui_error(string) ( uix_click_block(); uix_key_clear(); uix_screenstack_currentlayer = 0; uix_screenstack[0/*UI_SCREEN:ID*/] = "error"; uix_error = uix_screenstack[1/*UI_SCREEN: ID*/] = string; // First argument 0; ); function ui_screen() ( uix_hassetup ? (uix_screenstack + uix_screenstack_step*uix_screenstack_currentlayer)[0] : "error"; ); function ui_screen_level() ( uix_screenstack_currentlayer; ); function ui_screen_open(id) local(i, screen) ( uix_click_block(); uix_key_clear(); uix_screenstack_currentlayer += 1; uix_screenstack_currentlayer < uix_screenstack_layercount ? ( screen = (uix_screenstack + uix_screenstack_step*uix_screenstack_currentlayer); screen[0] = id; i = 1; while ( screen[i] = 0; i += 1; i < uix_screenstack_step; ); ) : ui_error("Too many screens - only 10 dialogs deep") ); function ui_screen_close() ( uix_click_block(); uix_key_clear(); uix_screenstack_currentlayer > 0 ? ( uix_screenstack_currentlayer -= 1; ) : ui_error("Cannot close top-level screen"); ); function ui_screen_arg(index) local(screen, offset) ( screen = (uix_screenstack + uix_screenstack_step*uix_screenstack_currentlayer); offset = index + 1/*UI_SCREEN: ID*/; offset < uix_screenstack_step ? ( screen[offset]; ) : ( ui_error("Screens only have 10 arguments"); ); ); function ui_screen_arg(index, value) local(screen, offset) ( screen = (uix_screenstack + uix_screenstack_step*uix_screenstack_currentlayer); offset = index + 1; offset < uix_screenstack_step ? ( screen[offset] = value; ) : ( ui_error("Screens only have 10 arguments"); ); ); function uix_unreserved_screen_below(limit) ( limit = (limit < 0) ? 127 : limit - 1; while (limit > 0 && uix_screen_reservations[limit]) ( limit -= 1; ); limit; ); function ui_setup(stackstart) local(uix_screenstack_end, uix_drawconfig_end) ( // Mitigate some gnarly behaviour - see uix_prev_srate at top !srate ? ( srate = uix_prev_srate; debug.gnarly_srate_hack += 1; ); uix_prev_srate = srate; !uix_hassetup || stackstart != uix_screenstack ? ( uix_hassetup = 1; uix_screenstack = stackstart; uix_screenstack_currentlayer = 0; uix_screenstack_end = stackstart + uix_screenstack_step*uix_screenstack_layercount; uix_drawconfig = uix_screenstack_end; uix_drawconfig_end = uix_drawconfig + uix_drawconfig_step*uix_drawconfig_count; uix_reserved_end = uix_drawconfig_end; uix_screen_reservations = uix_reserved_end; uix_reserved_end += 128; // Stop the pre-processor complaining 4/*UI_SPLIT_DIRECTION: TOP, BOTTOM, LEFT, RIGHT*/; ); uix_reserved_end; ); function ui_reserve_image(index) ( uix_screen_reservations[index] = 1; ); function ui_start(defaultScreen) local(i, click, clickdelta, imgW, imgH, retina_scaling) ( uix_drawconfig_currentindex = 0; uix_drawconfig_current = uix_drawconfig; uix_hassetup ? ( !ui_screen() ? ( uix_screenstack_currentlayer = 0; i = 0; while ( uix_screenstack[i] = 0; i += 1; i < uix_screenstack_step; ); uix_screenstack[0] = defaultScreen; ); gfx_dest = -1; // Draw to main screen gfx_mode = 0; gfx_a = 1; // Default colours gfx_clear = uix_clearcolor(242, 242, 242); retina_scaling = gfx_ext_retina ? gfx_ext_retina : 1; uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] = retina_scaling; uix_drawconfig_current[10/*uix_DRAWCONFIG:CLIP_SCREEN*/] = -1; uix_drawconfig_current[11/*uix_DRAWCONFIG:CLIP_LEFT*/] = 0; uix_drawconfig_current[12/*uix_DRAWCONFIG:CLIP_WIDTH*/] = gfx_w; uix_drawconfig_current[13/*uix_DRAWCONFIG:CLIP_TOP*/] = 0; uix_drawconfig_current[14/*uix_DRAWCONFIG:CLIP_HEIGHT*/] = gfx_h; uix_drawconfig_current[15/*uix_DRAWCONFIG:CLIP_ALPHA*/] = 1; uix_drawconfig_current[0/*uix_DRAWCONFIG:RED*/] = 0; uix_drawconfig_current[1/*uix_DRAWCONFIG:GREEN*/] = 0; uix_drawconfig_current[2/*uix_DRAWCONFIG:BLUE*/] = 0; uix_drawconfig_current[3/*uix_DRAWCONFIG:ALPHA*/] = 1; uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] = 0; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] = 0; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = gfx_w/retina_scaling; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = gfx_h/retina_scaling; uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/] = 0.5; uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/] = 0.5; uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/] = 10; uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/] = 8; uix_drawconfig_current[6/*uix_DRAWCONFIG:FONTINDEX*/] = 16; uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/] = uix_default_fontface; uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/] = uix_default_fontsize; uix_drawconfig_current[4/*uix_DRAWCONFIG:FONTBOLD*/] = 0; uix_drawconfig_current[5/*uix_DRAWCONFIG:FONTITALIC*/] = 0; uix_font_dirty = 1; uix_setgfxfont(); uix_interacted = (!!mouse_cap) || (mouse_cap != uix_mousecap_prev); uix_undo_pending ? ( sliderchange(-1); uix_undo_pending = 0; ); uix_prev_mouse_x = uix_mouse_x; uix_prev_mouse_y = uix_mouse_y; uix_mouse_x = mouse_x/retina_scaling; uix_mouse_y = mouse_y/retina_scaling; (mouse_cap&67) && (uix_mouse_x != uix_prev_mouse_x || uix_mouse_y != uix_prev_mouse_y) ? uix_interacted = 1; uix_scroll_y = mouse_wheel; uix_scroll_x = mouse_hwheel; mouse_wheel = mouse_hwheel = 0; uix_scroll_y || uix_scroll_x ? uix_interacted = 1; uix_unclick1 = (!(mouse_cap&1) && uix_mousecap_prev&1); uix_click1 = (mouse_cap&1 && !(uix_mousecap_prev&1)) ? ( clickdelta = time_precise() - uix_click1_t; uix_click1_x = uix_mouse_x; uix_click1_y = uix_mouse_y; uix_click1 = 1; uix_click1_t = time_precise() - 0.001; clickdelta < uix_doubleclicktime ? ( uix_click1count += 1; ) : ( uix_click1count = 1; ); ); uix_unclick2 = (!(mouse_cap&2) && uix_mousecap_prev&2); uix_click2 = (mouse_cap&2 && !(uix_mousecap_prev&2)) ? ( clickdelta = time_precise() - uix_click2_t; uix_click2 = 1; uix_click2_x = uix_mouse_x; uix_click2_y = uix_mouse_y; uix_click2_t = time_precise() - 0.001; clickdelta < uix_doubleclicktime ? ( uix_click2count += 1; ) : ( uix_click2count = 1; ); ); uix_unclick64 = (!(mouse_cap&64) && uix_mousecap_prev&64); uix_click64 = (mouse_cap&64 && !(uix_mousecap_prev&64)) ? ( clickdelta = time_precise() - uix_click64_t; uix_click64 = 1; uix_click64_x = uix_mouse_x; uix_click64_y = uix_mouse_y; uix_click64_t = time_precise() - 0.001; clickdelta < uix_doubleclicktime ? ( uix_click64count += 1; ) : ( uix_click64count = 1; ); ); uix_mousecap_prev = mouse_cap; uix_mouseblocked ? uix_click_block(); // Must be first, so unclick events get removed too !(mouse_cap&1) && !(mouse_cap&2) && !(mouse_cap&64) ? uix_mouseblocked = 0; // Keyboard !uix_latestchar || !uix_char_consumed ? ( uix_latestchar = gfx_getchar(); uix_latestchar == -1 ? uix_latestchar = 0; ); uix_char_consumed = 0; uix_latestchar ? uix_interacted = 1; ) : ( uix_error = "ui_setup() has not been called"; ); ); function ui_system() local(text, error, screen) ( ui_screen() == "error" ? ( gfx_clear = 255 + 255*256 + 255*65536; gfx_r = 64; gfx_g = gfx_b = 0; gfx_x = gfx_y = gfx_texth; screen = uix_screenstack + uix_screenstack_step*uix_screenstack_currentlayer; error = screen[1/*UI_SCREEN: ID*/]; // First argument strlen(error) ? ( gfx_printf("Error: %s\n(%f)", error, error); ) : ( gfx_printf("Error: #%s", error); ); uix_click1 ? ( uix_screenstack_currentlayer = -1; ui_screen_open(0); ); ) : ( gfx_clear = 255 + 255*256 + 255*65536; gfx_r = gfx_g = gfx_b = 0; gfx_x = gfx_y = gfx_texth; ui_screen() ? ( gfx_printf("Unknown screen: %s (%f)", ui_screen(), ui_screen()); uix_click1 ? ( uix_screenstack_currentlayer = -1; ui_screen_open(0); ); ) : ( gfx_drawstr("Current screen is 0 - are you calling ui_start() first?"); ); ); ); function uix_undo_point(soft) local(time) ( time = time_precise(); // "Soft" means it only registers an undo point after 1.5s of no changes !soft || uix_last_unto_time < (time - 1500) ? ( uix_undo_pending = 1; ); uix_last_undo_time = time; ); function ui_automate(slidervar*, new_value) ( slidervar !== new_value ? ( slidervar = new_value; slider_automate(slidervar); 1 ) : 0; ); function ui_left() ( uix_round ? ( floor(uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + 0.5); ) : ( uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/]; ); ); function ui_left_retina() ( uix_round ? ( floor(uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] + 0.5); ) : ( uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); ); function ui_top() ( uix_round ? ( floor(uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + 0.5); ) : ( uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/]; ); ); function ui_top_retina() ( uix_round ? ( floor(uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] + 0.5); ) : ( uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); ); function ui_bottom() ( uix_round ? ( floor(uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] + 0.5); ) : ( uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] ); ); function ui_bottom_retina() ( uix_round ? ( floor((uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/])*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] + 0.5); ) : ( (uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/])*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] ); ); function ui_right() ( uix_round ? ( floor(uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] + 0.5); ) : ( uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]; ); ); function ui_right_retina() ( uix_round ? ( floor((uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/])*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] + 0.5); ) : ( (uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/])*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); ); function ui_width() ( uix_round ? ( ui_right() - ui_left(); ) : ( uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]; ); ); function ui_width_retina() ( uix_round ? ( ui_right_retina() - ui_left_retina(); ) : ( uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); ); function ui_height() ( uix_round ? ( ui_bottom() - ui_top(); ) : ( uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]; ); ); function ui_height_retina() ( uix_round ? ( ui_bottom_retina() - ui_top_retina(); ) : ( uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); ); /////// Drawing operations /////// function ui_color_refresh() ( uix_setgfxcolor(); ); function ui_color(r, g, b, a) ( uix_drawconfig_current[0/*uix_DRAWCONFIG:RED*/] = r; uix_drawconfig_current[1/*uix_DRAWCONFIG:GREEN*/] = g; uix_drawconfig_current[2/*uix_DRAWCONFIG:BLUE*/] = b; uix_drawconfig_current[3/*uix_DRAWCONFIG:ALPHA*/] = a; uix_setgfxcolor(); ); function ui_color(r, g, b) ( ui_color(r, g, b, 1); ); function ui_align(halign, valign) ( halign >= 0 && halign <= 1 ? uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/] = halign; valign >= 0 && valign <= 1 ? uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/] = valign; ); function ui_halign() ( uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]; ); function ui_valign() ( uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]; ); function ui_fontsize(size) ( size ? ( uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/] = size ? size : uix_default_fontsize; uix_font_dirty = 1; uix_setgfxfont(); ) : uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/]; ); function ui_fontface(face) ( uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/] = face; uix_font_dirty = 1; uix_setgfxfont(); ); function ui_fontbold(isBold) ( uix_drawconfig_current[4/*uix_DRAWCONFIG:FONTBOLD*/] = isBold; uix_font_dirty = 1; uix_setgfxfont(); ); function ui_fontitalic(isItalic) ( uix_drawconfig_current[5/*uix_DRAWCONFIG:FONTITALIC*/] = isItalic; uix_font_dirty = 1; uix_setgfxfont(); ); function ui_font(face, size, isBold, isItalic) ( face = face >= 0 ? face : uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/]; size = size >= 0 ? size : uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/]; uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/] = face; uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/] = size; uix_drawconfig_current[4/*uix_DRAWCONFIG:FONTBOLD*/] = isBold; uix_drawconfig_current[5/*uix_DRAWCONFIG:FONTITALIC*/] = isItalic; uix_font_dirty = 1; uix_setgfxfont(); ); function ui_font_refresh() ( uix_setgfxcolor(); uix_setgfxfont(); ); function ui_font() ( uix_font_dirty = 1; uix_setgfxcolor(); uix_setgfxfont(); ); function ui_fill() ( uix_setgfxcolor(); gfx_rect(ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); ); function ui_image_fill(imageBuffer, width, height, alpha) local(scaling, visibleWidth, visibleHeight, a) ( scaling = max(ui_width()/width, ui_height()/height); visibleWidth = ui_width()/scaling; visibleHeight = ui_height()/scaling; a = gfx_a; gfx_a = alpha; gfx_blit(imageBuffer, scaling, 0, (width - visibleWidth)*uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/], (height - visibleHeight)*uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/], visibleWidth, visibleHeight, ui_left(), ui_top(), ui_width(), ui_height()); gfx_a = a; ); function ui_image_fill(imageBuffer, width, height) ( ui_image_fill(imageBuffer, width, height, 1); ); function ui_image_fill(imageBuffer, alpha) local(width, height) ( gfx_getimgdim(imageBuffer, width, height); ui_image_fill(imageBuffer, width, height, alpha); ); function ui_image_fill(imageBuffer) ( ui_image_fill(imageBuffer, 1); ); function ui_texth_retina() ( uix_setgfxfont(); gfx_texth; ); function ui_texth() ( ui_texth_retina()/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); function ui_text_width(text) local(text_h, text_w) ( text >= 0 ? ( text_w = text_h = 0; uix_setgfxfont(); gfx_measurestr(text, text_w, text_h); text_w/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ) : 0; ); function ui_text_height(text) local(text_h, text_w) ( text >= 0 ? ( uix_setgfxfont(); gfx_measurestr(text, text_w, text_h); text_h/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ) : ui_texth(); ); function ui_text(text) local (text_h, text_w, boxwidth, boxheight, valign, halign, fontscale, fontsize) ( textw = texth = 0; text >= 0 ? ( uix_setgfxcolor(); uix_setgfxfont(); valign = uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]; halign = uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]; gfx_measurestr(text, text_w, text_h); boxwidth = ui_width_retina(); boxheight = ui_height_retina(); fontscale = 1; text_w > boxwidth ? ( fontscale = boxwidth/text_w; ); text_h > boxheight ? ( fontscale = min(boxheight/text_h, fontscale); ); fontscale != 1 ? ( fontsize = max(8, floor(fontscale*uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/])); // TODO: why is fontscale set here? fontscale = fontsize/uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/]; gfx_setfont( 16, uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/], fontsize, uix_fontflags() ); gfx_measurestr(text, text_w, text_h); ); valign = uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]; halign = uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]; gfx_x = ui_left_retina() + (boxwidth - text_w)*halign; gfx_y = ui_top_retina() + (boxheight - text_h)*valign; gfx_drawstr(text); ); text_w; ); function ui_textnumber(number, format) local(text) ( sprintf(#uix_textnumber, format ? format : "%f", number); ui_text(#uix_textnumber); ); function ui_textnumber(number) ( ui_textnumber(number, "%f"); ); function ui_parsenumber(text, default) local(text_length, i, char, result, digit, hadDigit, hadDecimal, decimalFactor) ( text_length = strlen(text); i = 0; result = 0; sign = 1; hadDigit = hadDecimal = 0; decimalFactor = 1; while (i < text_length) ( char = str_getchar(text, i, 'cu'); char == 45 && !hadDigit && !hadDecimal ? ( sign = -1; ) : char >= 48 && char <= 57 ? ( // 0-9 hadDigit = 1; digit = char - 48; result = digit + 10*result; hadDecimal ? decimalFactor *= 10; ) : char == 46 && !hadDecimal ? ( hadDecimal = 1; ) : char == 32 || char == 9 ? ( 0; // Whitespace - ignore ) : ( i = text_length; // stop on first invalid character ); i += 1; ); hadDigit ? sign*result/decimalFactor : default; ); function ui_parsenumber(number) ( ui_parsenumber(number, 0); ); function uix_fitline(text, start, text_end, width) local(i, result, line, line_end, char, hadspace, overflowed, text_w, text_h) ( line = #; strcpy(line, ""); line_end = 0; hadspace = 0; overflowed = 0; i = result = start; while (!overflowed && i < text_end) ( char = str_getchar(text, i); char == 10 ? ( result = i; overflowed = 1; ) : ( !hadspace ? result = i; char == 32 || char == 9 ? ( hadspace = 1; gfx_measurestr(line, text_w, text_h); overflowed = text_w > width; !overflowed ? result = i; ); str_setchar(line, line_end, char); line_end += 1; ); i += 1; ); !overflowed ? ( gfx_measurestr(line, text_w, text_h); overflowed = text_w > width; ); overflowed ? result : text_end; ); function ui_wraptext_height(text) local(text_length, line_start, line_end, width, height) ( uix_setgfxfont(); width = ui_width_retina(); height = 0; text_length = strlen(text); line_start = 0; while (line_start < text_length) ( line_end = uix_fitline(text, line_start, text_length, width); height += gfx_texth; line_start = line_end + 1; ); height/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); function ui_wraptext(text) local(text_length, line_start, line_end, width, height, line, halign, valign, text_h, text_w, left_x) ( uix_setgfxcolor(); uix_setgfxfont(); width = ui_width_retina(); height = 0; halign = uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]; valign = uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]; gfx_y = (valign ? ( ui_top() + (ui_height() - ui_wraptext_height(text))*valign; ) : ui_top())*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; text_length = strlen(text); line_start = 0; while (line_start < text_length) ( line_end = uix_fitline(text, line_start, text_length, width); line = #; strcpy_substr(line, text, line_start, line_end - line_start); gfx_measurestr(line, text_w, text_h); gfx_x = ui_left_retina() + (ui_width_retina() - text_w)*halign; gfx_drawstr(line); gfx_y += gfx_texth; height += gfx_texth; line_start = line_end + 1; ); height/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); function ui_border_top() ( uix_setgfxcolor(); gfx_line(ui_left_retina(), ui_top_retina(), ui_right_retina() - 1, ui_top_retina()); ); function ui_border_bottom() ( uix_setgfxcolor(); gfx_line(ui_left_retina(), ui_bottom_retina() - 1, ui_right_retina() - 1, ui_bottom_retina() - 1); ); function ui_border_left() ( uix_setgfxcolor(); gfx_line(ui_left_retina(), ui_top_retina(), ui_left_retina(), ui_bottom_retina() - 1); ); function ui_border_right() ( uix_setgfxcolor(); gfx_line(ui_right_retina() - 1, ui_top_retina(), ui_right_retina() - 1, ui_bottom_retina() - 1); ); function ui_border() ( uix_setgfxcolor(); gfx_x = ui_left_retina(); gfx_y = ui_top_retina(); gfx_lineto(ui_right_retina() - 1, gfx_y, 0); gfx_lineto(gfx_x, ui_bottom_retina() - 1, 0); gfx_lineto(ui_left_retina(), gfx_y, 0); gfx_lineto(gfx_x, ui_top_retina(), 0); ); ///// Viewport stack operations ///// function ui_push() local(i, oldlayer) ( uix_drawconfig_currentindex += 1; uix_drawconfig_currentindex < uix_drawconfig_count ? ( i = 0; oldlayer = uix_drawconfig_current; uix_drawconfig_current = uix_drawconfig + uix_drawconfig_currentindex*uix_drawconfig_step; while ( uix_drawconfig_current[i] = oldlayer[i]; i += 1; i < uix_drawconfig_step; ); // Some things shouldn't just be copied uix_drawconfig_current[24/*uix_DRAWCONFIG:SPLIT_DIRECTION*/] = -1; ); 0; ); function ui_set_rect(left, top, width, height) ( uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] = left; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] = top; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = width; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = height; ); function ui_set_rect_retina(left, top, width, height) ( uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] = left/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] = top/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = width/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = height/uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); function ui_retina(new_retina) local(old_retina, factor) ( new_retina ? ( old_retina = uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; factor = old_retina/new_retina; uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] = new_retina; uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] *= factor; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] *= factor; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] *= factor; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] *= factor; uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/] *= factor; old_retina; ) : uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ); function ui_push_rect(left, top, width, height) ( ui_push(); ui_set_rect(left, top, width, height); ); function ui_push_rect_retina(left, top, width, height) ( ui_push(); ui_set_rect_retina(left, top, width, height); ); function ui_pop() local(prev) ( prev = uix_drawconfig_current; uix_drawconfig_currentindex > 0 ? ( uix_drawconfig_currentindex -= 1; uix_drawconfig_current = uix_drawconfig + uix_drawconfig_currentindex*uix_drawconfig_step; prev[6/*uix_DRAWCONFIG:FONTINDEX*/] != uix_drawconfig_current[6/*uix_DRAWCONFIG:FONTINDEX*/] ? uix_font_dirty = 1; prev[7/*uix_DRAWCONFIG:FONTFACE*/] != uix_drawconfig_current[7/*uix_DRAWCONFIG:FONTFACE*/] ? uix_font_dirty = 1; prev[8/*uix_DRAWCONFIG:FONTSIZE*/] != uix_drawconfig_current[8/*uix_DRAWCONFIG:FONTSIZE*/] ? uix_font_dirty = 1; prev[4/*uix_DRAWCONFIG:FONTBOLD*/] != uix_drawconfig_current[4/*uix_DRAWCONFIG:FONTBOLD*/] ? uix_font_dirty = 1; prev[5/*uix_DRAWCONFIG:FONTITALIC*/] != uix_drawconfig_current[5/*uix_DRAWCONFIG:FONTITALIC*/] ? uix_font_dirty = 1; uix_font_dirty ? uix_setgfxfont(); prev[10/*uix_DRAWCONFIG:CLIP_SCREEN*/] != uix_drawconfig_current[10/*uix_DRAWCONFIG:CLIP_SCREEN*/] ? ( gfx_a = prev[15/*uix_DRAWCONFIG:CLIP_ALPHA*/]; gfx_dest = uix_drawconfig_current[10/*uix_DRAWCONFIG:CLIP_SCREEN*/]; gfx_x = prev[11/*uix_DRAWCONFIG:CLIP_LEFT*/]; gfx_y = prev[13/*uix_DRAWCONFIG:CLIP_TOP*/]; gfx_blit(prev[10/*uix_DRAWCONFIG:CLIP_SCREEN*/], 1, 0, prev[11/*uix_DRAWCONFIG:CLIP_LEFT*/], prev[13/*uix_DRAWCONFIG:CLIP_TOP*/], prev[12/*uix_DRAWCONFIG:CLIP_WIDTH*/], prev[14/*uix_DRAWCONFIG:CLIP_HEIGHT*/]); ); ); uix_setgfxcolor(); ); function uix_push_screen() local(oldscreen, newscreen) ( oldscreen = uix_drawconfig_current[10/*uix_DRAWCONFIG:CLIP_SCREEN*/]; newscreen = uix_unreserved_screen_below(oldscreen); gfx_setimgdim(newscreen, gfx_w, gfx_h); ui_push(); uix_drawconfig_current[15/*uix_DRAWCONFIG:CLIP_ALPHA*/] = 1; gfx_dest = uix_drawconfig_current[10/*uix_DRAWCONFIG:CLIP_SCREEN*/] = newscreen; gfx_a = 1; gfx_mode = 0; gfx_x = uix_drawconfig_current[11/*uix_DRAWCONFIG:CLIP_LEFT*/]; gfx_y = uix_drawconfig_current[13/*uix_DRAWCONFIG:CLIP_TOP*/]; gfx_blit(oldscreen, 1, 0, uix_drawconfig_current[11/*uix_DRAWCONFIG:CLIP_LEFT*/], uix_drawconfig_current[13/*uix_DRAWCONFIG:CLIP_TOP*/], uix_drawconfig_current[12/*uix_DRAWCONFIG:CLIP_WIDTH*/], uix_drawconfig_current[14/*uix_DRAWCONFIG:CLIP_HEIGHT*/]); uix_setgfxcolor(); ); function ui_push_clip(alpha) local(retina) ( !alpha ? alpha = 1; uix_push_screen(); retina = uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; uix_drawconfig_current[15/*uix_DRAWCONFIG:CLIP_ALPHA*/] = alpha; uix_drawconfig_current[11/*uix_DRAWCONFIG:CLIP_LEFT*/] = uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/]*retina; uix_drawconfig_current[13/*uix_DRAWCONFIG:CLIP_TOP*/] = uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/]*retina; uix_drawconfig_current[12/*uix_DRAWCONFIG:CLIP_WIDTH*/] = uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]*retina; uix_drawconfig_current[14/*uix_DRAWCONFIG:CLIP_HEIGHT*/] = uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]*retina; ); function ui_split_top(height) local(oldTop) ( height == -1 ? height = ui_texth() + uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]*2; height = min(height, uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); oldTop = uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/]; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] += height; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] -= height; ui_push(); uix_drawconfig_current[24/*uix_DRAWCONFIG:SPLIT_DIRECTION*/] = 0/*UI_SPLIT_DIRECTION:TOP*/; uix_drawconfig_current[25/*uix_DRAWCONFIG:SPLIT_HEIGHT*/] = height; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] = oldTop; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = height; height; ); function ui_split_topratio(ratio) ( ui_split_top(ratio*uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); ); function ui_split_toptext(text) local(text_height) ( text_height = max(ui_texth(), ui_text_height(text)); ui_split_top(text_height + 2*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]); ); function ui_split_bottom(height) local(oldBottom) ( height == -1 ? height = ui_texth() + uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]*2; height = min(height, uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); oldBottom = uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] -= height; ui_push(); uix_drawconfig_current[24/*uix_DRAWCONFIG:SPLIT_DIRECTION*/] = 1/*UI_SPLIT_DIRECTION:BOTTOM*/; uix_drawconfig_current[25/*uix_DRAWCONFIG:SPLIT_HEIGHT*/] = height; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] = oldBottom - height; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = height; height; ); function ui_split_bottomratio(ratio) ( ui_split_bottom(ratio*uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); ); function ui_split_bottomtext(text) ( text_height = max(ui_texth(), ui_text_height(text)); ui_split_bottom(text_height + 2*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]); ); function ui_split_left(width) local(oldLeft) ( width == -1 ? width = ui_texth()*4 + uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]*2; width = min(width, uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); oldLeft = uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/]; uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] += width; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] -= width; ui_push(); uix_drawconfig_current[24/*uix_DRAWCONFIG:SPLIT_DIRECTION*/] = 2/*UI_SPLIT_DIRECTION:LEFT*/; uix_drawconfig_current[26/*uix_DRAWCONFIG:SPLIT_WIDTH*/] = width; uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] = oldLeft; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = width; width; ); function ui_split_leftratio(ratio) ( ui_split_left(ratio*uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); ); function ui_split_lefttext(text) ( ui_split_left(ui_text_width(text) + 2*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]); ); function ui_split_right(width) local(oldRight) ( width == -1 ? width = ui_texth()*4 + uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]*2; width = min(width, uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); oldRight = uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] -= width; ui_push(); uix_drawconfig_current[24/*uix_DRAWCONFIG:SPLIT_DIRECTION*/] = 3/*UI_SPLIT_DIRECTION:RIGHT*/; uix_drawconfig_current[26/*uix_DRAWCONFIG:SPLIT_WIDTH*/] = width; uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] = oldRight - width; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = width; width; ); function ui_split_rightratio(ratio) ( ui_split_right(ratio*uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); ); function ui_split_righttext(text) ( ui_split_right(ui_text_width(text) + 2*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]); ); function ui_split_next() local(direction, width, height) ( direction = uix_drawconfig_current[24/*uix_DRAWCONFIG:SPLIT_DIRECTION*/]; width = uix_drawconfig_current[26/*uix_DRAWCONFIG:SPLIT_WIDTH*/]; height = uix_drawconfig_current[25/*uix_DRAWCONFIG:SPLIT_HEIGHT*/]; ui_pop(); direction == 2/*UI_SPLIT_DIRECTION:LEFT*/ ? ( ui_split_left(width); ) : direction == 0/*UI_SPLIT_DIRECTION:TOP*/ ? ( ui_split_top(height); ) : direction == 3/*UI_SPLIT_DIRECTION:RIGHT*/ ? ( ui_split_right(width); ) : direction == 1/*UI_SPLIT_DIRECTION:BOTTOM*/ ? ( ui_split_bottom(height); ) : ( ui_error("Called ui_split_next() without ui_split_*()"); ui_push(); ) ); function ui_push_height(height) ( height == -1 ? height = ui_texth() + uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]*2; ui_push(); height = min(height, uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] += (uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] - height)*uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = height; height; ); function ui_push_heightratio(ratio) ( ui_push_height(ratio*uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); ); function ui_push_heighttext(text) local(text_height) ( text_height = max(ui_texth(), ui_text_height(text)); ui_push_height(text_height + 2*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]); ); function ui_push_width(width) ( width == -1 ? width = ui_texth()*4 + uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]*2; ui_push(); width = min(width, uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] += (uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] - width)*uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = width; ); function ui_push_widthratio(ratio) ( ui_push_width(ratio*uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); ); function ui_push_widthtext(text) local(text_width) ( text_width = ui_text_width(text); ui_push_width(text_width + 2*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]); ); function ui_push_above(height) local(newheight) ( height == -1 ? height = ui_texth() + uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]*2; ui_push(); newheight = (uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] - height)*uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = newheight; newheight; ); function ui_push_aboveratio(ratio) ( ui_push_above(ratio*uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); ); function ui_push_abovetext(text) local(text_height) ( text_height = max(ui_texth(), ui_text_height(text)); ui_push_above(text_height + 2*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]); ); function ui_push_below(height) local(newheight) ( height == -1 ? height = ui_texth() + uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]*2; ui_push(); newheight = (uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] - height)*(1 - uix_drawconfig_current[21/*uix_DRAWCONFIG:VALIGN*/]); uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] = uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] + uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] - newheight; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] = newheight; newheight; ); function ui_push_belowratio(ratio) ( ui_push_below(ratio*uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/]); ); function ui_push_belowtext(text) local(text_height) ( text_height = max(ui_texth(), ui_text_height(text)); ui_push_below(text_height + 2*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]); ); function ui_push_leftof(width) local(newwidth) ( width == -1 ? width = ui_texth()*4 + uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]*2; ui_push(); newwidth = (uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] - width)*uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = newwidth; newwidth; ); function ui_push_leftofratio(ratio) ( ui_push_leftof(ratio*uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); ); function ui_push_leftoftext(text) local(text_width) ( text_width = ui_text_width(text); ui_push_leftof(text_width + 2*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]); ); function ui_push_rightof(width) local(newwidth) ( width == -1 ? width = ui_texth()*4 + uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]*2; ui_push(); newwidth = (uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] - width)*(1 - uix_drawconfig_current[20/*uix_DRAWCONFIG:HALIGN*/]); uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] = uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] + uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] - newwidth; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] = newwidth; newwidth; ); function ui_push_rightofratio(ratio) ( ui_push_rightof(ratio*uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/]); ); function ui_push_rightoftext(text) local(text_width) ( text_width = ui_text_width(text); ui_push_rightof(text_width + 2*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]); ); function ui_pad(l, t, r, b) ( l < 0 ? l = -l*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]; r < 0 ? r = -r*uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]; t < 0 ? t = -t*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]; b < 0 ? b = -b*uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]; uix_drawconfig_current[16/*uix_DRAWCONFIG:LEFT*/] += l; uix_drawconfig_current[17/*uix_DRAWCONFIG:TOP*/] += t; uix_drawconfig_current[18/*uix_DRAWCONFIG:WIDTH*/] -= l + r; uix_drawconfig_current[19/*uix_DRAWCONFIG:HEIGHT*/] -= t + b; ); function ui_pad(w, h) ( ui_pad(w, h, w, h); ); function ui_pad() ( ui_pad(-1, -1, -1, -1); ); function ui_padtop(n) ( ui_pad(0, n ? n : -1, 0, 0); ); function ui_padbottom(n) ( ui_pad(0, 0, 0, n ? n : -1); ); function ui_padleft(n) ( ui_pad(n ? n : -1, 0, 0, 0); ); function ui_padright(n) ( ui_pad(0, 0, n ? n : -1, 0); ); function ui_padding(hpadding, vpadding) ( hpadding >= 0 ? uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/] = hpadding; vpadding >= 0 ? uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/] = vpadding; ); function ui_padding_x() ( uix_drawconfig_current[22/*uix_DRAWCONFIG:HPADDING*/]; ); function ui_padding_y() ( uix_drawconfig_current[23/*uix_DRAWCONFIG:VPADDING*/]; ); //////// Mouse functions //////// function ui_interacted() ( uix_interacted; ); function uix_click_x(i) ( !i || i == 1 ? uix_click1_x : i == 2 ? uix_click2_x : i == 64 ? uix_click64_x : 0; ); function uix_click_y(i) ( !i || i == 1 ? uix_click1_y : i == 2 ? uix_click2_y : i == 64 ? uix_click64_y : 0; ); function uix_click_t(i) ( !i || i == 1 ? uix_click1_t : i == 2 ? uix_click2_t : i == 64 ? uix_click64_t : 0; ); function uix_click(i) ( !i || i == 1 ? uix_click1 : i == 2 ? uix_click2 : i == 64 ? uix_click64 : 0; ); function uix_unclick(i) ( !i || i == 1 ? uix_unclick1 : i == 2 ? uix_unclick2 : i == 64 ? uix_unclick64 : 0; ); function uix_clickcount(i) ( !i || i == 1 ? uix_click1count : i == 2 ? uix_click2count : i == 64 ? uix_click64count : 0; ); function uix_clickwasinside(i) ( !uix_mouseblocked && uix_click_x(i) >= ui_left() && uix_click_x(i) < ui_right() && uix_click_y(i) >= ui_top() && uix_click_y(i) < ui_bottom(); ); function ui_mouse_x() ( uix_mouse_x - ui_left(); ); function ui_mouse_xratio() ( ui_mouse_x()/ui_width(); ); function ui_mouse_y() ( uix_mouse_y - ui_top(); ); function ui_mouse_yratio() ( ui_mouse_y()/ui_height(); ); function ui_hover() ( uix_mouse_x >= ui_left() && uix_mouse_x < ui_right() && uix_mouse_y >= ui_top() && uix_mouse_y < ui_bottom(); ); function ui_mouse_down(i) ( uix_click(i) && ui_hover(); ); function ui_mouse_down_outside(i) ( uix_click(i) && !ui_hover(); ); function ui_mouse_up(i) ( uix_unclick(i) && ui_hover(); ); function ui_click_clear() ( uix_click_block(); ); function ui_drag(i) local(dragtime) ( !i ? i = 1; mouse_cap&i && uix_clickwasinside(i) ? ( dragtime = time_precise() - uix_click_t(i); dragtime >= uix_doubleclicktime || abs(uix_click_x(i) - uix_mouse_x) >= uix_draglimit || abs(uix_click_y(i) - uix_mouse_y) >= uix_draglimit ? ( dragtime; ) : 0; ) : 0; ); function ui_drag_up(i) local(dragtime) ( !i ? i = 1; uix_unclick(i) && uix_clickwasinside(i) ? ( dragtime = time_precise() - uix_click_t(i); dragtime >= uix_doubleclicktime || abs(uix_click_x(i) - uix_mouse_x) >= uix_draglimit || abs(uix_click_y(i) - uix_mouse_y) >= uix_draglimit ? ( dragtime; ) : 0; ) : 0; ); function ui_drag_x(i) ( !i ? i = 1; mouse_cap&i && uix_clickwasinside(i) ? ( uix_mouse_x - uix_click_x(i); ) : 0; ); function ui_drag_y(i) ( !i ? i = 1; mouse_cap&i && uix_clickwasinside(i) ? ( uix_mouse_y - uix_click_y(i); ) : 0; ); function ui_mouse_dx() ( uix_mouse_x - uix_prev_mouse_x; ); function ui_mouse_dy() ( uix_mouse_y - uix_prev_mouse_y; ); function ui_scroll_y() ( ui_hover() ? uix_scroll_y : 0; ); function ui_scroll_x() ( ui_hover() ? uix_scroll_x : 0; ); function ui_press(i) ( !i ? i = 1; ui_hover() && mouse_cap&i && uix_clickwasinside(i) ? ( time_precise() - uix_click_t(i); ) : 0; ); function ui_clickcount(i) ( uix_clickcount(i); ); function ui_click(i) ( ui_mouse_up(i) && uix_clickwasinside(i) && ui_hover() ? ( time_precise() - uix_click_t(i); ) : 0; ); function ui_key() ( uix_latestchar; ); function ui_key_printable() ( uix_latestchar >= 32 && uix_latestchar < 127 ? ( uix_latestchar; ) : 0; ); function ui_key_next() ( uix_char_consumed = 1; uix_latestchar = gfx_getchar(); uix_latestchar == -1 ? uix_latestchar = 0; uix_latestchar; ); //////// Fancy graphics //////// function ui_graph_step(buffer, length, step, offset, modulo_length, low, high) local(i, i2, v, x, y, mid, top, bottom, height, left, width) ( low == high ? ( i = 0; mid = low; while (i < length) ( v = buffer[i*step]; low = min(low, v); high = max(high, v); i += 1; ); // Keep it symmetrical low = min(low, 2*mid - high); high = max(high, 2*mid - low); ); length < 1 ? length = 1; modulo_length = max(1, max(length>>4, modulo_length)); top = ui_top_retina() + 0.5; bottom = ui_bottom_retina() - 0.5; height = ui_height_retina() - 1; left = ui_left_retina(); width = ui_width_retina() - 1; i = 0; while (i < length) ( i2 = i + offset; while (i2 < 0) (i2 += modulo_length); while (i2 >= modulo_length) (i2 -= modulo_length); v = buffer[i2*step]; x = left + i/(length - 1)*width; y = top + max(0, min(1, (v - high)/(low - high)))*height; i == 0 ? ( gfx_x = x; gfx_y = y; ) : ( gfx_lineto(x, y); ); i += 1; ); (high - low)/2; ); function ui_graph_step(buffer, length, step, offset, low, high) ( ui_graph_step(buffer, length, step, offset, length, low, high); ); function ui_graph_step(buffer, length, step, low, high) ( ui_graph_step(buffer, length, step, 0, length, low, high); ); function ui_graph(buffer, length, offset, modulo_length, low, high) local(points, step) ( step = 1; points = min(length, ui_width()*4); step = max(1, ceil(length/points)); ui_graph_step(buffer + (offset%step), floor(length/step), step, floor(offset/step), floor(modulo_length/step), low, high); ); function ui_graph(buffer, length, offset, low, high) ( ui_graph(buffer, length, offset, length, low, high); ); function ui_graph(buffer, length, low, high) ( ui_graph(buffer, length, 0, low, high); ); /////////////// DEBUG/TUTORIAL /////////////// function ui_debug() local(oldR, oldG, oldB, oldA, oldX, oldY, oldFont, i, corner, config, top, left, bottom, right, textX, textY, textW, textH, hue) ( oldR = gfx_r; oldG = gfx_g; oldB = gfx_b; oldA = gfx_a; oldX = gfx_x; oldY = gfx_y; oldFont = gfx_getfont(); gfx_setfont(0); gfx_a = 0.6; i = 0; while (i <= uix_drawconfig_currentindex) ( config = uix_drawconfig + uix_drawconfig_step*i; left = config[16/*uix_DRAWCONFIG:LEFT*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; top = config[17/*uix_DRAWCONFIG:TOP*/]*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; right = (config[16/*uix_DRAWCONFIG:LEFT*/] + config[18/*uix_DRAWCONFIG:WIDTH*/])*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] - 1; bottom = (config[17/*uix_DRAWCONFIG:TOP*/] + config[19/*uix_DRAWCONFIG:HEIGHT*/])*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/] - 1; sprintf(#uix_debug_text, "%i", i + 1); gfx_measurestr(#uix_debug_text, textW, textH); corner = 0; while (corner < 4) ( gfx_r = gfx_g = gfx_b = 1; textX = left + 2; textY = top + 2; (corner%4 == 1 || corner%4 == 2) ? ( textX = right - 1 - textW; ); (corner%4 > 1) ? ( textY = bottom - 1 - textH; ); gfx_rect(textX - 1, textY - 1, textW + 3, textH + 3); hue = $pi*sqrt(2)*i + time_precise()*0.1; gfx_r = max(0, min(1, 0.5 + sin(hue)))*0.6; gfx_g = max(0, min(1, 0.5 + sin(hue + $pi*2/3)))*0.6; gfx_b = max(0, min(1, 0.5 + sin(hue + $pi*4/3)))*0.6; gfx_x = textX; gfx_y = textY; gfx_drawstr(#uix_debug_text); corner += 1; ); gfx_line(left, top, right, top); gfx_line(right, top, right, bottom); gfx_line(right, bottom, left, bottom); gfx_line(left, bottom, left, top); i += 1; ); gfx_r = oldR; gfx_g = oldG; gfx_b = oldB; gfx_a = oldA; gfx_x = oldX; gfx_y = oldY; gfx_setfont(oldFont); ); /////////////// LEVEL 2 /////////////// // Total number of themes: 4/*uix_THEME: TRON, BITMAP_SIMPLE*/ uix_control_theme = 0/*uix_THEME:DEFAULT*/; uix_control_theme_prev = -1; uix_control_width_prev = -1; uix_control_height_prev = -1; // Claim this screen for our own use uix_control_reserved_screen = ui_reserve_image(127); function uix_control_color_from_theme(x, y, a) local(old_dest, r, g, b, old_x, old_y) ( old_x = gfx_x; old_y = gfx_y; old_dest = gfx_dest; gfx_dest = uix_control_theme_buffer; gfx_x = x; gfx_y = y; gfx_getpixel(r, g, b); gfx_dest = old_dest; gfx_x = old_x; gfx_y = old_y; ui_color(r*255, g*255, b*255, a); ); function uix_control_color_from_theme(x, y) ( uix_control_color_from_theme(x, y, 1); ); function control_start(defaultPage, theme, imageBuffer) local(reset, i, x, y) ( ui_start(defaultPage); // TODO: check retina here? reset = (uix_control_theme_prev != theme || uix_control_width_prev != gfx_w || uix_control_height_prev != gfx_h); uix_control_theme_prev = theme; uix_control_width_prev = gfx_w; uix_control_height_prev = gfx_h; theme == "black" ? ( uix_control_theme = 1/*uix_THEME:BLACK_AND_WHITE*/; gfx_clear = 0; ui_color(255, 255, 255); ui_fontface("Trebuchet MS"); ui_fontsize(20); ui_padding(10, 10); ) : theme == "tron" ? ( uix_control_theme = 2/*uix_THEME:TRON*/; gfx_clear = $x454545; reset ? ( gfx_setimgdim(uix_control_reserved_screen, gfx_w, gfx_h); gfx_dest = uix_control_reserved_screen; ui_color(70, 70, 70); ui_fill(); ui_color(67, 67, 67); gfx_y = 0; while (gfx_y < gfx_h) ( gfx_line(0, gfx_y, gfx_w, gfx_y); gfx_y += 2; ); gfx_dest = -1; ); gfx_x = gfx_y = 0; gfx_blit(uix_control_reserved_screen, 1, 0); ui_color(245, 255, 255); ui_fontface("Verdana"); ) : theme == "bitmap-simple" ? ( uix_control_theme = 3/*uix_THEME:BITMAP_SIMPLE*/; uix_control_theme_buffer = imageBuffer; y = 0; while (y < gfx_h) ( x = 0; while (x < gfx_w) ( gfx_blit(uix_control_theme_buffer, ui_retina(), 0, 20, 20, 120, 120, x, y); x += 120*ui_retina(); ); y += 120; ); uix_control_color_from_theme(151, 30); ) : ( uix_control_theme = 0/*uix_THEME:DEFAULT*/; //ui_color(242, 242, 242); ); ); function control_start(defaultPage, theme) ( control_start(defaultPage, theme, 0); ); function control_state() ( ui_press() ? "press" : ui_hover() ? "hover" : ui_drag() ? "drag" : "none"; ); function uix_gloss(strength) local(width, height, topalpha, bottomalpha) ( // White fade height = ui_height_retina()*0.5; topalpha = strength*0.3; bottomalpha = 0; gfx_gradrect( ui_left_retina(), ui_top_retina(), ui_width_retina(), height, 1, 1, 1, topalpha, 0, 0, 0, 0, 0, 0, 0, (bottomalpha - topalpha)/height ); // Black fade height = ui_height_retina()*0.5; topalpha = 0; bottomalpha = strength*0.1; gfx_gradrect( ui_left_retina(), ui_bottom_retina() - height, ui_width_retina(), height, 0, 0, 0, topalpha, 0, 0, 0, 0, 0, 0, 0, (bottomalpha - topalpha)/height ); // Black fade 2 height = ui_height_retina()*0.2; topalpha = 0; bottomalpha = strength*0.1; gfx_gradrect( ui_left_retina(), ui_bottom_retina() - height, ui_width_retina(), height, 0, 0, 0, topalpha, 0, 0, 0, 0, 0, 0, 0, (bottomalpha - topalpha)/height ); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( // Left fade width = min(ui_width_retina()*0.3, 5); topalpha = strength*0.05; bottomalpha = 0; gfx_gradrect( ui_left_retina(), ui_top_retina(), width, ui_height_retina(), 1, 1, 1, topalpha, 0, 0, 0, (bottomalpha - topalpha)/width, 0, 0, 0, 0 ); // Right fade topalpha = strength*0.05; bottomalpha = 0; gfx_gradrect( ui_right_retina() - width, ui_top_retina(), width, ui_height_retina(), 1, 1, 1, 0, 0, 0, 0, -(bottomalpha - topalpha)/width, 0, 0, 0, 0 ); ); ui_color(0, 0, 0, 0.1); ui_border(); ); function uix_circle_shade(x, y, r, angle, shadowstrength) ( ui_push(); ui_color(255, 255, 255, 0.3); gfx_arc(x, y + 1, r, -1.5 + angle, 1.5 + angle, 1); gfx_arc(x, y + 1, r - 0.3, -1 + angle, 1 + angle, 1); gfx_a = 0.15; //gfx_arc(x, y + 2, r, -0.5 + angle, 0.5 + angle, 1); angle += $pi; ui_color(0, 0, 0, 0.2*shadowstrength); gfx_arc(x, y - 1, r, -1.2 + angle, 1.2 + angle, 1); gfx_arc(x, y - 1, r, -0.8 + angle, 0.8 + angle, 1); gfx_a = 0.15; //gfx_arc(x, y - 2, r, -0.5 + angle, 0.5 + angle, 1); ui_color(0, 0, 0, 0.1); gfx_circle(x, y, r, 0, 1); ui_pop(); ); function uix_dotted_line(x1, y1, x2, y2, drawlength, skiplength) local(distance, steps, drawR, i, r1, r2) ( distance = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)); steps = distance/(drawlength + skiplength); x1 = floor(x1) + 0.5; y1 = floor(y1) + 0.5; x2 = floor(x2) + 0.5; y2 = floor(y2) + 0.5; drawR = (drawlength - 1)/(drawlength + skiplength); i = 0; while (i < steps) ( r1 = i/steps; r2 = min(1, (i + drawR)/steps); gfx_line(x1 + (x2 - x1)*r1, y1 + (y2 - y1)*r1, x1 + (x2 - x1)*r2, y1 + (y2 - y1)*r2, 1); i += 1; ); ); function uix_control_state(state) ( (!state || state == "auto") ? control_state() : state; ); function control_background_enabled(state) local(shade) ( state = uix_control_state(state); shade = (state == "press") ? 0.5 : (state == "hover") ? 0.75 : (state == "drag") ? 0.75 : 1; uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_push(); ui_color(255*shade, 255*shade, 255*shade); ui_pad(2, 2); ui_fill(); ui_pop(); ui_color(0, 0, 0); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( shade = 1.5 - shade; ui_push(); ui_color(203*shade, 213*shade, 215*shade); ui_pad(2, 2); ui_fill(); ui_pop(); ui_color(0, 0, 0); state == "press" || state == "hover" ? ( ui_color(200, 240, 255); ) : ( ui_color(162, 228, 255); ); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( state == "press" ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 180, 140, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(311, 150); ) : state == "hover" ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 180, 260, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(311, 270); ) : state == "drag" ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 180, 380, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(311, 390); ) : ( gfx_blit(uix_control_theme_buffer, 1, 0, 180, 20, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(311, 30); ); ) : ( ui_color(64*shade, 102*shade, 140*shade); ui_fill(); (state == "press") ? ui_color(230, 230, 230) : ui_color(255, 255, 255); ); ); function uix_control_background_enabled_circle(x, y, r, state) local(shade) ( state = uix_control_state(state); shade = (state == "press") ? 0.5 : (state == "hover") ? 0.75 : (state == "drag") ? 0.75 : 1; uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255*shade, 255*shade, 255*shade); gfx_circle(x, y, r, 1, 1); ui_color(0, 0, 0); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( shade = 1.5 - shade; ui_color(231*shade, 246*shade, 255*shade); gfx_circle(x, y, r, 1, 1); //ui_color(162, 228, 255); ui_color(255, 255, 255); ) : ( ui_color(64*shade, 102*shade, 140*shade); gfx_circle(x, y, r, 1, 1); (state == "press") ? ui_color(230, 230, 230) : ui_color(255, 255, 255); ui_color(255, 255, 255); ); ); function uix_control_background_enabled_circle(state) ( uix_control_background_enabled_circle(ui_left_retina() + ui_width_retina()*0.5, ui_top_retina() + ui_height_retina()*0.5, min(ui_height_retina(), ui_width_retina())*0.5, state); ); function control_finish_enabled(state) ( uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( state == "press" ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 340, 140, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(471, 150); ) : state == "hover" ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 340, 260, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(471, 270); ) : state == "drag" ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 340, 380, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(471, 390); ) : ( gfx_blit(uix_control_theme_buffer, 1, 0, 340, 20, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(471, 30); ); ) : ( ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( uix_gloss(1.8); ui_color(0, 0, 0); ) : ( uix_gloss(1); ui_color(102, 102, 102, 0.25); ui_border(); ); ui_pop(); ); ); function uix_control_finish_enabled_circle(x, y, r, state) ( uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( 0 ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( uix_circle_shade(x, y, r, 0, 2); ) : ( uix_circle_shade(x, y, r, 0, 1); ); ); function uix_control_finish_enabled_circle(state) ( uix_control_finish_enabled_circle(ui_left() + ui_width()*0.5, ui_top() + ui_height()*0.5, min(ui_height(), ui_width())*0.5, state); ); function control_background_passive(state) ( uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ui_fill(); ui_color(255, 255, 255); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(48, 48, 48); ui_fill(); //ui_color(0, 0, 0); //ui_color(140, 198, 221); ui_color(255, 255, 255); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 500, 140, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(631, 150); ) : ( ui_color(255, 255, 255); ui_fill(); ui_color(0, 0, 0); ); ); function control_finish_passive(state) ( ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); uix_dotted_line(ui_left_retina(), ui_top_retina(), ui_right_retina() - 1, ui_top_retina(), 2, 2); uix_dotted_line(ui_right_retina() - 1, ui_top_retina(), ui_right_retina() - 1, ui_bottom_retina(), 2, 2); uix_dotted_line(ui_right_retina() - 1, ui_bottom_retina(), ui_left_retina(), ui_bottom_retina(), 2, 2); uix_dotted_line(ui_left_retina(), ui_bottom_retina(), ui_left_retina(), ui_top_retina(), 2, 2); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( uix_gloss(1); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 660, 140, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(791, 150); ) : ( uix_gloss(0.5); ui_color(102, 102, 102, 0.5); ui_border(); ); ui_pop(); ); function control_background_disabled(state) ( uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ui_fill(); ui_color(255, 255, 255); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(96, 96, 96); ui_fill(); ui_color(48, 48, 48); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 500, 20, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(631, 30); ) : ( ui_color(180, 180, 180); ui_fill(); ui_color(255, 255, 255); ); ); function control_finish_disabled(state) ( ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); uix_dotted_line(ui_left(), ui_top(), ui_right(), ui_top(), 1, 3); uix_dotted_line(ui_right(), ui_top(), ui_right(), ui_bottom(), 1, 3); uix_dotted_line(ui_right(), ui_bottom(), ui_left(), ui_bottom(), 1, 3); uix_dotted_line(ui_left(), ui_bottom(), ui_left(), ui_top(), 1, 3); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 660, 20, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(791, 30); ) : ( ui_color(0, 0, 0, 0.1); ui_border(); ); ui_pop(); ); function control_background_inset(state) ( uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ui_fill(); ui_color(255, 255, 255); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(0, 0, 0, 0.57); ui_fill(); ui_color(205, 167, 119); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 500, 260, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(631, 270); ) : ( ui_color(255, 255, 255); ui_fill(); ui_color(0, 0, 0); ); ); function control_finish_inset() local(strength, height, topalpha, bottomalpha) ( strength = 1; ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); ui_border(); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( uix_gloss(-0.2); ui_color(0, 0, 0, 0.1); ui_border(); ui_color(32, 32, 32); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 660, 260, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(791, 270); ) : ( // Black fade height = min(5, ui_height_retina()/2); topalpha = strength*0.1; bottomalpha = 0; gfx_gradrect( ui_left_retina(), ui_top_retina(), ui_width_retina(), height, 0, 0, 0, topalpha, 0, 0, 0, 0, 0, 0, 0, (bottomalpha - topalpha)/height ); // White fade height = min(5, ui_height_retina()/2); topalpha = 0; bottomalpha = strength*0.3; gfx_gradrect( ui_left_retina(), ui_top_retina(), ui_width_retina(), height, 1, 1, 1, topalpha, 0, 0, 0, 0, 0, 0, 0, (bottomalpha - topalpha)/height ); ui_color(102, 102, 102, 0.5); ui_border(); ); ui_pop(); ); function control_background_technical(state) ( uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ui_fill(); ui_color(255, 255, 255); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(16, 16, 16); ui_fill(); ui_color(205, 147, 74); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 500, 380, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(631, 390); ) : ( ui_color(32, 32, 32); ui_fill(); ui_color(192, 128, 64); ); ); function control_finish_technical(state) ( ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); uix_dotted_line(ui_left(), ui_top(), ui_right() - 1, ui_top(), 2, 2); uix_dotted_line(ui_right() - 1, ui_top(), ui_right() - 1, ui_bottom(), 2, 2); uix_dotted_line(ui_right() - 1, ui_bottom(), ui_left(), ui_bottom(), 2, 2); uix_dotted_line(ui_left(), ui_bottom(), ui_left(), ui_top(), 2, 2); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( uix_gloss(1.5); ui_color(0, 0, 0, 0.2); ui_border(); ui_color(205, 147, 74); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 660, 380, 120, 60, ui_left_retina(), ui_top_retina(), ui_width_retina(), ui_height_retina()); uix_control_color_from_theme(791, 390); ) : ( ui_color(0, 0, 0); uix_gloss(1); ui_border(); ); ui_pop(); ); function control_group(text) local(texth, textw, textl, textr, textv) ( uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_fontsize(min(min(16, ui_height()*0.2), ui_padding_y()*2)); ui_pad(ui_padding_x()/2, ui_padding_y()/2); ui_push(); ui_color(128, 128, 128); gfx_roundrect(ui_left_retina(), ui_top_retina() + 1, ui_width_retina(), ui_height_retina() - 1, 10*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/], 1); ui_pop(); strlen(text) > 0 ? ( ui_split_bottom(ui_texth() + ui_padding_y()/2); ui_color(128, 128, 128); ui_border_top(); ui_color(255, 255, 255); ui_align(0.5, 0.5); ui_text(text); ui_pop(); ); ui_pad(); ) : ( ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_fontsize(min(min(18, ui_height()*0.2), ui_padding_y()*2)); ) : ( ui_fontsize(min(min(16, ui_height()*0.22), ui_padding_y()*3)); ); texth = textw = 0; uix_setgfxfont(); textw = texth = 0; text >= 0 ? gfx_measurestr(text, textw, texth); !texth ? texth = gfx_texth; texth /= uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; textw /= uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; // Border color uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( uix_control_color_from_theme(151, 30, 0.5); ) : ( ui_color(102, 102, 102, 0.5); ); ui_pad(ui_padding_x()/2, 0); ui_split_top(texth); ui_padleft(); ui_padright(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_align(0.5, 0.5); ) : ( ui_align(0, 0.5); ); ui_push_width(textw + ui_padding_x()); textl = ui_left_retina(); textr = ui_right_retina(); textv = ui_top_retina() + ui_height_retina()/2; textw > 0 ? ( ui_align(0.5, 0.5); ui_text(text); ); ui_pop(); ui_pop(); ui_padbottom(); // Border colour is lighter uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( uix_control_color_from_theme(151, 30, 0.25); ); !textw ? textl = textr = ui_left_retina(); ui_push(); gfx_x = textr; gfx_y = textv; uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( uix_dotted_line(textr, textv, ui_right_retina() - 1, textv, 1, 1); uix_dotted_line(ui_right_retina() - 1, textv, ui_right_retina() - 1, ui_bottom_retina(), 1, 1); uix_dotted_line(ui_right_retina() - 1, ui_bottom_retina(), ui_left_retina(), ui_bottom_retina(), 1, 1); uix_dotted_line(ui_left_retina(), ui_bottom_retina(), ui_left_retina(), textv, 1, 1); uix_dotted_line(ui_left_retina(), textv, textl, textv, 1, 1); ) : ( gfx_lineto(ui_right_retina() - 1, gfx_y); gfx_lineto(gfx_x, ui_bottom_retina()); gfx_lineto(ui_left_retina(), gfx_y); gfx_lineto(gfx_x, textv); gfx_lineto(textl, gfx_y); ); ui_pop(); ui_pop(); ui_pad(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_pad(0, -1, 0, -1); ) : ( ui_pad(0, -1); ); ); ); function control_readout(text) local() ( ui_push(); control_background_inset(); ui_text(text); control_finish_inset(); ui_pop(); ); function control_button(text, status) local(click) ( ui_push(); status ? control_background_enabled() : control_background_disabled(); ui_text(text); status ? control_finish_enabled() : control_finish_disabled(); click = status ? ui_click() : 0; ui_pop(); click; ); function control_button(text) ( control_button(text, 1); ); function control_arrow(direction) local(size, tmp, centerx, centery, point1x, point1y, point2x, point2y, point3x, point3y) ( // left, up, right, down size = min(ui_height_retina(), ui_width_retina()); direction == "left" || direction == 0 ? ( direction = 0; centerx = size/2; centery = ui_height_retina()/2; ) : direction == "up" || direction == 1 ? ( direction = 1; centerx = ui_width_retina()/2; centery = size/2; ) : direction == "right" || direction == 2 ? ( direction = 2; centerx = ui_width_retina() - size/2; centery = ui_height_retina()/2; ) : ( direction = 3; centerx = ui_width_retina()/2; centery = ui_height_retina() - size/2; ); centerx += ui_left_retina(); centery += ui_top_retina(); size = min(size, ui_texth_retina()*2); size *= 0.5; angle = direction*$pi/2; // Draw facing upwards to start point1x = 0; point1y = 0.5*size*(direction >= 2 ? 1 : -1); point2x = -0.5*size; point2y = -point1y; point3x = 0.5*size; point3y = -point1y; direction == 0 || direction == 2 ? ( // Swap X and Y tmp = point1x; point1x = point1y; point1y = tmp; tmp = point2x; point2x = point2y; point2y = tmp; tmp = point3x; point3x = point3y; point3y = tmp; ); ui_color_refresh(); gfx_triangle(centerx + point1x, centery + point1y, centerx + point2x, centery + point2y, centerx + point3x, centery + point3y); ); function control_selector(value, text, next_value, prev_value) local(buttonwidth) ( ui_push_height(ui_texth() + 2*ui_padding_y()); control_background_inset(); buttonwidth = min(ui_height()/2, ui_width()/2); ui_halign() <= 0.5 ? ui_split_left(buttonwidth) : ui_split_right(buttonwidth); ui_color(255, 255, 255, 0.8); ui_split_topratio(0.5); next_value != value ? control_background_enabled() : control_background_disabled(); control_arrow("up"); next_value != value ? control_finish_enabled() : control_finish_disabled(); ui_click() ? ( value = next_value; uix_undo_point(1); ui_click_clear(); ); ui_split_next(); prev_value != value ? control_background_enabled() : control_background_disabled(); control_arrow("down"); prev_value != value ? control_finish_enabled() : control_finish_disabled(); ui_click() ? ( value = prev_value; uix_undo_point(1); ui_click_clear(); ); ui_pop(); ui_pop(); ui_push(); ui_padleft(); ui_padright(); ui_text(text); ui_pop(); control_finish_inset(); ui_pop(); value; ); function control_navbar(title, next_title, next_screen) local(click, direction) ( direction = 0; ui_split_toptext(title); control_background_passive(); title ? ( ui_text(title); ); control_finish_passive(); ui_screen_level() > 0 ? ( ui_split_lefttext("< back"); control_button("< back") ? ( direction = -1; ui_screen_close(); ); ui_pop(); ); (next_screen >= 0 || next_title >= 0) ? ( next_title = next_title ? next_title : "next >"; ui_split_righttext(next_title); control_button(next_title) ? ( direction = 1; next_screen > 0 ? ui_screen_open(next_screen); ); ui_pop(); ); ui_pop(); direction ); function control_navbar(title) ( control_navbar(title, -1, -1); ); function uix_slider_value_to_ratio(value, range_low, range_high, curve_bias) local(valueratio) ( valueratio = max(0, min(1, (value - range_low)/(range_high - range_low))); curve_bias ? ( log(valueratio*(exp(curve_bias) - 1) + 1)/curve_bias ) : valueratio; ); function uix_slider_ratio_to_value(ratio, range_low, range_high, curve_bias) local(valueratio) ( ratio = max(0, min(1, ratio)); valueratio = curve_bias ? ( (exp(ratio*curve_bias) - 1)/(exp(curve_bias) - 1) ) : ratio; range_low + (range_high - range_low)*valueratio; ); function uix_control_slider_h(value, range_low, range_high, curve_bias, hasDefault, defaultValue, linkToLeft) local(valueratio, screenratio, state, barwidth, handlesize) ( // We calculate screenratio first (before updating value) because then any rounding/limiting applied to the value is reflected in the UI screenratio = uix_slider_value_to_ratio(value, range_low, range_high, curve_bias); ui_push_height(ui_texth()*2); handlesize = ui_height(); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( control_background_technical(); ) : ( control_background_inset(); control_finish_inset(); ); state = control_state(); ui_push(); linkToLeft ? ( barwidth = floor((ui_width() - 1)*screenratio + 1.5); ui_split_left(barwidth); ) : ( ui_align(screenratio, 0.5); ui_push_width(handlesize); ); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(121, 173, 185); ui_fill(); ) : ( control_background_enabled(state); control_finish_enabled(state); ); ui_pop(); ui_pop(); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( control_finish_technical(); ) : ( 0; ); ui_pop(); ui_mouse_down() || ui_drag() ? ( screenratio = linkToLeft ? ( ui_mouse_xratio() ) : ( (ui_mouse_x() - handlesize*0.5)/(ui_width() - handlesize); ); value = uix_slider_ratio_to_value(screenratio, range_low, range_high, curve_bias); ); ui_scroll_y() ? ( valueratio = uix_slider_value_to_ratio(value, range_low, range_high, curve_bias); valueratio += ui_scroll_y()/uix_scroll_scale; value = uix_slider_ratio_to_value(valueratio, range_low, range_high, curve_bias); ); hasDefault && ui_click() && ui_clickcount() == 2 ? ( value = defaultValue; uix_undo_point(); ); ui_scroll_y() ? uix_undo_point(1); ui_drag_up() ? uix_undo_point(); value; ); function control_slider_left(value, range_low, range_high, curve_bias, default) ( uix_control_slider_h(value, range_low, range_high, curve_bias, 1, default, 1); ); function control_slider_left(value, range_low, range_high, curve_bias) ( uix_control_slider_h(value, range_low, range_high, curve_bias, 0, 0, 1); ); function control_slider_left(value, range_low, range_high) ( control_slider_left(value, range_low, range_high, 0); ); function control_slider_x(value, range_low, range_high, curve_bias, default) ( uix_control_slider_h(value, range_low, range_high, curve_bias, 1, default, 0); ); function control_slider_x(value, range_low, range_high, curve_bias) ( uix_control_slider_h(value, range_low, range_high, curve_bias, 0, 0, 0); ); function control_slider_x(value, range_low, range_high) ( control_slider_x(value, range_low, range_high, 0); ); function uix_control_slider_v(value, range_low, range_high, curve_bias, hasDefault, defaultValue, linkToBottom) local(valueratio, screenratio, state, barheight, handlesize) ( // We calculate screenratio first (before updating value) because then any rounding/limiting applied to the value is reflected in the UI screenratio = uix_slider_value_to_ratio(value, range_low, range_high, curve_bias); ui_push_width(ui_texth()*2); handlesize = ui_width(); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( control_background_technical(); ) : ( control_background_inset(); control_finish_inset(); ); state = control_state(); ui_push(); linkToBottom ? ( barheight = floor((ui_height() - 1)*screenratio + 1.5); ui_split_bottom(barheight); ) : ( ui_align(0.5, 1 - screenratio); ui_push_height(handlesize); ); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(121, 173, 185); ui_fill(); ) : ( control_background_enabled(state); control_finish_enabled(state); ); ui_pop(); ui_pop(); uix_control_theme == 2/*uix_THEME:TRON*/ ? ( control_finish_technical(); ) : ( 0; ); ui_pop(); ui_mouse_down() || ui_drag() ? ( screenratio = linkToBottom ? ( 1 - ui_mouse_yratio() ) : ( (ui_height() - ui_mouse_y() - handlesize*0.5)/(ui_height() - handlesize); ); value = uix_slider_ratio_to_value(screenratio, range_low, range_high, curve_bias); ); ui_scroll_y() ? ( valueratio = uix_slider_value_to_ratio(value, range_low, range_high, curve_bias); valueratio += ui_scroll_y()/uix_scroll_scale; value = uix_slider_ratio_to_value(valueratio, range_low, range_high, curve_bias); ); hasDefault && ui_click() && ui_clickcount() == 2 ? ( value = defaultValue; uix_undo_point(); ); ui_scroll_y() ? uix_undo_point(1); ui_drag_up() ? uix_undo_point(); value; ); function control_slider_bottom(value, range_low, range_high, curve_bias, default) ( uix_control_slider_v(value, range_low, range_high, curve_bias, 1, default, 1); ); function control_slider_bottom(value, range_low, range_high, curve_bias) ( uix_control_slider_v(value, range_low, range_high, curve_bias, 0, 0, 1); ); function control_slider_bottom(value, range_low, range_high) ( control_slider_bottom(value, range_low, range_high, 0); ); function control_slider_y(value, range_low, range_high, curve_bias, default) ( uix_control_slider_v(value, range_low, range_high, curve_bias, 1, default, 0); ); function control_slider_y(value, range_low, range_high, curve_bias) ( uix_control_slider_v(value, range_low, range_high, curve_bias, 0, 0, 0); ); function control_slider_y(value, range_low, range_high) ( control_slider_y(value, range_low, range_high, 0); ); function uix_control_dragvalue(value, range_low, range_high, curve_bias) local(valueratio, deltay) ( ui_drag() || ui_scroll_y() ? ( valueratio = uix_slider_value_to_ratio(value, range_low, range_high, curve_bias); deltay = ui_mouse_dy()/uix_drag_scale*exp(-abs(ui_drag_x())/uix_drag_scale) - ui_scroll_y()/5000; value = uix_slider_ratio_to_value(valueratio - deltay, range_low, range_high, curve_bias); ); ui_scroll_y() ? uix_undo_point(1); ui_drag_up() ? uix_undo_point(); value; ); function uix_thick_arc(centrex, centrey, inner_radius, lowangle, angle) ( gfx_arc(centrex, centrey, inner_radius, lowangle, angle, 1); gfx_arc(centrex + 1, centrey, inner_radius, lowangle, angle, 1); gfx_arc(centrex, centrey + 1, inner_radius, lowangle, angle, 1); gfx_arc(centrex - 1, centrey, inner_radius, lowangle, angle, 1); gfx_arc(centrex, centrey - 1, inner_radius, lowangle, angle, 1); ); function uix_thick_line(x1, y1, x2, y2) ( gfx_line(x1, y1, x2, y2, 1); gfx_line(x1 + 1, y1, x2 + 1, y2, 1); gfx_line(x1, y1 + 1, x2, y2 + 1, 1); gfx_line(x1 - 1, y1, x2 - 1, y2, 1); gfx_line(x1, y1 - 1, x2, y2 - 1, 1); ); function uix_control_dial(value, range_low, range_high, curve_bias, hasDefault, defaultValue, linkToLeft) local(valueratio, screenratio, centrex, centrey, radius, inner_radius, highangle, lowangle, angle, x1, x2, y1, y2) ( screenratio = uix_slider_value_to_ratio(value, range_low, range_high, curve_bias); radius = min(min(ui_width_retina(), ui_height_retina())/2 - 1, 30*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]); centrex = (ui_left_retina() + radius) + (ui_width_retina() - radius*2 - 1)*ui_halign(); centrey = (ui_top_retina() + radius) + (ui_height_retina() - radius*2 - 1)*ui_valign(); inner_radius = radius - 2*(1 + ui_retina()); // Draw arc lowangle = -2.3; highangle = 2.3; angle = lowangle + (highangle - lowangle)*(screenratio*0.98 + 0.01); uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 820, 20, 120, 120, centrex - radius + 0.5, centrey - radius + 0.5, radius*2, radius*2); gfx_blit(uix_control_theme_buffer, 1, angle, 820, 200, 120, 120, centrex - radius + 0.5, centrey - radius + 0.5, radius*2, radius*2); ) : ( uix_control_background_enabled_circle(centrex, centrey, radius, "none"); uix_control_theme == 2/*uix_THEME:TRON*/ || !linkToLeft ? ( uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); x1 = centrex + sin(lowangle)*inner_radius; y1 = centrey - cos(lowangle)*inner_radius; x2 = centrex + sin(highangle)*inner_radius; y2 = centrey - cos(highangle)*inner_radius; gfx_circle(x1, y1, 1, 1, 1); gfx_circle(x2, y2, 1, 1, 1); ) : ( ui_color(131, 184, 206); uix_thick_arc(centrex, centrey, inner_radius, lowangle, highangle); ); x1 = centrex + sin(angle)*inner_radius*0.5; y1 = centrey - cos(angle)*inner_radius*0.5; x2 = centrex + sin(angle)*inner_radius; y2 = centrey - cos(angle)*inner_radius; uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ) : ( ui_color(255, 255, 255); ); uix_thick_line(x1, y1, x2, y2); ) : ( gfx_a = 1; uix_thick_arc(centrex, centrey, inner_radius, lowangle, angle); ); ui_pad(5, 5); uix_control_finish_enabled_circle(centrex, centrey, radius, 0); ); hasDefault && ui_click() && ui_clickcount() == 2 ? ( value = defaultValue; ); uix_control_dragvalue(value, range_low, range_high, curve_bias); ); function control_dial_left(value, range_low, range_high, curve_bias, default) ( uix_control_dial(value, range_low, range_high, curve_bias, 1, default, 1); ); function control_dial_left(value, range_low, range_high, curve_bias) ( uix_control_dial(value, range_low, range_high, curve_bias, 0, 0, 1); ); function control_dial_left(value, range_low, range_high) ( control_dial_left(value, range_low, range_high, 0); ); function control_dial(value, range_low, range_high, curve_bias, default) ( uix_control_dial(value, range_low, range_high, curve_bias, 1, default, 0); ); function control_dial(value, range_low, range_high, curve_bias) ( uix_control_dial(value, range_low, range_high, curve_bias, 0, 0, 0); ); function control_dial(value, range_low, range_high) ( control_dial(value, range_low, range_high, 0); ); function uix_control_dial_angle(angle, isUnit) local(display_angle, radius, centrex, centrey, inner_radius, x1, x2, y1, y2) ( radius = min(min(ui_width_retina(), ui_height_retina())/2 - 1, 30*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]); centrex = (ui_left_retina() + radius) + (ui_width_retina() - radius*2 - 1)*ui_halign(); centrey = (ui_top_retina() + radius) + (ui_height_retina() - radius*2 - 1)*ui_valign(); display_angle = isUnit ? 2*$pi*angle : angle; uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( gfx_blit(uix_control_theme_buffer, 1, 0, 980, 20, 120, 120, centrex - radius + 0.5, centrey - radius + 0.5, radius*2, radius*2); gfx_blit(uix_control_theme_buffer, 1, display_angle, 980, 200, 120, 120, centrex - radius + 0.5, centrey - radius + 0.5, radius*2, radius*2); ) : ( inner_radius = radius - 4; uix_control_background_enabled_circle(centrex, centrey, radius, "none"); x1 = centrex + sin(display_angle)*inner_radius*0.5; y1 = centrey - cos(display_angle)*inner_radius*0.5; x2 = centrex + sin(display_angle)*inner_radius; y2 = centrey - cos(display_angle)*inner_radius; uix_thick_line(x1, y1, x2, y2); ui_pad(5, 5); uix_control_finish_enabled_circle(centrex, centrey, radius, 0); ); isUnit ? ( angle = uix_control_dragvalue(angle, -0.03, 1.03, 0); angle -= floor(angle); ) : ( angle = uix_control_dragvalue(angle, -0.1, 2*$pi + 0.1, 0); angle < 0 ? angle += 2*$pi; angle >= 2*$pi ? angle -= 2*$pi; ); angle; ); function control_dial_angle(angle) ( uix_control_dial_angle(angle, 0); ); function control_dial_angle(angle, default) ( angle = control_dial_angle(angle); ui_click() && ui_clickcount() == 2 ? ( angle = default; ); angle; ); function control_dial_angle_unit(angle) ( angle = uix_control_dial_angle(angle, 1); ); function control_dial_angle_unit(angle, default) ( angle = uix_control_dial_angle(angle, 1); ui_click() && ui_clickcount() == 2 ? ( angle = default; ); angle; ); function control_dialog(title, width, height, doneText, cancelText) local(accepted) ( accepted = 0; ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ui_fill(); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(0, 0, 0, 0.5); ui_fill(); ) : ( ui_color(0, 0, 0, 0.2); ui_fill(); ); ui_pop(); width <= 0 ? width = min(ui_width()*0.8, 450); height <= 0 ? height = min(ui_height()*0.8, 350); title >= 0 ? height += ui_text_height(title) + ui_padding_y()*2; width = min(width + ui_padding_x()*2, ui_width()); height = min(height + ui_padding_y()*2, ui_height()); ui_pad((ui_width() - width)/2, (ui_height() - height)/2); uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ui_push_clip(1) : ui_push(); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(0, 0, 0); ui_fill(); ui_color(255, 255, 255); ui_border(); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color($x45, $x45, $x45); ui_fill(); ui_color(255, 255, 255, 0.1); ui_border(); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( y = 0; while (y < gfx_h) ( x = 0; while (x < gfx_w) ( gfx_blit(uix_control_theme_buffer, ui_retina(), 0, 20, 20, 120, 120, x, y); x += 120*ui_retina(); ); y += 120; ); ) : ( ui_color(242, 242, 242); ui_fill(); ui_color(102, 102, 102, 0.5); ui_border(); ); ui_pop(); // set main colour uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( ui_color(255, 255, 255); ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( ui_color(255, 255, 255); ) : uix_control_theme == 3/*uix_THEME:BITMAP_SIMPLE*/ ? ( uix_control_color_from_theme(151, 30); ui_border(); ) : ( ui_color(12, 12, 12); ); ui_key() == 27 ? ( accepted = (cancelText >= 0) ? -1 : 1; ); ui_key() == 13 ? accepted = 1; doneText >= 0 || cancelText >= 0 ? ( ui_split_bottomtext(-1); cancelText >= 0 && doneText < 0 ? ( control_background_disabled(); ui_text(cancelText); control_finish_enabled(); ui_click() ? accepted = -1; ) : cancelText >= 0 ? ( ui_push(); ui_split_leftratio(0.5); control_button(doneText) ? accepted = 1; ui_split_next(); control_background_disabled(); ui_text(cancelText); control_finish_enabled(); ui_click() ? accepted = -1; ui_pop(); ui_pop(); ) : ( control_button(doneText) ? accepted = 1; ); ui_pop(); ); title >= 0 ? ( ui_split_toptext(title); control_background_passive(); ui_text(title); control_finish_passive(); ui_pop(); ); ui_pad(); accepted ? ui_screen_close(); accepted; ); function control_dialog(title, doneText, cancelText) local(accepted) ( control_dialog(title, -1, -1, doneText, cancelText); ); function control_dialog(title, doneText) local(accepted) ( control_dialog(title, doneText, -1); ); function control_dialog(title) local(accepted) ( control_dialog(title, "OK"); ); function control_switch(value) local(state) ( ui_click() ? ( value = !value; uix_undo_point(); ); ui_push_height(ui_texth()*2); ui_push_width(min(ui_texth()*4, ui_height()*2.5)); control_background_inset(); control_finish_inset(); state = control_state(); value ? ui_split_rightratio(0.5) : ui_split_leftratio(0.5); control_background_enabled(state); control_finish_enabled(state); ui_pop(); ui_pop(); ui_pop(); value; ); function control_radio(value, option_value) local(state) ( ui_click() ? ( value = option_value; uix_undo_point(); ); ui_push_height(ui_texth()); ui_push_width(ui_texth()); control_background_inset(); control_finish_inset(); value == option_value ? ( ui_pad(2, 2); control_background_enabled(state); control_finish_enabled(state); ); ui_pop(); ui_pop(); value; ); function uix_control_closest_substring_width(text, targetwidth) local(text_length, best_index, best_width, i, candidatewidth) ( best_index = 0; best_width = 0; i = 0; text_length = strlen(text); while (i <= text_length) ( strcpy_substr(#uix_control_closest_substring_width, text, 0, i); candidatewidth = ui_text_width(#uix_control_closest_substring_width); abs(candidatewidth - targetwidth) <= abs(best_width - targetwidth) ? ( best_width = candidatewidth; best_index = i; ); i += 1; ); best_index; ); function uix_autoselect_char(char) ( // Alphanumeric (plus "." and "_") in the latin1 charset char == '.' || char == '_' || (char >= '0' && char <= '9') || (char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z') || (char >= 192 && char <= 255); ); function uix_control_textinput_pack(focused, start, end) local(packed) ( packed = start + end*67108864; focused ? packed + 1: -packed; ); function uix_control_textinput_unpack_focused(packed) ( packed > 0 ? 1 : 0; ); function uix_control_textinput_unpack_cursor(packed) ( packed > 0 ? (packed - 1)%67108864 : (-packed)%67108864; ); function uix_control_textinput_unpack_trail(packed) ( packed > 0 ? floor((packed - 1)/67108864) : floor(-packed/67108864); ); function control_textinput_hasfocus(prompt_selectpacked) ( uix_control_textinput_unpack_focused(prompt_selectpacked); ); function control_textinput_select(packed, cursor, trail) local(focused) ( focused = uix_control_textinput_unpack_focused(packed); uix_control_textinput_pack(focused, cursor, trail); ); function control_textinput_focus(packed) local(focused, cursor, trail) ( cursor = uix_control_textinput_unpack_cursor(packed); trail = uix_control_textinput_unpack_trail(packed); uix_control_textinput_pack(1, cursor, trail); ); function control_textinput_unfocus(packed) local(cursor, trail) ( cursor = uix_control_textinput_unpack_cursor(packed); trail = uix_control_textinput_unpack_trail(packed); uix_control_textinput_pack(0, cursor, trail); ); function control_textinput(text, packed) local(text_length, prompt_selectlow, prompt_selecthigh, textx, texty, selectw, t, char, keyinterested, char_index, select_padding) ( text_length = strlen(text); prompt_focused = uix_control_textinput_unpack_focused(packed); prompt_selectcursor = uix_control_textinput_unpack_cursor(packed); prompt_selecttrail = uix_control_textinput_unpack_trail(packed); prompt_selectcursor = min(text_length, prompt_selectcursor); prompt_selecttrail = min(text_length, prompt_selecttrail); prompt_selecthigh = max(prompt_selectcursor, prompt_selecttrail); prompt_selectlow = prompt_selecttrail >= 0 ? min(prompt_selectcursor, prompt_selecttrail) : prompt_selecthigh; ui_push(); ui_align(0, 0.5); control_background_inset(); ui_mouse_down() ? ( char_index = uix_control_closest_substring_width(text, ui_mouse_x() - ui_padding_x()); (mouse_cap&8) ? ( // Shift prompt_selecttrail = char_index; ) : ( prompt_selectcursor = char_index; prompt_selecttrail = prompt_selectcursor; ); uix_control_cursortimeoffset = time_precise(); ); ui_drag() ? ( prompt_selecttrail = uix_control_closest_substring_width(text, ui_mouse_x() - ui_padding_x()); uix_control_cursortimeoffset = time_precise(); ); (ui_drag() || ui_click()) && ui_clickcount() == 2 ? ( while (prompt_selectlow > 0 && uix_autoselect_char(str_getchar(text, prompt_selectlow - 1))) ( prompt_selectlow -= 1; ); while (prompt_selecthigh < text_length && uix_autoselect_char(str_getchar(text, prompt_selecthigh))) ( prompt_selecthigh += 1; ); ui_click() ? ( ui_click_clear(); prompt_selectcursor = prompt_selectlow; prompt_selecttrail = prompt_selecthigh; ); ); ui_mouse_down_outside() ? ( prompt_focused = 0; uix_undo_point(); ); ui_push(); ui_pad(); ui_font_refresh(); textx = ui_left_retina(); texty = ui_top_retina() + (ui_height_retina() - gfx_texth)/2; gfx_x = textx; gfx_y = texty; strcpy_substr(#control_tmp1, text, 0, prompt_selectlow); gfx_drawstr(#control_tmp1); prompt_selecthigh > prompt_selectlow ? ( strcpy_substr(#control_tmp1, text, prompt_selectlow, prompt_selecthigh - prompt_selectlow); selectw = ui_text_width(#control_tmp1); uix_control_theme == 1/*uix_THEME:BLACK_AND_WHITE*/ ? ( select_padding = 1*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ) : uix_control_theme == 2/*uix_THEME:TRON*/ ? ( select_padding = 2*uix_drawconfig_current[9/*uix_DRAWCONFIG:RETINA_SCALING*/]; ) : ( select_padding = 0; ); ui_push(); ui_set_rect_retina(gfx_x - select_padding, gfx_y - select_padding, selectw + select_padding*2, gfx_texth + select_padding*2); control_background_enabled(); gfx_drawstr(#control_tmp1); ui_pop(); ui_font_refresh(); ) : ( t = time_precise() - uix_control_cursortimeoffset; t = t - floor(t); prompt_selecttrail == prompt_selectcursor ? t < 0.5 ? ( gfx_line(gfx_x, gfx_y, gfx_x, gfx_y + gfx_texth); ); ); strcpy_from(#control_tmp1, text, max(prompt_selectlow, prompt_selecthigh)); gfx_drawstr(#control_tmp1); ui_pop(); control_finish_inset(); prompt_focused ? ( keyinterested = prompt_focused; while (prompt_focused && ui_key()) ( char = ui_key(); ui_key_printable() ? ( strcpy_substr(#control_tmp1, text, 0, prompt_selectlow); str_setchar(#control_tmp1, prompt_selectlow, char); strcpy_from(#control_tmp2, text, prompt_selecthigh); strcat(#control_tmp1, #control_tmp2); strcpy(text, #control_tmp1); prompt_selectcursor += 1; prompt_selecttrail = prompt_selectcursor; text_length = strlen(text); uix_undo_point(1); ) : char == 8 || char == 6579564 ? ( // Backspace and Delete prompt_selectlow == prompt_selecthigh ? ( char == 8 ? ( prompt_selectlow = max(prompt_selectlow - 1, 0); ) : ( prompt_selecthigh = min(text_length, prompt_selecthigh + 1); ); ); strcpy_substr(#control_tmp1, text, 0, prompt_selectlow); strcpy_from(#control_tmp2, text, prompt_selecthigh); strcat(#control_tmp1, #control_tmp2); strcpy(text, #control_tmp1); prompt_selectcursor = prompt_selecttrail = prompt_selectlow; text_length = strlen(text); uix_undo_point(1); ) : char == 1919379572 ? ( // Right (mouse_cap&8) ? ( // Shift prompt_selectcursor = min(prompt_selectcursor + 1, text_length); ) : ( prompt_selectlow == prompt_selecthigh ? ( // Move cursor right prompt_selectcursor = min(prompt_selectcursor + 1, text_length); ) : ( // Move to right of selection prompt_selectcursor = prompt_selecthigh; ); prompt_selecttrail = prompt_selectcursor; ); ) : char == 1818584692 ? ( // Left (mouse_cap&8) ? ( // Shift prompt_selectcursor = max(prompt_selectcursor - 1, 0); ) : ( prompt_selectlow == prompt_selecthigh ? ( // Move cursor left prompt_selectcursor = max(prompt_selectcursor - 1, 0); ) : ( // Move to left of selection prompt_selectcursor = prompt_selectlow; ); prompt_selecttrail = prompt_selectcursor; ); ) : char == 1752132965 ? ( // Home prompt_selectcursor = 0; (!(mouse_cap&8)) ? ( prompt_selecttrail = prompt_selectcursor; ); ) : char == 6647396 ? ( // End prompt_selectcursor = text_length; (!(mouse_cap&8)) ? ( prompt_selecttrail = prompt_selectcursor; ); ) : char == 1 ? ( // Ctrl+A prompt_selectcursor = 0; prompt_selecttrail = text_length; ) : ( keyinterested = 0; ); keyinterested ? ( ui_key_next(); uix_control_cursortimeoffset = time_precise(); ); ); ); ui_pop(); uix_control_textinput_pack(prompt_focused, prompt_selectcursor, prompt_selecttrail); ); uix_control_hidden_text_active_x =uix_control_hidden_text_active_y = -1; uix_control_hidden_text_state; function control_hidden_text(text) local(i) ( uix_control_hidden_text_active_x == ui_left() && uix_control_hidden_text_active_y == ui_top() ? ( ui_key() == 27 || ui_key() == 13 || ui_mouse_down_outside(1) || ui_mouse_down_outside(2) || ui_mouse_down_outside(64) ? ( uix_control_hidden_text_active_x = uix_control_hidden_text_active_y = -1; ); uix_control_hidden_text_state = control_textinput(text, uix_control_hidden_text_state); ) : ( ui_text(text); ui_click(2) || (ui_click() && ui_clickcount() == 3) ? ( // Right-click uix_control_hidden_text_active_x = ui_left(); uix_control_hidden_text_active_y = ui_top(); // TODO: select-all here, when it's implemented uix_control_hidden_text_state = control_textinput_focus(0); uix_control_hidden_text_state = control_textinput_select(uix_control_hidden_text_state, 0, strlen(text)); ); ); ); function control_hidden_textnumber(actualnumber, number, format) local(i) ( uix_control_hidden_text_active_x == ui_left() && uix_control_hidden_text_active_y == ui_top() ? ( ui_key() == 27 || ui_key() == 13 || ui_mouse_down_outside(1) || ui_mouse_down_outside(2) || ui_mouse_down_outside(64) ? ( uix_control_hidden_text_active_x = uix_control_hidden_text_active_y = -1; ui_key() != 27 ? ( actualnumber = ui_parsenumber(#uix_control_hidden_textnumber, actualnumber); uix_undo_point(); ); ); uix_control_hidden_text_state = control_textinput(#uix_control_hidden_textnumber, uix_control_hidden_text_state); ) : ( ui_textnumber(number, format); ui_click(2) || (ui_click() && ui_clickcount() == 3) ? ( // Right-click sprintf(#uix_control_hidden_textnumber, format ? format : "%f", number); uix_control_hidden_text_active_x = ui_left(); uix_control_hidden_text_active_y = ui_top(); // TODO: select-all here, when it's implemented uix_control_hidden_text_state = control_textinput_focus(0); uix_control_hidden_text_state = control_textinput_select(uix_control_hidden_text_state, 0, strlen(#uix_control_hidden_textnumber)); ); ); actualnumber; ); function control_hidden_textnumber(number, format) ( control_hidden_textnumber(number, number*1.00000006 /* sprintf() bug */, format); ); function control_hidden_textnumber(number) ( control_hidden_textnumber(number, "%f"); ); function control_system() local(prompt_title, prompt_text, prompt_init, prompt_selectlow, prompt_selecthigh, textx, texty, selectw, t, char, OK) ( ui_screen() == "control.prompt" ? ( prompt_text = ui_screen_arg(0); prompt_title = ui_screen_arg(1); prompt_init = ui_screen_arg(2); prompt_selectpacked = ui_screen_arg(3); !prompt_init ? ( while (gfx_getchar()) ( 0; // Drop keys from queue ); prompt_init = 1; strcpy(#control_prompt_text, prompt_text); prompt_selectpacked = control_textinput_focus(prompt_selectpacked); ); OK = control_dialog(prompt_title, 0, (ui_texth() + ui_padding_y()*2)*3, "done", "cancel"); ui_push_heighttext(-1); prompt_selectpacked = control_textinput(#control_prompt_text, prompt_selectpacked); ui_pop(); // Confirm/exit ui_key() == 13 ? ( OK = 1; ) : ui_key() == 27 ? ( OK = -1; ); ui_screen_arg(2, prompt_init); ui_screen_arg(3, prompt_selectpacked); OK ? ( (OK == 1) ? strcpy(prompt_text, #control_prompt_text); ui_screen() == "control.prompt" ? ui_screen_close(); ); ) : ui_system(); );