// 2024-04-20 10:00:16 #event properties (no comments/etc. here are saved) parent_index = _p_dialog_undo_block; uses_physics = false; #event create init event_inherited(); #region data dialog_w = ui(812); dialog_h = ui(440); title_height = 52; destroy_on_click_out = true; name = __txtx("palette_editor_title", "Palette editor"); palette = 0; index_selecting = 0; index_dragging = -1; interactable = true; index_drag_x = 0; index_drag_x_to = 0; index_drag_y = 0; index_drag_y_to = 0; index_drag_w = 0; index_drag_w_to = 0; index_drag_h = 0; index_drag_h_to = 0; setColor = function(color) { if(index_selecting == -1 || palette == 0) return; palette[index_selecting] = color; if(onApply == noone) return; onApply(palette); } onApply = noone; selector = new colorSelector(setColor); selector.dropper_close = false; selector.discretize_pal = false; previous_palette = c_black; function setDefault(pal) { setPalette(pal); previous_palette = array_clone(pal); } b_cancel = button(function() { onApply(previous_palette); instance_destroy(); }).setIcon(THEME.undo, 0, COLORS._main_icon) .setTooltip(__txtx("dialog_revert_and_exit", "Revert and exit")); b_apply = button(function() { onApply(palette); instance_destroy(); }).setIcon(THEME.accept, 0, COLORS._main_icon_dark); function setPalette(pal) { palette = pal; index_selecting = 0; if(array_length(palette) > 0) selector.setColor(palette[0]); } #endregion #region presets hovering_name = ""; sp_preset_w = ui(240 - 32 - 16); sp_presets = new scrollPane(sp_preset_w, dialog_h - ui(62), function(_y, _m) { var ww = sp_preset_w - ui(40); var hh = ui(32); var yy = _y + ui(8); var hg = ui(52); draw_clear_alpha(COLORS.panel_bg_clear, 0); for(var i = -1; i < array_length(PALETTES); i++) { var pal = i == -1? { name: "project", palette: PROJECT.attributes.palette, path: "" } : PALETTES[i]; var isHover = sHOVER && sp_presets.hover && point_in_rectangle(_m[0], _m[1], ui(4), yy, ui(4) + sp_preset_w - ui(16), yy + hg); draw_sprite_stretched(THEME.ui_panel_bg, 3, ui(4), yy, sp_preset_w - ui(16), hg); if(isHover) draw_sprite_stretched_ext(THEME.node_active, 1, ui(4), yy, sp_preset_w - ui(16), hg, COLORS._main_accent, 1); draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub); draw_text(ui(16), yy + ui(8), pal.name); drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(16)); if(isHover) { if(mouse_press(mb_left, interactable && sFOCUS)) { palette = array_clone(pal.palette); onApply(palette); index_selecting = 0; selector.setColor(palette[index_selecting], false); } if(i >= 0 && mouse_press(mb_right, interactable && sFOCUS)) { hovering = pal; menuCall("palette_window_preset_menu",,, [ menuItem(__txtx("palette_editor_set_default", "Set as default"), function() { DEF_PALETTE = array_clone(hovering.palette); }), menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { file_delete(hovering.path); __initPalette(); }), ]); } } yy += hg + ui(4); hh += hg + ui(4); } return hh; }); sp_presets.always_scroll = true; #endregion #region tools function sortPalette(sortFunc) { array_sort(palette, sortFunc); onApply(palette); } #endregion #region action onResize = function() { sp_presets.resize(sp_preset_w, dialog_h - ui(62)); } function checkMouse() {} #endregion #event step_begin init if !ready exit; #region destroy selector.interactable = interactable; if(!selector.dropper_active) { if(sHOVER && !point_in_rectangle(mouse_mx, mouse_my, dialog_x, dialog_y, dialog_x + dialog_w, dialog_y + dialog_h)) { if(destroy_on_click_out && mouse_press(mb_left)) instance_destroy(self); } doDrag(); } if(sFOCUS && WIDGET_CURRENT == noone) { if(keyboard_check_pressed(vk_enter)) { onApply(palette); instance_destroy(); } if(keyboard_check_pressed(vk_escape)) { onApply(previous_palette); instance_destroy(); } } #endregion #region resize if(_dialog_h != dialog_h || _dialog_w != dialog_w) { _dialog_h = dialog_h; _dialog_w = dialog_w; if(onResize != -1) onResize(); } #endregion #event draw_gui init if !ready exit; if palette == 0 exit; #region dropper selector.interactable = interactable; if(selector.dropper_active) { selector.drawDropper(self); exit; } #endregion #region base UI var presets_x = dialog_x; var presets_w = ui(240); var content_x = dialog_x + presets_w + ui(16); var content_w = dialog_w - presets_w - ui(16); var p = DIALOG_PAD; var p2 = DIALOG_PAD * 2; draw_sprite_stretched(THEME.dialog_bg, 0, presets_x - p, dialog_y - p, presets_w + p2, dialog_h + p2); if(sFOCUS) draw_sprite_stretched_ext(THEME.dialog_active, 0, presets_x - p, dialog_y - p, presets_w + p2, dialog_h + p2, COLORS._main_accent, 1); draw_sprite_stretched(THEME.dialog_bg, 0, content_x - p, dialog_y - p, content_w + p2, dialog_h + p2); if(sFOCUS) draw_sprite_stretched_ext(THEME.dialog_active, 0, content_x - p, dialog_y - p, content_w + p2, dialog_h + p2, COLORS._main_accent, 1); draw_set_text(f_p0, fa_left, fa_top, COLORS._main_text); draw_text(presets_x + ui(24), dialog_y + ui(16), __txt("Presets")); draw_text(content_x + (!interactable * ui(32)) + ui(24), dialog_y + ui(16), name); if(!interactable) draw_sprite_ui(THEME.lock, 0, content_x + ui(24 + 12), dialog_y + ui(16 + 12),,,, COLORS._main_icon); #endregion #region presets draw_sprite_stretched(THEME.ui_panel_bg, 1, presets_x + ui(16), dialog_y + ui(44), ui(240 - 32), dialog_h - ui(60)); sp_presets.setFocusHover(sFOCUS, sHOVER); sp_presets.draw(presets_x + ui(24), dialog_y + ui(44)); var bx = presets_x + presets_w - ui(44); var by = dialog_y + ui(12); var bs = ui(28); if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txtx("add_preset", "Add to preset"), THEME.add_20) == 2) { var dia = dialogCall(o_dialog_file_name, mouse_mx + ui(8), mouse_my + ui(8)); dia.onModify = function (txt) { var file = file_text_open_write(txt + ".hex"); for(var i = 0; i < array_length(palette); i++) { var cc = palette[i]; var r = number_to_hex(color_get_red(cc)); var g = number_to_hex(color_get_green(cc)); var b = number_to_hex(color_get_blue(cc)); var a = number_to_hex(color_get_alpha(cc)); file_text_write_string(file, $"{r}{g}{b}{a}\n"); } file_text_close(file); __initPalette(); }; dia.path = DIRECTORY + "Palettes/" } bx -= ui(32); if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txt("Refresh"), THEME.refresh_20) == 2) __initPalette(); bx -= ui(32); if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txtx("color_selector_open_palette", "Open palette folder"), THEME.path_open_20) == 2) { var _realpath = DIRECTORY + "Palettes"; shellOpenExplorer(_realpath) } draw_sprite_ui_uniform(THEME.path_open_20, 1, bx + bs / 2, by + bs / 2, 1, c_white); bx -= ui(32); #endregion #region palette var pl_x = content_x + ui(60); var pl_y = dialog_y + ui(54); var pl_w = content_w - ui(154); var pl_h = ui(24); var max_col = 8; var col = min(array_length(palette), max_col); var row = ceil(array_length(palette) / col); var ww = round(pl_w / col); var hh = (pl_h + ui(6)) * row; dialog_h = ui(408) + hh; draw_sprite_stretched(THEME.textbox, 3, pl_x - ui(6), pl_y - ui(6), pl_w + ui(12), hh + ui(6)); draw_sprite_stretched(THEME.textbox, 0, pl_x - ui(6), pl_y - ui(6), pl_w + ui(12), hh + ui(6)); #region tools var bx = content_x + content_w - ui(50); var by = dialog_y + ui(16); if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_sort", "Sort color"), THEME.sort) == 2) { menuCall("palette_window_sort_menu", bx + ui(32), by, [ menuItem(__txtx("palette_editor_sort_brighter", "Brighter"), function() { sortPalette(__sortBright); }), menuItem(__txtx("palette_editor_sort_darker", "Darker"), function() { sortPalette(__sortDark); }), -1, menuItem(__txtx("palette_editor_sort_hue", "Hue"), function() { sortPalette(__sortHue); }), menuItem(__txtx("palette_editor_sort_sat", "Saturation"), function() { sortPalette(__sortSat); }), menuItem(__txtx("palette_editor_sort_val", "Value"), function() { sortPalette(__sortVal); }), ],, palette); } bx -= ui(32); if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_reverse", "Reverse palette"), THEME.reverse) == 2) { palette = array_reverse(palette); onApply(palette); } bx -= ui(32); #endregion var hover = -1, hvx, hvy; var _pd = ui(5); for(var i = 0; i < row; i++) for(var j = 0; j < col; j++) { var index = i * col + j; if(index >= array_length(palette)) break; var _p = palette[index]; var _pa = _color_get_alpha(_p); var _kx = pl_x + j * ww; var _ky = pl_y + i * (pl_h + ui(6)); var _px = _kx + ui(2); var _py = _ky; var _pw = ww - ui(4); var _ph = pl_h; if(index == index_dragging) { index_drag_x_to = _px; index_drag_y_to = _py; index_drag_w_to = _pw; index_drag_h_to = _ph; continue; } if(_pa < 1) { draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph - ui(8), _p, 1); draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw, ui(6), c_black, 1); draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw * _pa, ui(6), c_white, 1); } else draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph, _p, 1); if(index == index_selecting) draw_sprite_stretched_ext(THEME.palette_selecting, 0, _px - _pd, _py - _pd, _pw + _pd * 2, _ph + _pd * 2, c_white, 1); if(sHOVER && point_in_rectangle(mouse_mx, mouse_my, _kx, _ky, _kx + ww, _ky + pl_h)) { hover = index; hvx = _kx; hvy = _ky; } } if(index_dragging > -1) { index_drag_x = index_drag_x == 0? index_drag_x_to : lerp_float(index_drag_x, index_drag_x_to, 5); index_drag_y = index_drag_y == 0? index_drag_y_to : lerp_float(index_drag_y, index_drag_y_to, 5); index_drag_w = index_drag_w == 0? index_drag_w_to : lerp_float(index_drag_w, index_drag_w_to, 5); index_drag_h = index_drag_h == 0? index_drag_h_to : lerp_float(index_drag_h, index_drag_h_to, 5); _px = index_drag_x; _py = index_drag_y; _pw = index_drag_w; _ph = index_drag_h; _p = palette[index_dragging]; _pa = _color_get_alpha(_p); if(_pa < 1) { draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph - ui(8), _p, 1); draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw, ui(6), c_black, 1); draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw * _pa, ui(6), c_white, 1); } else draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph, _p, 1); draw_sprite_stretched_ext(THEME.palette_selecting, 0, _px - _pd, _py - _pd, _pw + _pd * 2, _ph + _pd * 2, c_white, 1); if(hover > -1 && hover != index_dragging) { draw_set_color(COLORS.dialog_palette_divider); var sx = hvx; if(hover >= index_dragging) sx += ww; var tt = palette[index_dragging]; array_delete(palette, index_dragging, 1); array_insert(palette, hover, tt); index_selecting = hover; index_dragging = hover; onApply(palette); } if(mouse_release(mb_left)) index_dragging = -1; } else { index_drag_x = 0; index_drag_y = 0; index_drag_w = 0; index_drag_h = 0; } if(mouse_press(mb_left, sFOCUS) && hover > -1) { index_selecting = hover; if(interactable) index_dragging = hover; selector.setColor(palette[hover]); } var bx = content_x + content_w - ui(50); var by = pl_y - ui(2); if(array_length(palette) > 1) { if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.minus) == 2) { array_delete(palette, index_selecting, 1); index_selecting = clamp(index_selecting - 1, 0, array_length(palette) - 1); onApply(palette); } } else { draw_sprite_ui_uniform(THEME.minus, 0, bx + ui(14), by + ui(14), 1, COLORS._main_icon, 0.5); } bx -= ui(32); if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.add) == 2) { index_selecting = array_length(palette); palette[array_length(palette)] = c_black; onApply(palette); } bx = content_x + ui(18); if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_load", "Load palette file") + " (.hex)", THEME.file) == 2) { var path = get_open_filename("HEX palette|*.hex", ""); key_release(); if(isPaletteFile(path)) { palette = loadPalette(path); onApply(palette); } } draw_sprite_ui_uniform(THEME.file, 0, bx + ui(14), by + ui(14), 1, COLORS._main_icon); #endregion #region selector var col_x = content_x + ui(20); var col_y = dialog_y + ui(70) + hh; selector.draw(col_x, col_y, sFOCUS, sHOVER); #endregion #region controls var bx = content_x + content_w - ui(36); var by = dialog_y + dialog_h - ui(36); b_apply.register(); b_apply.setFocusHover(sFOCUS, sHOVER); b_apply.draw(bx - ui(18), by - ui(18), ui(36), ui(36), mouse_ui, THEME.button_lime); bx -= ui(48); b_cancel.register(); b_cancel.setFocusHover(sFOCUS, sHOVER); b_cancel.draw(bx - ui(18), by - ui(18), ui(36), ui(36), mouse_ui, THEME.button_hide); #endregion #event draw_gui_end selector.colorPicker();