Pixel-Composer/scripts/panel_preview/panel_preview.gml

2334 lines
104 KiB
Plaintext

#region funtion calls
function panel_preview_focus_content() { CALL("preview_focus_content"); PANEL_PREVIEW.fullView(); }
function panel_preview_save_current_frame() { CALL("preview_save_current_frame"); PANEL_PREVIEW.saveCurrentFrame(); }
function panel_preview_saveCurrentFrameToFocus() { CALL("preview_save_to_focused_file"); PANEL_PREVIEW.saveCurrentFrameToFocus(); }
function panel_preview_save_all_current_frame() { CALL("preview_save_all_current_frame"); PANEL_PREVIEW.saveAllCurrentFrames(); }
function panel_preview_preview_window() { CALL("preview_preview_window"); PANEL_PREVIEW.create_preview_window(PANEL_PREVIEW.getNodePreview()); }
function panel_preview_toggle_grid() { CALL("preview_toggle_grid"); PROJECT.previewGrid.show = !PROJECT.previewGrid.show; }
function panel_preview_pan() { CALL("preview_pan"); PANEL_PREVIEW.canvas_dragging_key = true; }
function panel_preview_zoom() { CALL("preview_zoom"); PANEL_PREVIEW.canvas_zooming_key = true; }
function panel_preview_3d_view_front() { CALL("preview_3d_front_view"); PANEL_PREVIEW.d3_view_action_front(); }
function panel_preview_3d_view_back() { CALL("preview_3d_back_view"); PANEL_PREVIEW.d3_view_action_back(); }
function panel_preview_3d_view_right() { CALL("preview_3d_right_view"); PANEL_PREVIEW.d3_view_action_right(); }
function panel_preview_3d_view_left() { CALL("preview_3d_left_view"); PANEL_PREVIEW.d3_view_action_left(); }
function panel_preview_3d_view_top() { CALL("preview_3d_top_view"); PANEL_PREVIEW.d3_view_action_top(); }
function panel_preview_3d_view_bottom() { CALL("preview_3d_bottom_view"); PANEL_PREVIEW.d3_view_action_bottom(); }
function panel_preview_set_zoom(zoom) { CALL("preview_preview_set_zoom"); PANEL_PREVIEW.fullView(zoom); }
function panel_preview_set_tile_off() { CALL("preview_set_tile_off"); PANEL_PREVIEW.set_tile_off(); }
function panel_preview_set_tile_horizontal() { CALL("preview_set_tile_horizontal"); PANEL_PREVIEW.set_tile_horizontal(); }
function panel_preview_set_tile_vertical() { CALL("preview_set_tile_vertical"); PANEL_PREVIEW.set_tile_vertical(); }
function panel_preview_set_tile_both() { CALL("preview_set_tile_both"); PANEL_PREVIEW.set_tile_both(); }
function panel_preview_set_tile_toggle() { CALL("preview_set_tile_toggle"); PANEL_PREVIEW.toggle_tile(); }
function panel_preview_set_split_off() { CALL("preview_set_split_off"); PANEL_PREVIEW.set_split_off(); }
function panel_preview_set_split_horizontal() { CALL("preview_set_split_horizontal"); PANEL_PREVIEW.set_split_horizontal(); }
function panel_preview_set_split_vertical() { CALL("preview_set_split_vertical"); PANEL_PREVIEW.set_split_vertical(); }
function panel_preview_toggle_split_view() { CALL("preview_toggle_split_view"); PANEL_PREVIEW.toggle_split_view(); }
function panel_preview_new_preview_window() { CALL("preview_new_preview_window"); PANEL_PREVIEW.new_preview_window(); }
function panel_preview_saveCurrentFrame() { CALL("preview_saveCurrentFrame"); PANEL_PREVIEW.saveCurrentFrame(); }
function panel_preview_saveAllCurrentFrames() { CALL("preview_saveAllCurrentFrames"); PANEL_PREVIEW.saveAllCurrentFrames(); }
function panel_preview_copyCurrentFrame() { CALL("preview_copyCurrentFrame"); PANEL_PREVIEW.copyCurrentFrame(); }
function panel_preview_copy_color() { CALL("preview_copy_color"); PANEL_PREVIEW.copy_color(); }
function panel_preview_copy_color_hex() { CALL("preview_copy_color_hex"); PANEL_PREVIEW.copy_color_hex(); }
function panel_preview_toggle_grid_pixel() { CALL("preview_toggle_grid_pixel"); PROJECT.previewGrid.pixel = !PROJECT.previewGrid.pixel; }
function panel_preview_toggle_grid_visible() { CALL("preview_toggle_grid_visible"); PROJECT.previewGrid.show = !PROJECT.previewGrid.show; }
function panel_preview_toggle_grid_snap() { CALL("preview_toggle_grid_snap"); PROJECT.previewGrid.snap = !PROJECT.previewGrid.snap; }
function panel_preview_onion_enabled() { CALL("preview_onion_enabled"); PROJECT.onion_skin.enabled = !PROJECT.onion_skin.enabled; }
function panel_preview_onion_on_top() { CALL("preview_onion_on_top"); PROJECT.onion_skin.on_top = !PROJECT.onion_skin.on_top; }
function panel_preview_set_reset_view_off() { CALL("preview_set_reset_view_off"); PANEL_PREVIEW.set_reset_view_off(); }
function panel_preview_set_reset_view_on() { CALL("preview_set_reset_view_on"); PANEL_PREVIEW.set_reset_view_on(); }
function panel_preview_toggle_reset_view() { CALL("preview_toggle_reset_view"); PANEL_PREVIEW.toggle_reset_view(); }
function panel_preview_show_info() { CALL("preview_show_info"); PANEL_PREVIEW.show_info = !PANEL_PREVIEW.show_info; }
function panel_preview_toggle_lock() { CALL("preview_toggle_lock"); PANEL_PREVIEW.toggle_lock(); }
function __fnInit_Preview() {
registerFunction("Preview", "Focus content", "F", MOD_KEY.none, panel_preview_focus_content ).setMenu("preview_focus_content", THEME.icon_center_canvas)
registerFunction("Preview", "Save current frame", "S", MOD_KEY.shift, panel_preview_save_current_frame ).setMenu("preview_save_current_frame")
registerFunction("Preview", "Save to focused file", "", MOD_KEY.none, panel_preview_saveCurrentFrameToFocus ).setMenu("preview_save_to_focused_file")
registerFunction("Preview", "Save all current frame", "", MOD_KEY.none, panel_preview_save_all_current_frame ).setMenu("preview_save_all_current_frame")
registerFunction("Preview", "Preview window", "P", MOD_KEY.ctrl, panel_preview_preview_window ).setMenu("preview_preview_window")
registerFunction("Preview", "Toggle grid", "G", MOD_KEY.ctrl, panel_preview_toggle_grid ).setMenu("preview_toggle_grid")
registerFunction("Preview", "Pan", "", MOD_KEY.ctrl, panel_preview_pan ).setMenu("preview_pan")
registerFunction("Preview", "Zoom", "", MOD_KEY.alt | MOD_KEY.ctrl, panel_preview_zoom ).setMenu("preview_zoom")
registerFunction("Preview", "3D Front view", vk_numpad1, MOD_KEY.none, panel_preview_3d_view_front ).setMenu("preview_3d_front_view")
registerFunction("Preview", "3D Back view", vk_numpad1, MOD_KEY.alt, panel_preview_3d_view_back ).setMenu("preview_3d_back_view")
registerFunction("Preview", "3D Right view ", vk_numpad3, MOD_KEY.none, panel_preview_3d_view_right ).setMenu("preview_3d_right_view")
registerFunction("Preview", "3D Left view ", vk_numpad3, MOD_KEY.alt, panel_preview_3d_view_left ).setMenu("preview_3d_left_view")
registerFunction("Preview", "3D Top view", vk_numpad7, MOD_KEY.none, panel_preview_3d_view_top ).setMenu("preview_3d_top_view")
registerFunction("Preview", "3D Bottom view", vk_numpad7, MOD_KEY.alt, panel_preview_3d_view_bottom ).setMenu("preview_3d_bottom_view")
registerFunction("Preview", "Scale x1", "1", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(1) } ).setMenu("preview_scale_x1")
registerFunction("Preview", "Scale x2", "2", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(2) } ).setMenu("preview_scale_x2")
registerFunction("Preview", "Scale x4", "3", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(4) } ).setMenu("preview_scale_x4")
registerFunction("Preview", "Scale x8", "4", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(8) } ).setMenu("preview_scale_x8")
registerFunction("Preview", "Tile Off", "", MOD_KEY.none, panel_preview_set_tile_off ).setMenu("preview_set_tile_off")
registerFunction("Preview", "Tile Horizontal", "", MOD_KEY.none, panel_preview_set_tile_horizontal ).setMenu("preview_set_tile_horizontal")
registerFunction("Preview", "Tile Vertical", "", MOD_KEY.none, panel_preview_set_tile_vertical ).setMenu("preview_set_tile_vertical")
registerFunction("Preview", "Tile Both", "", MOD_KEY.none, panel_preview_set_tile_both ).setMenu("preview_set_tile_both")
registerFunction("Preview", "Toggle Tile", "", MOD_KEY.none, panel_preview_set_tile_toggle ).setMenu("preview_toggle_tile")
registerFunction("Preview", "Tiling Settings", "", MOD_KEY.none, function(_dat) /*=>*/ { submenuCall(_dat, [
MENU_ITEMS.preview_set_tile_off,
MENU_ITEMS.preview_set_tile_horizontal,
MENU_ITEMS.preview_set_tile_vertical,
MENU_ITEMS.preview_set_tile_both,
]) }).setMenu("preview_tiling_settings")
registerFunction("Preview", "Split View Off", "", MOD_KEY.none, panel_preview_set_split_off ).setMenu("preview_set_split_off")
registerFunction("Preview", "Split View Horizontal", "", MOD_KEY.none, panel_preview_set_split_horizontal ).setMenu("preview_set_split_horizontal")
registerFunction("Preview", "Split View Vertical", "", MOD_KEY.none, panel_preview_set_split_vertical ).setMenu("preview_set_split_vertical")
registerFunction("Preview", "Toggle Split View", "", MOD_KEY.none, panel_preview_toggle_split_view ).setMenu("preview_toggle_split_view")
registerFunction("Preview", "Split View Settings", "", MOD_KEY.none, function(_dat) /*=>*/ { submenuCall(_dat, [
MENU_ITEMS.preview_set_split_off,
MENU_ITEMS.preview_set_split_horizontal,
MENU_ITEMS.preview_set_split_vertical,
]) }).setMenu("preview_split_view_settings")
registerFunction("Preview", "Set Reset View Off", "", MOD_KEY.none, panel_preview_set_reset_view_off ).setMenu("preview_set_reset_view_off")
registerFunction("Preview", "Set Reset View On", "", MOD_KEY.none, panel_preview_set_reset_view_on ).setMenu("preview_set_reset_view_on")
registerFunction("Preview", "Toggle Reset View", "", MOD_KEY.none, panel_preview_toggle_reset_view ).setMenu("preview_toggle_reset_view")
registerFunction("Preview", "New Preview Window", "", MOD_KEY.none, panel_preview_new_preview_window ).setMenu("preview_new_preview_window")
registerFunction("Preview", "Save Current Frame", "", MOD_KEY.none, panel_preview_saveCurrentFrame ).setMenu("preview_save_current_frame")
registerFunction("Preview", "Save All Current Frames", "", MOD_KEY.none, panel_preview_saveAllCurrentFrames ).setMenu("preview_save_all_current_frames")
registerFunction("Preview", "Copy Current Frame", "", MOD_KEY.none, panel_preview_copyCurrentFrame ).setMenu("preview_copy_current_frame", THEME.copy)
registerFunction("Preview", "Copy Color", "", MOD_KEY.none, panel_preview_copy_color ).setMenu("preview_copy_color")
registerFunction("Preview", "Copy Color Hex", "", MOD_KEY.none, panel_preview_copy_color_hex ).setMenu("preview_copy_color_hex")
registerFunction("Preview", "Toggle Pixel Grid", "", MOD_KEY.none, panel_preview_toggle_grid_pixel ).setMenu("preview_toggle_grid_pixel")
registerFunction("Preview", "Toggle Grid", "", MOD_KEY.none, panel_preview_toggle_grid_visible ).setMenu("preview_toggle_grid_visible")
registerFunction("Preview", "Toggle Snap to Grid", "", MOD_KEY.none, panel_preview_toggle_grid_snap ).setMenu("preview_toggle_grid_snap")
registerFunction("Preview", "Toggle Onion Skin", "", MOD_KEY.none, panel_preview_onion_enabled ).setMenu("preview_onion_enabled")
registerFunction("Preview", "Toggle Onion Skin view", "", MOD_KEY.none, panel_preview_onion_on_top ).setMenu("preview_onion_on_top")
registerFunction("Preview", "Toggle Show Info", "", MOD_KEY.none, panel_preview_show_info ).setMenu("preview_show_info")
registerFunction("Preview", "Toggle Lock", "", MOD_KEY.none, panel_preview_toggle_lock ).setMenu("preview_toggle_lock")
registerFunction("Preview", "Grid Settings", "", MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Preview_Grid_Setting()) }).setMenu("preview_grid_settings")
registerFunction("Preview", "Onion Skin Settings", "", MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Preview_Onion_Setting()) }).setMenu("preview_onion_settings")
registerFunction("Preview", "3D View Settings", "", MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Preview_3D_Setting(PANEL_PREVIEW)) }).setMenu("preview_3D_settings")
registerFunction("Preview", "3D SDF View Settings", "", MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Preview_3D_SDF_Setting(PANEL_PREVIEW)) }).setMenu("preview_3D_SDF_settings")
registerFunction("Preview", "3D Snap Settings", "", MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(PANEL_PREVIEW)) }).setMenu("preview_snap_settings")
registerFunction("Preview", "View Settings", "", MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Preview_View_Setting(PANEL_PREVIEW)) }).setMenu("preview_view_settings")
__fnGroupInit_Preview();
}
function __fnGroupInit_Preview() {
MENU_ITEMS.preview_group_preview_bg = menuItemGroup(__txtx("panel_menu_preview_background", "Preview background"), [
[ s_preview_transparent, function() { PANEL_PREVIEW.canvas_bg = -1; } ],
[ s_preview_white, function() { PANEL_PREVIEW.canvas_bg = c_white; } ],
[ s_preview_black, function() { PANEL_PREVIEW.canvas_bg = c_black; } ],
], ["Preview", "Background"]);
registerFunction("Preview", "Background", "", MOD_KEY.none, function() /*=>*/ { menuCall("", [ MENU_ITEMS.menu_group_preview_bg ]); });
}
#endregion
function Panel_Preview() : PanelContent() constructor {
title = __txt("Preview");
context_str = "Preview";
icon = THEME.panel_preview_icon;
last_focus = noone;
#region ---- canvas control & sample ----
function initSize() { canvas_x = w / 2; canvas_y = h / 2; }
run_in(1, function() /*=>*/ { initSize() });
canvas_x = 0;
canvas_y = 0;
canvas_s = 1;
canvas_w = ui(128);
canvas_h = ui(128);
canvas_a = 0;
canvas_bg = -1;
do_fullView = false;
canvas_hover = true;
canvas_dragging_key = false;
canvas_dragging = false;
canvas_drag_key = 0;
canvas_drag_mx = 0;
canvas_drag_my = 0;
canvas_drag_sx = 0;
canvas_drag_sy = 0;
canvas_zooming_key = false;
canvas_zooming = false;
canvas_zoom_mx = 0;
canvas_zoom_my = 0;
canvas_zoom_m = 0;
canvas_zoom_s = 0;
view_pan_tool = false;
view_zoom_tool = false;
sample_color = noone;
sample_x = noone;
sample_y = noone;
#endregion
#region ---- preview ----
locked = false;
preview_node = [ noone, noone ];
preview_surfaces = [ 0, 0 ];
preview_surface = [ 0, 0 ];
tile_surface = surface_create(1, 1);
preview_x = 0;
preview_x_to = 0;
preview_x_max = 0;
preview_sequence = [ 0, 0 ];
_preview_sequence = preview_sequence;
preview_rate = 10;
right_menu_x = 0;
right_menu_y = 8;
mouse_on_preview = 0;
_mouse_on_preview = 0;
splitView = 0;
splitPosition = 0.5;
splitSelection = 0;
splitViewDragging = false;
splitViewStart = 0;
splitViewMouse = 0;
tileMode = 0;
bg_color = COLORS.panel_bg_clear;
mouse_pos_string = "";
show_info = true;
show_view_control = 1;
resetViewOnDoubleClick = true;
#endregion
#region ---- tool ----
tool_x = 0;
tool_x_to = 0;
tool_x_max = 0;
tool_y = 0;
tool_y_to = 0;
tool_y_max = 0;
tool_ry = 0;
tool_ry_to = 0;
tool_ry_max = 0;
tool_current = noone;
toolbar_width = ui(40);
toolbar_height = ui(40);
tool_hovering = noone;
tool_side_draw_l = false;
tool_side_draw_r = false;
overlay_hovering = false;
view_hovering = false;
sbChannel = new scrollBox([], function(index) {
var node = __getNodePreview();
if(node == noone) return;
node.preview_channel = sbChannelIndex[index].index;
node.setHeight();
});
sbChannelIndex = [];
sbChannel.font = f_p1;
sbChannel.align = fa_left;
#endregion
#region ---- 3d ----
d3_active = NODE_3D.none;
d3_active_transition = 0;
d3_surface = noone;
d3_surface_normal = noone;
d3_surface_depth = noone;
d3_surface_outline = noone;
d3_surface_bg = noone;
d3_preview_channel = 0;
d3_deferData = noone;
d3_drawBG = false;
global.SKY_SPHERE = new __3dUVSphere(0.5, 16, 8, true);
#region camera
d3_view_camera = new __3dCamera();
d3_camW = 1;
d3_camH = 1;
d3_view_camera.setFocusAngle(135, 45, 4);
d3_camLerp = 0;
d3_camLerp_x = 0;
d3_camLerp_y = 0;
d3_camTarget = new __vec3();
d3_camPanning = false;
d3_camPan_mx = 0;
d3_camPan_my = 0;
d3_zoom_speed = 0.2;
d3_pan_speed = 2;
#endregion
#region scene
d3_scene = new __3dScene(d3_view_camera, "Preview panel");
d3_scene.lightAmbient = $404040;
d3_scene.cull_mode = cull_counterclockwise;
d3_scene_preview = d3_scene;
d3_scene_light_enabled = true;
d3_scene_light0 = new __3dLightDirectional();
d3_scene_light0.color = $FFFFFF;
d3_scene_light0.shadow_active = false;
d3_scene_light0.shadow_map_scale = 4;
d3_scene_light0.transform.position.set(-1, -2, 3);
d3_scene_light1 = new __3dLightDirectional();
d3_scene_light1.color = $505050;
d3_scene_light1.transform.position.set(1, 2, -3);
#endregion
#region tool
d3_tool_snap = false;
d3_tool_snap_position = 1;
d3_tool_snap_rotation = 15;
#endregion
#endregion
tb_framerate = new textBox(TEXTBOX_INPUT.number, function(val) { preview_rate = real(val); });
#region ++++ toolbars & actions ++++
static set_tile_off = function() /*=>*/ { tileMode = 0; }
static set_tile_horizontal = function() /*=>*/ { tileMode = 1; }
static set_tile_vertical = function() /*=>*/ { tileMode = 2; }
static set_tile_both = function() /*=>*/ { tileMode = 3; }
static toggle_tile = function() /*=>*/ { tileMode = (tileMode + 1) % 4; }
static new_preview_window = function() /*=>*/ { create_preview_window(getNodePreview()); }
static copy_color = function() /*=>*/ { clipboard_set_text(sample_color); }
static copy_color_hex = function() /*=>*/ { clipboard_set_text(color_get_hex(sample_color)); }
static set_reset_view_off = function() /*=>*/ { resetViewOnDoubleClick = 0; }
static set_reset_view_on = function() /*=>*/ { resetViewOnDoubleClick = 1; }
static toggle_reset_view = function() /*=>*/ { resetViewOnDoubleClick = !resetViewOnDoubleClick; }
static set_split_off = function() /*=>*/ { splitView = 0; }
static set_split_horizontal= function() /*=>*/ { splitView = 1; }
static set_split_vertical = function() /*=>*/ { splitView = 2; }
static toggle_split_view = function() /*=>*/ { splitView = (splitView + 1) % 3; }
static toggle_lock = function() /*=>*/ { locked = !locked }
topbar_height = ui(32);
toolbar_height = ui(40);
toolbars = [
[
THEME.icon_reset_when_preview,
function() /*=>*/ {return !resetViewOnDoubleClick},
new tooltipSelector(__txtx("panel_preview_on_preview", "On preview"), [ __txt("Keep view"), __txt("Center view") ]),
toggle_reset_view,
function(data) /*=>*/ {
menuCall("preview_reset_view_menu", [
MENU_ITEMS.preview_set_reset_view_off,
MENU_ITEMS.preview_set_reset_view_on,
], data.x + ui(28), data.y + ui(28));
},
],
[
THEME.icon_split_view,
function() /*=>*/ {return splitView},
new tooltipSelector(__txt("Split view"), [ __txt("Off"), __txt("Horizontal"), __txt("Vertical"), ]),
toggle_split_view,
function(data) /*=>*/ {
menuCall("preview_split_menu", [
MENU_ITEMS.preview_set_split_off,
MENU_ITEMS.preview_set_split_horizontal,
MENU_ITEMS.preview_set_split_vertical,
], data.x + ui(28), data.y + ui(28));
},
],
[
THEME.icon_tile_view,
function() /*=>*/ {return tileMode},
new tooltipSelector(__txt("Tiling"), [ __txt("Off"), __txt("Horizontal"), __txt("Vertical"), __txt("Both") ]),
toggle_tile,
function(data) /*=>*/ {
menuCall("preview_tile_menu", [
MENU_ITEMS.preview_set_tile_off,
MENU_ITEMS.preview_set_tile_horizontal,
MENU_ITEMS.preview_set_tile_vertical,
MENU_ITEMS.preview_set_tile_both,
], data.x + ui(28), data.y + ui(28));
},
],
[
THEME.icon_grid_setting,
function() /*=>*/ {return 0},
function() /*=>*/ {return new tooltipHotkey(__txtx("grid_title", "Grid settings") + "...", "Preview", "Grid Settings")},
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
],
[
THEME.onion_skin,
function() /*=>*/ {return 0},
function() /*=>*/ {return new tooltipHotkey(__txt("Onion Skin") + "...", "Preview", "Onion Skin Settings")},
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Onion_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
],
];
toolbars_3d = [
[
THEME.d3d_preview_settings,
function() /*=>*/ {return 0},
function() /*=>*/ {return new tooltipHotkey(__txt("3D Preview Settings") + "...", "Preview", "3D View Settings")},
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_3D_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
],
[
THEME.d3d_snap_settings,
function() /*=>*/ {return 0},
function() /*=>*/ {return new tooltipHotkey(__txt("3D Snap Settings") + "...", "Preview", "3D Snap Settings")},
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
],
];
toolbars_3d_sdf = [
[
THEME.d3d_preview_settings,
function() /*=>*/ {return 0},
function() /*=>*/ {return new tooltipHotkey(__txt("3D SDF Preview Settings") + "...", "Preview", "3D SDF View Settings")},
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_3D_SDF_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
],
[
THEME.d3d_snap_settings,
function() /*=>*/ {return 0},
function() /*=>*/ {return new tooltipHotkey(__txt("3D Snap Settings") + "...", "Preview", "3D Snap Settings")},
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
],
];
actions = [
[
THEME.lock,
new tooltipHotkey(__txtx("panel_preview_lock_preview", "Lock previewing node"), "Preview", "Toggle Lock"),
toggle_lock,
function() /*=>*/ {return !locked},
],
[
THEME.icon_preview_export,
new tooltipHotkey(__txtx("panel_preview_export_canvas", "Export canvas"), "Preview", "Save current frame"),
function() /*=>*/ { saveCurrentFrame(); },
function() /*=>*/ {return 0},
],
[
THEME.icon_center_canvas,
new tooltipHotkey(__txtx("panel_preview_center_canvas", "Center canvas"), "Preview", "Focus content"),
function() /*=>*/ { fullView(); },
function() /*=>*/ {return 0},
],
[
THEME.icon_visibility,
new tooltipHotkey(__txtx("graph_visibility_title", "Visibility settings") + "...", "Preview", "View Settings"),
function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_View_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); },
function() /*=>*/ {return 0},
],
];
static d3_view_action_front = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = 0; }
static d3_view_action_back = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 180; d3_camLerp_y = 0; }
static d3_view_action_right = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 90; d3_camLerp_y = 0; }
static d3_view_action_left = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = -90; d3_camLerp_y = 0; }
static d3_view_action_bottom = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = -89; }
static d3_view_action_top = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = 89; }
#endregion
////============ DATA ============
function setNodePreview(node) {
if(locked) return;
if(resetViewOnDoubleClick)
do_fullView = true;
preview_node[splitView? splitSelection : 0] = node;
}
function removeNodePreview(node) {
if(locked) return;
if(preview_node[0] == node) preview_node[0] = noone;
if(preview_node[1] == node) preview_node[1] = noone;
}
function resetNodePreview() {
preview_node = [ noone, noone ];
locked = false;
}
function __getNodePreview() { return preview_node[splitView? splitSelection : 0]; }
function getNodePreview() {
var _node = __getNodePreview();
if(_node == noone) return noone;
if(!_node.project.active) {
resetNodePreview();
return noone;
}
if(is_instanceof(_node, Node))
_node = _node.getPreviewingNode();
return _node;
}
function getNodePreviewSurface() { return preview_surfaces[splitView? splitSelection : 0]; }
function getNodePreviewSequence() { return preview_sequence[splitView? splitSelection : 0]; }
function getPreviewData() { #region
preview_surfaces = [ noone, noone ];
preview_sequence = [ noone, noone ];
for( var i = 0; i < 2; i++ ) {
var node = preview_node[i];
if(node == noone) continue;
if(!node.active) {
resetNodePreview();
return;
}
var value = node.getPreviewValues();
if(is_array(value)) {
preview_sequence[i] = value;
canvas_a = array_length(value);
} else {
preview_surfaces[i] = value;
canvas_a = 0;
}
if(preview_sequence[i] != noone) {
if(array_length(preview_sequence[i]) == 0) return;
preview_surfaces[i] = preview_sequence[i][safe_mod(node.preview_index, array_length(preview_sequence[i]))];
}
}
var prevS = getNodePreviewSurface();
if(is_surface(prevS)) {
canvas_w = surface_get_width_safe(prevS);
canvas_h = surface_get_height_safe(prevS);
}
} #endregion
function onFocusBegin() { PANEL_PREVIEW = self; }
////============ VIEW ============
function dragCanvas() {
if(canvas_dragging) {
if(!MOUSE_WRAPPING) {
var dx = mx - canvas_drag_mx;
var dy = my - canvas_drag_my;
canvas_x += dx;
canvas_y += dy;
}
canvas_drag_mx = mx;
canvas_drag_my = my;
setMouseWrap();
if(mouse_release(canvas_drag_key)) {
canvas_dragging = false;
view_pan_tool = false;
}
}
if(canvas_zooming) {
if(!MOUSE_WRAPPING) {
// var mdx = mx - canvas_zoom_mx;
var mdy = my - canvas_zoom_m;
var dd = -(mdy) / 200;
var _s = canvas_s;
canvas_s = clamp(canvas_s * (1 + dd), 0.10, 64);
if(_s != canvas_s) {
var dx = (canvas_s - _s) * ((canvas_zoom_mx - canvas_x) / _s);
var dy = (canvas_s - _s) * ((canvas_zoom_my - canvas_y) / _s);
canvas_x -= dx;
canvas_y -= dy;
}
}
canvas_zoom_m = my;
setMouseWrap();
if(mouse_release(canvas_drag_key)) {
canvas_zooming = false;
view_zoom_tool = false;
}
}
if(pHOVER && canvas_hover) {
var _doDragging = false;
var _doZooming = false;
if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) {
_doDragging = true;
canvas_drag_key = PREFERENCES.pan_mouse_key;
} else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) {
_doDragging = true;
canvas_drag_key = mb_left;
} else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) {
_doZooming = true;
canvas_drag_key = mb_left;
}
if(_doDragging) {
canvas_dragging = true;
canvas_drag_mx = mx;
canvas_drag_my = my;
canvas_drag_sx = canvas_x;
canvas_drag_sy = canvas_y;
}
if(_doZooming) {
canvas_zooming = true;
canvas_zoom_mx = mx;
canvas_zoom_my = my;
canvas_zoom_m = my;
canvas_zoom_s = canvas_s;
}
var _canvas_s = canvas_s;
var inc = 0.1;
if(canvas_s > 16) inc = 2;
else if(canvas_s > 8) inc = 1;
else if(canvas_s > 3) inc = 0.5;
else if(canvas_s > 1) inc = 0.25;
if(mouse_wheel_down() && !key_mod_press_any()) canvas_s = max(round(canvas_s / inc) * inc - inc, 0.10);
if(mouse_wheel_up() && !key_mod_press_any()) canvas_s = min(round(canvas_s / inc) * inc + inc, 1024);
if(_canvas_s != canvas_s) {
var dx = (canvas_s - _canvas_s) * ((mx - canvas_x) / _canvas_s);
var dy = (canvas_s - _canvas_s) * ((my - canvas_y) / _canvas_s);
canvas_x -= dx;
canvas_y -= dy;
}
}
canvas_dragging_key = false;
canvas_zooming_key = false;
canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height);
}
function dragCanvas3D() {
if(d3_camLerp) {
d3_view_camera.focus_angle_x = lerp_float(d3_view_camera.focus_angle_x, d3_camLerp_x, 3, 1);
d3_view_camera.focus_angle_y = lerp_float(d3_view_camera.focus_angle_y, d3_camLerp_y, 3, 1);
if(d3_view_camera.focus_angle_x == d3_camLerp_x && d3_view_camera.focus_angle_y == d3_camLerp_y)
d3_camLerp = false;
}
if(d3_camPanning) {
if(!MOUSE_WRAPPING) {
var dx = mx - d3_camPan_mx;
var dy = my - d3_camPan_my;
var px = d3_view_camera.focus_angle_x;
var py = d3_view_camera.focus_angle_y;
var ax = px + dx * 0.2 * d3_pan_speed;
var ay = py + dy * 0.1 * d3_pan_speed;
//if(py < 90 && ay >= 90) ax -= 180;
//if(py > 90 && ay <= 90) ax += 180;
//print($"{ax},\t{ay}");
d3_view_camera.focus_angle_x = ax;
d3_view_camera.focus_angle_y = ay;
}
d3_camPan_mx = mx;
d3_camPan_my = my;
setMouseWrap();
if(mouse_release(canvas_drag_key)) {
d3_camPanning = false;
view_pan_tool = false;
}
}
if(canvas_zooming) {
if(!MOUSE_WRAPPING) {
var dy = -(my - canvas_zoom_m) / 200;
d3_view_camera.focus_dist = clamp(d3_view_camera.focus_dist + dy, 1, 1000);
}
canvas_zoom_m = my;
setMouseWrap();
if(mouse_release(canvas_drag_key)) {
canvas_zooming = false;
view_zoom_tool = false;
}
}
if(pHOVER && canvas_hover) {
var _doDragging = false;
var _doZooming = false;
if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) {
_doDragging = true;
canvas_drag_key = PREFERENCES.pan_mouse_key;
} else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) {
_doDragging = true;
canvas_drag_key = mb_left;
} else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) {
_doZooming = true;
canvas_drag_key = mb_left;
}
if(_doDragging) {
d3_camPanning = true;
d3_camPan_mx = mx;
d3_camPan_my = my;
}
if(_doZooming) {
canvas_zooming = true;
canvas_zoom_m = my;
}
if(mouse_wheel_up()) d3_view_camera.focus_dist = max( 1, d3_view_camera.focus_dist * (1 - d3_zoom_speed));
if(mouse_wheel_down()) d3_view_camera.focus_dist = min(1000, d3_view_camera.focus_dist * (1 + d3_zoom_speed));
}
canvas_dragging_key = false;
canvas_zooming_key = false;
canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height);
}
function fullView(scale = 0) {
var bbox = noone;
var node = getNodePreview();
if(node != noone) bbox = node.getPreviewBoundingBox();
if(bbox == noone) bbox = BBOX().fromWH(0, 0, PROJECT.attributes.surface_dimension[0], PROJECT.attributes.surface_dimension[1]);
var _x = bbox.x0, _y = bbox.y0;
var _w = bbox.w, _h = bbox.h;
if(_w == 0 || _h == 0) {
_x = 0;
_y = 0;
_w = DEF_SURF_W;
_h = DEF_SURF_H;
}
var tl = tool_side_draw_l * 40;
var tr = tool_side_draw_r * 40;
var ss = scale == 0? min((w - 32 - tl - tr) / _w, (h - 32 - toolbar_height * 2) / _h) : scale;
canvas_s = ss;
canvas_x = w / 2 - _w * canvas_s / 2 - _x * canvas_s + (tl - tr) / 2;
canvas_y = h / 2 - _h * canvas_s / 2 - _y * canvas_s;
}
function drawNodeChannel(_node, _x, _y) {
if(array_length(_node.outputs) < 2) return 0;
var chName = [];
sbChannelIndex = [];
var currName = _node.outputs[_node.preview_channel].name;
draw_set_text(sbChannel.font, fa_center, fa_center);
var ww = 0;
var hh = TEXTBOX_HEIGHT - ui(2);
var _am = _node.getOutputJunctionAmount();
for( var i = 0; i < _am; i++ ) {
var _outi = _node.getOutputJunctionIndex(i);
var _outj = _node.outputs[_outi];
array_push(chName, _outj.name);
array_push(sbChannelIndex, _outj);
ww = max(ww, string_width(_outj.name) + ui(40));
}
if(!array_empty(chName)) {
sbChannel.data_list = chName;
sbChannel.setFocusHover(pFOCUS, pHOVER);
sbChannel.draw(_x - ww, _y - hh / 2, ww, hh, currName, [mx, my], x, y);
right_menu_y += ui(40);
}
return ww + ui(4);
}
static onFullScreen = function() { run_in(1, fullView); }
////============ DRAW ============
function drawOnionSkin(node, psx, psy, ss) {
var _surf = preview_surfaces[0];
var _rang = PROJECT.onion_skin.range;
var _alph = PROJECT.onion_skin.alpha;
var _colr = PROJECT.onion_skin.color;
var _step = PROJECT.onion_skin.step;
var _top = PROJECT.onion_skin.on_top;
var fr = CURRENT_FRAME;
var st = min(_rang[0], _rang[1]);
var ed = max(_rang[0], _rang[1]);
st = sign(st) * floor(abs(st) / _step) * _step;
ed = sign(ed) * floor(abs(ed) / _step) * _step;
st += fr;
ed += fr;
var surf, aa, cc;
if(!_top) {
draw_surface_ext_safe(_surf, psx, psy, ss, ss);
BLEND_ADD
}
for( var i = st; i <= ed; i += _step ) {
surf = node.getCacheFrame(i);
if(!is_surface(surf)) continue;
aa = power(_alph, abs((i - fr) / _step));
cc = c_white;
if(i < fr) cc = _colr[0];
else if(i > fr) cc = _colr[1];
draw_surface_ext_safe(surf, psx, psy, ss, ss, 0, cc, aa);
}
BLEND_NORMAL
if(_top) draw_surface_ext_safe(_surf, psx, psy, ss, ss);
}
function drawNodePreview() {
var ss = canvas_s;
var psx = 0, psy = 0;
var psw = 0, psh = 0;
var pswd = 0, pshd = 0;
var psx1 = 0, psy1 = 0;
var ssx = 0, ssy = 0;
var ssw = 0, ssh = 0;
if(is_surface(preview_surfaces[0])) {
psx = canvas_x + preview_node[0].preview_x * ss;
psy = canvas_y + preview_node[0].preview_y * ss;
psw = surface_get_width_safe(preview_surfaces[0]);
psh = surface_get_height_safe(preview_surfaces[0]);
pswd = psw * ss;
pshd = psh * ss;
psx1 = psx + pswd;
psy1 = psy + pshd;
}
if(is_surface(preview_surfaces[1])) {
var ssx = canvas_x + preview_node[1].preview_x * ss;
var ssy = canvas_y + preview_node[1].preview_y * ss;
var ssw = surface_get_width_safe(preview_surfaces[1]);
var ssh = surface_get_height_safe(preview_surfaces[1]);
}
var _node = getNodePreview();
if(_node) title = _node.renamed? _node.display_name : _node.name;
#region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Draw Surfaces <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
var _ps0 = is_surface(preview_surfaces[0]);
var _ps1 = is_surface(preview_surfaces[1]);
if(_ps0) {
var _sw = surface_get_width_safe(preview_surfaces[0]);
var _sh = surface_get_height_safe(preview_surfaces[0]);
preview_surface[0] = surface_verify(preview_surface[0], _sw, _sh);
surface_set_shader(preview_surface[0], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample);
shader_set_f("palette", PROJECT.palettes);
shader_set_i("keys", array_length(PROJECT.attributes.palette));
shader_set_i("alpha", 1);
draw_surface_safe(preview_surfaces[0]);
surface_reset_shader();
}
if(_ps1) {
var _sw = surface_get_width_safe(preview_surfaces[1]);
var _sh = surface_get_height_safe(preview_surfaces[1]);
preview_surface[1] = surface_verify(preview_surface[1], _sw, _sh);
surface_set_shader(preview_surface[1], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample);
shader_set_f("palette", PROJECT.palettes);
shader_set_i("keys", array_length(PROJECT.attributes.palette));
shader_set_i("alpha", 1);
draw_surface_safe(preview_surfaces[1]);
surface_reset_shader();
}
switch(splitView) {
case 0 :
if(_ps0) {
preview_node[0].previewing = 1;
switch(tileMode) {
case 0 :
if(PROJECT.onion_skin.enabled) drawOnionSkin(_node, psx, psy, ss);
else draw_surface_ext(preview_surface[0], psx, psy, ss, ss, 0, c_white, preview_node[0].preview_alpha);
break;
case 1 :
tile_surface = surface_verify(tile_surface, w, surface_get_height_safe(preview_surface[0]) * ss);
surface_set_target(tile_surface);
DRAW_CLEAR
draw_surface_tiled_ext_safe(preview_surface[0], psx, 0, ss, ss, 0, c_white, 1);
surface_reset_target();
draw_surface_safe(tile_surface, 0, psy);
break;
case 2 :
tile_surface = surface_verify(tile_surface, surface_get_width_safe(preview_surface[0]) * ss, h);
surface_set_target(tile_surface);
DRAW_CLEAR
draw_surface_tiled_ext_safe(preview_surface[0], 0, psy, ss, ss, 0, c_white, 1);
surface_reset_target();
draw_surface_safe(tile_surface, psx, 0);
break;
case 3 :
draw_surface_tiled_ext_safe(preview_surface[0], psx, psy, ss, ss, 0, c_white, 1); break;
}
}
break;
case 1 :
var sp = splitPosition * w;
if(_ps0) {
preview_node[0].previewing = 2;
var maxX = min(sp, psx1);
var sW = min(psw, (maxX - psx) / ss);
if(sW > 0)
draw_surface_part_ext_safe(preview_surface[0], 0, 0, sW, psh, psx, psy, ss, ss, 0, c_white, 1);
}
if(_ps1) {
preview_node[1].previewing = 3;
var minX = max(ssx, sp);
var sX = (minX - ssx) / ss;
var spx = max(sp, ssx);
if(sX >= 0 && sX < ssw)
draw_surface_part_ext_safe(preview_surface[1], sX, 0, ssw - sX, ssh, spx, ssy, ss, ss, 0, c_white, 1);
}
break;
case 2 :
var sp = splitPosition * h;
if(_ps0) {
preview_node[0].previewing = 4;
var maxY = min(sp, psy1);
var sH = min(psh, (maxY - psy) / ss);
if(sH > 0)
draw_surface_part_ext_safe(preview_surface[0], 0, 0, psw, sH, psx, psy, ss, ss, 0, c_white, 1);
}
if(_ps1) {
preview_node[1].previewing = 5;
var minY = max(ssy, sp);
var sY = (minY - ssy) / ss;
var spy = max(sp, ssy);
if(sY >= 0 && sY < ssh)
draw_surface_part_ext_safe(preview_surface[1], 0, sY, ssw, ssh - sY, ssx, spy, ss, ss, 0, c_white, 1);
}
break;
}
#endregion
if(!instance_exists(o_dialog_menubox)) { // color sample
sample_color = noone;
sample_x = noone;
sample_y = noone;
if(mouse_on_preview && (mouse_press(mb_right) || key_mod_press(CTRL))) {
var _sx = sample_x;
var _sy = sample_y;
sample_x = floor((mx - canvas_x) / canvas_s);
sample_y = floor((my - canvas_y) / canvas_s);
var surf = getNodePreviewSurface();
sample_color = surface_get_pixel_ext(surf, sample_x, sample_y);
//print($"{dec_to_hex(sample_color)}: {color_get_alpha(int64(sample_color))}");
}
}
if(is_surface(preview_surfaces[0])) { // outline
if(PROJECT.previewGrid.pixel && canvas_s >= 16) {
var gw = pswd / canvas_s;
var gh = pshd / canvas_s;
var cx = canvas_x;
var cy = canvas_y;
draw_set_color(PROJECT.previewGrid.color);
draw_set_alpha(PROJECT.previewGrid.opacity * 0.5 * clamp((canvas_s - 16) / 16, 0, 1));
for( var i = 1; i < gw; i++ ) {
var _xx = cx + i * canvas_s;
draw_line(_xx, cy, _xx, cy + pshd);
}
for( var i = 1; i < gh; i++ ) {
var _yy = cy + i * canvas_s;
draw_line(cx, _yy - 1, cx + pswd, _yy - 1);
}
draw_set_alpha(1);
}
if(PROJECT.previewGrid.show) {
var _gw = PROJECT.previewGrid.size[0] * canvas_s;
var _gh = PROJECT.previewGrid.size[1] * canvas_s;
var gw = pswd / _gw;
var gh = pshd / _gh;
var cx = canvas_x;
var cy = canvas_y;
draw_set_color(PROJECT.previewGrid.color);
draw_set_alpha(PROJECT.previewGrid.opacity);
for( var i = 1; i < gw; i++ ) {
var _xx = cx + i * _gw;
draw_line(_xx, cy, _xx, cy + pshd);
}
for( var i = 1; i < gh; i++ ) {
var _yy = cy + i * _gh;
draw_line(cx, _yy, cx + pswd, _yy);
}
draw_set_alpha(1);
}
draw_set_color(COLORS.panel_preview_surface_outline);
draw_rectangle(psx, psy, psx + pswd - 1, psy + pshd - 1, true);
}
}
function draw3DPolygon(_node) {
surface_depth_disable(false);
_node.previewing = 1;
d3_scene_preview = struct_has(_node, "scene")? _node.scene : d3_scene;
d3_scene_preview.camera = d3_view_camera;
#region view
var _pos, targ, _blend = 1;
targ = d3_camTarget;
_pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist);
if(d3_active_transition == 1) {
var _up = new __vec3(0, 0, -1);
d3_view_camera.position._lerp_float(_pos, 5, 0.1);
d3_view_camera.focus._lerp_float( targ, 5, 0.1);
d3_view_camera.up._lerp_float( _up, 5, 0.1);
if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ))
d3_active_transition = 0;
} else if(d3_active_transition == -1) {
var _pos = new __vec3(0, 0, 8);
var targ = new __vec3(0, 0, 0);
var _up = new __vec3(0, 1, 0);
d3_view_camera.position._lerp_float(_pos, 5, 0.1);
d3_view_camera.focus._lerp_float( targ, 5, 0.1);
d3_view_camera.up._lerp_float( _up, 5, 0.1);
_blend = d3_view_camera.position.distance(_pos) / 2;
_blend = clamp(_blend, 0, 1);
if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ))
d3_active_transition = 0;
} else {
d3_view_camera.position.set(_pos);
d3_view_camera.focus.set(targ);
}
d3_view_camera.setViewSize(w, h);
d3_view_camera.setMatrix();
#endregion
#region background
surface_free_safe(d3_surface_bg);
if(d3_scene_preview != d3_scene)
d3_surface_bg = d3_scene_preview.renderBackground(w, h);
#endregion
#region shadow
if(d3_scene_preview == d3_scene) {
d3_scene_light0.shadow_map_scale = d3_view_camera.focus_dist * 2;
var _prev_obj = _node.getPreviewObject();
if(_prev_obj != noone) {
d3_scene_light0.submitShadow(d3_scene_preview, _prev_obj);
_prev_obj.submitShadow(d3_scene_preview, _prev_obj);
}
}
#endregion
d3_surface = surface_verify(d3_surface, w, h);
d3_surface_normal = surface_verify(d3_surface_normal, w, h);
d3_surface_depth = surface_verify(d3_surface_depth, w, h);
d3_surface_outline = surface_verify(d3_surface_outline, w, h);
#region defer
var _prev_obj = _node.getPreviewObject();
if(_prev_obj) d3_deferData = d3_scene_preview.deferPass(_prev_obj, w, h, d3_deferData);
#endregion
#region grid
surface_set_target_ext(0, d3_surface);
surface_set_target_ext(1, d3_surface_normal);
surface_set_target_ext(2, d3_surface_depth);
draw_clear_alpha(bg_color, 0);
d3_view_camera.applyCamera();
gpu_set_ztestenable(true);
gpu_set_zwriteenable(false);
if(OS != os_macosx) {
gpu_set_cullmode(cull_noculling);
shader_set(sh_d3d_grid_view);
var _dist = round(d3_view_camera.focus.distance(d3_view_camera.position));
var _tx = round(d3_view_camera.focus.x);
var _ty = round(d3_view_camera.focus.y);
var _scale = _dist * 2;
while(_scale > 32) _scale /= 2;
shader_set_f("axisBlend", _blend);
shader_set_f("scale", _scale);
shader_set_f("shift", _tx / _dist / 2, _ty / _dist / 2);
draw_sprite_stretched(s_fx_pixel, 0, _tx - _dist, _ty - _dist, _dist * 2, _dist * 2);
shader_reset();
}
gpu_set_zwriteenable(true);
#endregion
#region draw
d3_scene_preview.reset();
gpu_set_cullmode(cull_counterclockwise);
var _prev_obj = _node.getPreviewObjects();
if(d3_scene_preview == d3_scene) {
if(d3_scene_light_enabled) {
d3_scene_preview.addLightDirectional(d3_scene_light0);
d3_scene_preview.addLightDirectional(d3_scene_light1);
}
}
for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) {
var _prev = _prev_obj[i];
if(_prev == noone) continue;
_prev.submitShader(d3_scene_preview);
}
d3_scene_preview.apply(d3_deferData);
for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) {
var _prev = _prev_obj[i];
if(_prev == noone) continue;
_prev.submitUI(d3_scene_preview);
}
gpu_set_cullmode(cull_noculling);
surface_reset_target();
draw_clear(bg_color);
switch(d3_preview_channel) {
case 0 :
if(d3_scene_preview.draw_background)
draw_surface_safe(d3_surface_bg);
draw_surface_safe(d3_surface);
if(is_struct(d3_deferData)) {
BLEND_MULTIPLY
draw_surface_safe(d3_deferData.ssao);
BLEND_NORMAL
}
break;
case 1 : draw_surface_safe(d3_surface_normal); break;
case 2 : draw_surface_safe(d3_surface_depth); break;
}
#endregion
#region outline
var inspect_node = PANEL_INSPECTOR.getInspecting();
if(inspect_node && inspect_node.is_3D == NODE_3D.polygon) {
var _inspect_obj = inspect_node.getPreviewObjectOutline();
surface_set_target(d3_surface_outline);
draw_clear(c_black);
d3_scene_preview.camera.applyCamera();
gpu_set_ztestenable(false);
for( var i = 0, n = array_length(_inspect_obj); i < n; i++ ) {
if(_inspect_obj[i] == noone) continue;
_inspect_obj[i].submitSel(d3_scene_preview);
}
surface_reset_target();
shader_set(sh_d3d_outline);
shader_set_dim("dimension", d3_surface_outline);
shader_set_color("outlineColor", COLORS._main_accent);
draw_surface_safe(d3_surface_outline);
shader_reset();
}
#endregion
d3_scene_preview.camera.resetCamera();
surface_depth_disable(true);
}
function draw3DSdf(_node) {
_node.previewing = 1;
var _env = _node.environ;
var _obj = _node.object;
d3_scene_preview = d3_scene;
d3_scene_preview.camera = d3_view_camera;
#region view
d3_view_camera.fov = max(1, _env.fov * 1.23);
var _pos, targ, _blend = 1;
targ = d3_camTarget;
_pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist);
if(d3_active_transition == 1) {
var _up = new __vec3(0, 0, -1);
d3_view_camera.position._lerp_float(_pos, 5, 0.1);
d3_view_camera.focus._lerp_float( targ, 5, 0.1);
d3_view_camera.up._lerp_float( _up, 5, 0.1);
if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ))
d3_active_transition = 0;
} else if(d3_active_transition == -1) {
var _pos = new __vec3(0, 0, 8);
var targ = new __vec3(0, 0, 0);
var _up = new __vec3(0, 1, 0);
d3_view_camera.position._lerp_float(_pos, 5, 0.1);
d3_view_camera.focus._lerp_float( targ, 5, 0.1);
d3_view_camera.up._lerp_float( _up, 5, 0.1);
_blend = d3_view_camera.position.distance(_pos) / 2;
_blend = clamp(_blend, 0, 1);
if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ))
d3_active_transition = 0;
} else {
d3_view_camera.position.set(_pos);
d3_view_camera.focus.set(targ);
}
d3_view_camera.setViewSize(w, h);
d3_view_camera.setMatrix();
#endregion
draw_clear(bg_color);
gpu_set_texfilter(true);
shader_set(sh_rm_primitive);
var zm = 4 / d3_view_camera.focus_dist;
shader_set_f("camRotation", [ d3_view_camera.focus_angle_y, -d3_view_camera.focus_angle_x, 0 ]);
shader_set_f("camScale", zm);
shader_set_f("camRatio", w / h);
shader_set_i("shapeAmount", 0);
_env.apply();
if(_obj) _obj.apply();
shader_set_i("drawBg", d3_drawBG);
shader_set_f("depthInt", 0);
var _scale = zm / 2;
var _step = 1;
while(_scale > 32) {
_scale /= 2;
_step /= 2;
}
shader_set_i("drawGrid", true);
shader_set_f("gridStep", _step);
shader_set_f("gridScale", zm / 2);
shader_set_f("axisBlend", 1);
shader_set_f("viewRange", [ d3_view_camera.view_near, d3_view_camera.view_far ]);
draw_sprite_stretched(s_fx_pixel, 0, 0, 0, w, h);
shader_reset();
gpu_set_texfilter(false);
}
function draw3D() {
var _node = getNodePreview();
if(_node == noone) return;
switch(d3_active) {
case NODE_3D.polygon : draw3DPolygon(_node); break;
case NODE_3D.sdf : draw3DSdf(_node); break;
}
}
function drawPreviewOverlay() {
right_menu_y = toolbar_height - ui(4);
if(show_view_control == 2) {
if(d3_active) right_menu_y += ui(72);
else right_menu_y += ui(40);
}
toolbar_draw = false;
var _node = getNodePreview();
#region status texts (top right)
draw_set_text(f_p2, fa_right, fa_top, COLORS._main_text);
var _lh = line_get_height();
if(right_menu_x == 0) right_menu_x = w - ui(8);
if(show_info) {
if(PANEL_PREVIEW == self) {
draw_set_color(COLORS._main_text_accent);
draw_text(right_menu_x, right_menu_y, __txt("Active"));
right_menu_y += _lh;
}
var txt = $"{__txt("fps")} {fps}";
if(PREFERENCES.panel_preview_show_real_fps)
txt += $" / {FPS_REAL}";
draw_set_color(fps >= PROJECT.animator.framerate? COLORS._main_text_sub : COLORS._main_value_negative);
draw_text(right_menu_x, right_menu_y, txt);
right_menu_y += _lh;
draw_set_color(COLORS._main_text_sub);
draw_text(right_menu_x, right_menu_y, $"{__txt("Frame")} {CURRENT_FRAME + 1}/{TOTAL_FRAMES}");
if(d3_active == NODE_3D.none) {
right_menu_y += _lh;
draw_text(right_menu_x, right_menu_y, $"x{canvas_s}");
if(pHOVER) {
right_menu_y += _lh;
var mpx = floor((mx - canvas_x) / canvas_s);
var mpy = floor((my - canvas_y) / canvas_s);
draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]");
if(mouse_pos_string != "") {
right_menu_y += _lh;
draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}");
}
}
if(_node != noone) {
right_menu_y += _lh;
var txt = $"{canvas_w} x {canvas_h}px";
if(canvas_a) txt = $"{canvas_a} x {txt}";
draw_text(right_menu_x, right_menu_y, txt);
right_menu_x = w - ui(8);
right_menu_y += _lh;
}
}
mouse_pos_string = "";
}
right_menu_x = w - ui(8);
#endregion
var pseq = getNodePreviewSequence();
if(pseq == noone) return;
if(!array_equals(pseq, _preview_sequence)) {
_preview_sequence = pseq;
preview_x = 0;
preview_x_to = 0;
}
var prev_size = ui(48);
preview_x = lerp_float(preview_x, preview_x_to, 4);
if(pHOVER && my > h - toolbar_height - prev_size - ui(16) && my > toolbar_height) {
canvas_hover = false;
if(mouse_wheel_down() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to - prev_size * SCROLL_SPEED, - preview_x_max, 0);
if(mouse_wheel_up() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to + prev_size * SCROLL_SPEED, - preview_x_max, 0);
}
#region surface array
preview_x_max = 0;
if(array_length(pseq) > 1) {
var _xx = tool_side_draw_l * ui(40);
var xx = _xx + preview_x + ui(8);
var yy = h - toolbar_height - prev_size - ui(8);
if(my > yy - 8) mouse_on_preview = 0;
var hoverable = pHOVER && point_in_rectangle(mx, my, _xx, ui(32), w, h - toolbar_height);
for(var i = 0; i < array_length(pseq); i++) {
var prev = pseq[i];
if(is_instanceof(prev, __d3dMaterial))
prev = prev.surface;
if(!is_surface(prev)) continue;
var prev_w = surface_get_width_safe(prev);
var prev_h = surface_get_height_safe(prev);
var ss = prev_size / max(prev_w, prev_h);
var prev_sw = prev_w * ss;
draw_set_color(COLORS.panel_preview_surface_outline);
draw_rectangle(xx, yy, xx + prev_w * ss, yy + prev_h * ss, true);
if(hoverable && point_in_rectangle(mx, my, xx, yy, xx + prev_sw, yy + prev_h * ss)) {
if(mouse_press(mb_left, pFOCUS)) {
_node.preview_index = i;
_node.onValueUpdate(0);
if(resetViewOnDoubleClick)
do_fullView = true;
}
draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 1);
} else {
draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 0.5);
}
if(i == _node.preview_index) {
draw_set_color(COLORS._main_accent);
draw_rectangle(xx, yy, xx + prev_sw, yy + prev_h * ss, true);
}
xx += prev_sw + ui(8);
preview_x_max += prev_sw + ui(8);
}
}
#endregion
preview_x_max = max(preview_x_max - ui(100), 0);
}
function drawViewController() {
if(!show_view_control) return;
var _side = show_view_control == 1? 1 : -1;
var _view_x = show_view_control == 1?
tool_side_draw_l * toolbar_width + ui(8) :
w - tool_side_draw_r * toolbar_width - ui(8);
var _view_y = topbar_height + ui(8);
var _hab = pHOVER && tool_hovering == noone && !view_pan_tool && !view_zoom_tool;
view_hovering = false;
if(d3_active) {
var d3_view_wr = ui(32);
var _d3x = _view_x + d3_view_wr * _side;
var _d3y = _view_y + d3_view_wr;
var _hv = false;
if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wr)) {
_hv = true;
view_hovering = true;
if(mouse_press(mb_left, pFOCUS)) {
canvas_drag_key = mb_left;
d3_camPanning = true;
d3_camPan_mx = mx;
d3_camPan_my = my;
view_pan_tool = true;
}
}
if(view_pan_tool)
_hv = true;
draw_circle_ui(_d3x, _d3y, d3_view_wr, _hv? 0 : 0.02, COLORS._main_icon, 0.3);
var _qview = new BBMOD_Quaternion().FromEuler(d3_view_camera.focus_angle_y, -d3_view_camera.focus_angle_x, 0);
var _as = [
new BBMOD_Vec3(-1, 0, 0),
new BBMOD_Vec3(0, 0, 1),
new BBMOD_Vec3(0, -1, 0),
];
for(var i = 0; i < 3; i++) {
_as[i] = _qview.Rotate(_as[i]);
draw_set_color(COLORS.axis[i]);
draw_line_round(_d3x, _d3y, _d3x + _as[i].X * (d3_view_wr * 0.75), _d3y + _as[i].Y * (d3_view_wr * 0.75), 3);
}
var d3_view_wz = ui(16);
var _d3x = _view_x + (d3_view_wr * 2 + ui(20)) * _side;
var _d3y = _view_y + d3_view_wz;
var _hv = false;
if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) {
_hv = true;
view_hovering = true;
if(mouse_press(mb_left, pFOCUS)) {
canvas_drag_key = mb_left;
canvas_zooming = true;
canvas_zoom_m = my;
view_zoom_tool = true;
}
}
if(view_zoom_tool)
_hv = true;
draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3);
draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1);
} else {
var d3_view_wz = ui(16);
var _d3x = _view_x + d3_view_wz * _side;
var _d3y = _view_y + d3_view_wz;
var _hv = false;
if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) {
_hv = true;
view_hovering = true;
if(mouse_press(mb_left, pFOCUS)) {
canvas_drag_key = mb_left;
canvas_dragging = true;
canvas_drag_mx = mx;
canvas_drag_my = my;
canvas_drag_sx = canvas_x;
canvas_drag_sy = canvas_y;
view_pan_tool = true;
}
}
if(view_pan_tool)
_hv = true;
draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3);
draw_sprite_ui(THEME.view_pan, 0, _d3x, _d3y, 1, 1, 0, view_pan_tool? COLORS._main_accent : COLORS._main_icon, 1);
_d3x += (d3_view_wz + ui(4) + d3_view_wz) * _side;
_d3y = _view_y + d3_view_wz;
_hv = false;
if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) {
_hv = true;
view_hovering = true;
if(mouse_press(mb_left, pFOCUS)) {
canvas_drag_key = mb_left;
canvas_zooming = true;
canvas_zoom_mx = w / 2;
canvas_zoom_my = h / 2;
canvas_zoom_m = my;
canvas_zoom_s = canvas_s;
view_zoom_tool = true;
}
}
if(view_zoom_tool)
_hv = true;
draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3);
draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1);
}
}
function drawNodeTools(active, _node) {
var _mx = mx;
var _my = my;
var overHover = pHOVER && mouse_on_preview == 1;
var tool_size = ui(32);
var cx = canvas_x + _node.preview_x * canvas_s;
var cy = canvas_y + _node.preview_y * canvas_s;
var _snx = 0, _sny = 0;
tool_side_draw_l = _node.tools != -1;
tool_side_draw_r = _node.rightTools != -1;
if(_node.tools != -1 && point_in_rectangle(_mx, _my, 0, 0, toolbar_width, h)) {
overHover = false;
mouse_on_preview = 0;
}
overHover &= !view_hovering;
overHover &= tool_hovering == noone && !overlay_hovering;
overHover &= !canvas_dragging && !canvas_zooming;
overHover &= point_in_rectangle(mx, my, (_node.tools != -1) * toolbar_width, toolbar_height, w, h - toolbar_height);
var overActive = active && overHover;
var params = { w, h, toolbar_height };
var mouse_free = false;
if(_node.is_3D == NODE_3D.none) {
if(key_mod_press(CTRL)) {
_snx = PROJECT.previewGrid.show? PROJECT.previewGrid.size[0] : 1;
_sny = PROJECT.previewGrid.show? PROJECT.previewGrid.size[1] : 1;
} else if(PROJECT.previewGrid.snap) {
_snx = PROJECT.previewGrid.size[0];
_sny = PROJECT.previewGrid.size[1];
}
mouse_free = _node.drawOverlay(overHover, overActive, cx, cy, canvas_s, _mx, _my, _snx, _sny, params);
} else {
if(key_mod_press(CTRL) || d3_tool_snap) {
_snx = d3_tool_snap_position;
_sny = d3_tool_snap_rotation;
}
mouse_free = _node.drawOverlay3D(overActive, d3_scene, _mx, _my, _snx, _sny, params);
}
#region node overlay
overlay_hovering = false;
if(_node.drawPreviewToolOverlay(pHOVER, pFOCUS, _mx, _my, { x, y, w, h, toolbar_height,
x0: _node.tools == -1? 0 : ui(40),
x1: w,
y0: toolbar_height - ui(8),
y1: h - toolbar_height
})) {
canvas_hover = false;
overlay_hovering = true;
}
#endregion
var _tool = tool_hovering;
tool_hovering = noone;
if(_node.tools == -1) {
tool_current = noone;
return;
}
var aa = d3_active? 0.8 : 1;
draw_sprite_stretched_ext(THEME.tool_side, 1, 0, ui(32), toolbar_width, h - toolbar_height - ui(32), c_white, aa);
tool_y_max = 0;
tool_y = lerp_float(tool_y, tool_y_to, 5);
var xx = ui(1) + toolbar_width / 2;
var yy = ui(34) + tool_size / 2 + tool_y;
var pd = 2;
var thov = pHOVER && point_in_rectangle(mx, my, 0, toolbar_height, toolbar_width, h - toolbar_height);
if(thov) canvas_hover = false;
for(var i = 0; i < array_length(_node.tools); i++) { // left tools
var tool = _node.tools[i];
var _x0 = xx - tool_size / 2;
var _y0 = yy - tool_size / 2;
var _x1 = xx + tool_size / 2;
var _y1 = yy + tool_size / 2;
if(tool == -1) {
draw_set_color(COLORS._main_icon_dark);
draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2);
yy += ui(8);
tool_y_max += ui(8);
continue;
}
if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1))
tool_hovering = tool;
if(tool.subtools > 0 && _tool == tool) { // hovering subtools
var s_ww = tool_size * tool.subtools;
var s_hh = tool_size;
draw_sprite_stretched(THEME.s_box_r2_clr, 0, _x0 - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2);
var stool = tool.spr;
for( var j = 0; j < array_length(stool); j++ ) {
var _sxx = xx + j * tool_size;
var _syy = yy;
var _sx0 = _sxx - tool_size / 2;
var _sy0 = _syy - tool_size / 2;
var _sx1 = _sxx + tool_size / 2;
var _sy1 = _syy + tool_size / 2;
if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) {
TOOLTIP = tool.getDisplayName(j);
draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2);
if(mouse_press(mb_left, pFOCUS))
tool.toggle(j);
}
if(tool_current == tool && tool.selecting == j) {
draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1);
draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1);
}
draw_sprite_colored(stool[j], 0, _sxx, _syy);
}
if(point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x0 + s_ww, _y1 - 1))
tool_hovering = tool;
} else { // single tools
if(tool_hovering == tool) {
draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2);
TOOLTIP = tool.getDisplayName();
if(mouse_press(mb_left, pFOCUS))
tool.toggle();
}
if(pFOCUS && WIDGET_CURRENT == noone) {
var _key = tool.checkHotkey();
if(keyboard_check_pressed(ord(string(i + 1))) || (_key != noone && _key.isPressing()))
tool.toggleKeyboard();
}
if(tool_current == tool) {
draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1);
draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1);
}
if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy);
else draw_sprite_colored(tool.spr, 0, xx, yy);
}
yy += tool_size;
tool_y_max += tool_size;
}
var _h = _node.drawTools == noone? 0 : _node.drawTools(_mx, _my, xx, yy - tool_size / 2, tool_size, thov, pFOCUS);
yy += _h;
tool_y_max += _h;
tool_y_max = max(0, tool_y_max - h + toolbar_height * 2);
if(thov && !key_mod_press_any()) {
if(mouse_wheel_up()) tool_y_to = clamp(tool_y_to + ui(64) * SCROLL_SPEED, -tool_y_max, 0);
if(mouse_wheel_down()) tool_y_to = clamp(tool_y_to - ui(64) * SCROLL_SPEED, -tool_y_max, 0);
}
if(_node.rightTools != -1) {
right_menu_x = w - toolbar_width - ui(8);
tool_ry_max = 0;
tool_ry = lerp_float(tool_ry, tool_ry_to, 5);
var _tbx = w - toolbar_width;
var xx = _tbx + toolbar_width / 2;
var yy = ui(34) + tool_size / 2 + tool_ry;
var _sw = -toolbar_width / sprite_get_width(THEME.tool_side);
var _sh = h - toolbar_height - ui(32) / sprite_get_height(THEME.tool_side);
draw_sprite_ext(THEME.tool_side, 1, w + 1, ui(32), _sw, _sh, 0, c_white, aa);
var thov = pHOVER && point_in_rectangle(mx, my, _tbx, toolbar_height, w, h - toolbar_height);
if(thov) canvas_hover = false;
for(var i = 0; i < array_length(_node.rightTools); i++) { // right tools
var tool = _node.rightTools[i];
var _x0 = xx - tool_size / 2;
var _y0 = yy - tool_size / 2;
var _x1 = xx + tool_size / 2;
var _y1 = yy + tool_size / 2;
if(tool == -1) {
draw_set_color(COLORS._main_icon_dark);
draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2);
yy += ui(8);
tool_ry_max += ui(8);
continue;
}
if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1))
tool_hovering = tool;
if(tool.subtools > 0 && _tool == tool) { // hovering subtools
var stool = tool.spr;
var s_ww = tool_size * tool.subtools;
var s_hh = tool_size;
var tx = _x0 - s_ww + tool_size;
draw_sprite_stretched(THEME.s_box_r2_clr, 0, tx - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2);
var _am = array_length(stool);
for( var j = 0; j < _am; j++ ) {
var _sind = _am - 1 - j;
var _sxx = tx + j * tool_size + tool_size / 2;
var _syy = yy;
var _sx0 = _sxx - tool_size / 2;
var _sy0 = _syy - tool_size / 2;
var _sx1 = _sxx + tool_size / 2;
var _sy1 = _syy + tool_size / 2;
draw_sprite_colored(stool[_sind], 0, _sxx, _syy);
if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) {
TOOLTIP = tool.getDisplayName(_sind);
draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2);
if(mouse_press(mb_left, pFOCUS))
tool.toggle(_sind);
}
if(tool_current == tool && tool.selecting == _sind) {
draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1);
draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1);
}
}
if(point_in_rectangle(_mx, _my, tx, _y0 + 1, tx + s_ww, _y1 - 1))
tool_hovering = tool;
} else { // single tools
if(tool_hovering == tool) {
draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2);
TOOLTIP = tool.getDisplayName();
if(mouse_press(mb_left, pFOCUS))
tool.toggle();
}
if(pFOCUS && WIDGET_CURRENT == noone) {
var _key = tool.checkHotkey();
if(keyboard_check_pressed(ord(string(i + 1))) || (_key != noone && _key.isPressing()))
tool.toggleKeyboard();
}
if(tool_current == tool) {
draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1);
draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1);
}
if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy);
else draw_sprite_colored(tool.spr, 0, xx, yy);
}
yy += tool_size;
tool_ry_max += tool_size;
}
tool_ry_max = max(0, tool_ry_max - h + toolbar_height * 2);
if(thov && !key_mod_press_any()) {
if(mouse_wheel_up()) tool_ry_to = clamp(tool_ry_to + ui(64) * SCROLL_SPEED, -tool_ry_max, 0);
if(mouse_wheel_down()) tool_ry_to = clamp(tool_ry_to - ui(64) * SCROLL_SPEED, -tool_ry_max, 0);
}
}
}
function drawToolBar(_tool, _node) {
var ty = h - toolbar_height;
var aa = d3_active? 0.8 : 1;
draw_sprite_stretched_ext(THEME.toolbar, 1, 0, 0, w, topbar_height, c_white, aa);
draw_sprite_stretched_ext(THEME.toolbar, 0, 0, ty, w, toolbar_height, c_white, aa);
if(_tool && tool_current != noone) { // tool settings
var settings = array_merge(_tool.getToolSettings(), tool_current.settings);
tool_x = lerp_float(tool_x, tool_x_to, 5);
var tolx = tool_x + ui(8);
var toly = ui(8);
var tolw = ui(48);
var tolh = toolbar_height - ui(20);
var tol_max_w = ui(16);
for( var i = 0, n = array_length(settings); i < n; i++ ) {
var sett = settings[i];
var nme = sett[0];
var wdg = sett[1];
var key = sett[2];
var atr = sett[3];
if(nme != "") {
tolx += ui(8) + bool(i == 0) * ui(8);
tol_max_w += ui(8) + bool(i == 0) * ui(8);
}
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub);
if(nme != "") {
draw_text(tolx, toolbar_height / 2 - ui(2), nme);
tolx += string_width(nme) + ui(8);
tol_max_w += string_width(nme) + ui(8);
}
wdg.setFocusHover(pFOCUS, pHOVER);
var _tool_font = f_p3;
switch(instanceof(wdg)) {
case "textBox" :
tolw = ui(40);
if(wdg.side_button != noone) tolw += tolh + ui(8);
break;
case "buttonGroup":
case "checkBoxGroup" :
tolw = tolh * wdg.size;
break;
case "checkBox" :
tolw = tolh;
break;
case "scrollBox" :
tolw = ui(96);
_tool_font = f_p2;
break;
case "buttonClass" :
tolw = wdg.text == ""? tolh : tolw;
break;
}
var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ])
params.s = tolh;
params.font = _tool_font;
wdg.drawParam(params);
tolx += tolw + ui(8);
tol_max_w += tolw + ui(8);
}
tol_max_w = max(0, tol_max_w - w);
if(point_in_rectangle(mx, my, 0, 0, w, toolbar_height) && !key_mod_press_any()) {
if(mouse_wheel_up()) tool_x_to = clamp(tool_x_to + ui(64) * SCROLL_SPEED, -tol_max_w, 0);
if(mouse_wheel_down()) tool_x_to = clamp(tool_x_to - ui(64) * SCROLL_SPEED, -tol_max_w, 0);
}
} else { // color sampler
var cx = ui(6);
var cy = ui(6);
var cw = ui(32);
var ch = topbar_height - ui(10);
if(sample_color != noone) {
drawColor(sample_color, cx, cy, cw, ch);
var tx = cx + cw + ui(8);
var hx = color_get_hex(sample_color);
draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text);
draw_text(tx, cy + ch / 2, hx);
tx += string_width(hx) + ui(8);
draw_set_color(COLORS._main_text_sub);
draw_text(tx, cy + ch / 2, $"({color_get_alpha(sample_color)})");
}
}
var tbx = toolbar_height / 2;
var tby = ty + toolbar_height / 2;
var _toolbars = toolbars;
switch(d3_active) {
case NODE_3D.none : _toolbars = toolbars; break;
case NODE_3D.polygon : _toolbars = toolbars_3d; break;
case NODE_3D.sdf : _toolbars = toolbars_3d_sdf; break;
}
for( var i = 0, n = array_length(_toolbars); i < n; i++ ) {
var tb = _toolbars[i];
var tbSpr = tb[0];
var tbInd = tb[1]();
var tbTooltip = is_method(tb[2])? tb[2]() : tb[2];
var tbActive = tb[3];
var tbRight = array_safe_get(tb, 4, 0);
var tbData = { x: x + tbx - ui(14), y: y + tby - ui(14) };
var tooltip = instance_exists(o_dialog_menubox)? "" : tbTooltip;
if(is_instanceof(tbTooltip, tooltipSelector))
tbTooltip.index = tbInd;
var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tooltip, tbSpr, tbInd);
if(b == 2) tbActive(tbData);
if(tbRight != 0 && b == 3) tbRight(tbData);
tbx += ui(32);
}
tbx = w - toolbar_height / 2;
for( var i = 0, n = array_length(actions); i < n; i++ ) {
var tb = actions[i];
var tbSpr = tb[0];
var tbTooltip = tb[1];
var tbIndex = tb[3]();
var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbIndex);
if(b == 2) tb[2]( { x: x + tbx - ui(14), y: y + tby - ui(14) } );
tbx -= ui(32);
}
draw_set_color(COLORS.panel_toolbar_separator);
draw_line_width(tbx + ui(12), tby - toolbar_height / 2 + ui(8), tbx + ui(12), tby + toolbar_height / 2 - ui(8), 2);
var _nodeRaw = __getNodePreview();
if(_nodeRaw) tbx -= drawNodeChannel(_nodeRaw, tbx, tby);
}
function drawSplitView() {
if(splitView == 0) return;
draw_set_color(COLORS.panel_preview_split_line);
if(splitViewDragging) {
if(splitView == 1) {
var cx = splitViewStart + (mx - splitViewMouse);
splitPosition = clamp(cx / w, .1, .9);
} else if(splitView == 2) {
var cy = splitViewStart + (my - splitViewMouse);
splitPosition = clamp(cy / h, .1, .9);
}
if(mouse_release(mb_left))
splitViewDragging = false;
}
if(splitView == 1) {
var sx = w * splitPosition;
if(mouse_on_preview && point_in_rectangle(mx, my, sx - ui(4), 0, sx + ui(4), h)) {
draw_line_width(sx, 0, sx, h, 2);
if(mouse_press(mb_left, pFOCUS)) {
splitViewDragging = true;
splitViewStart = sx;
splitViewMouse = mx;
}
} else
draw_line_width(sx, 0, sx, h, 1);
draw_sprite_ui_uniform(THEME.icon_active_split, 0, splitSelection? sx + ui(16) : sx - ui(16), toolbar_height + ui(16),, COLORS._main_accent);
if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) {
if(point_in_rectangle(mx, my, 0, 0, sx, h))
splitSelection = 0;
else if(point_in_rectangle(mx, my, sx, 0, w, h))
splitSelection = 1;
}
} else {
var sy = h * splitPosition;
if(mouse_on_preview && point_in_rectangle(mx, my, 0, sy - ui(4), w, sy + ui(4))) {
draw_line_width(0, sy, w, sy, 2);
if(mouse_press(mb_left, pFOCUS)) {
splitViewDragging = true;
splitViewStart = sy;
splitViewMouse = my;
}
} else
draw_line_width(0, sy, w, sy, 1);
draw_sprite_ui_uniform(THEME.icon_active_split, 0, ui(16), splitSelection? sy + ui(16) : sy - ui(16),, COLORS._main_accent);
if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) {
if(point_in_rectangle(mx, my, 0, 0, w, sy))
splitSelection = 0;
else if(point_in_rectangle(mx, my, 0, sy, w, h))
splitSelection = 1;
}
}
}
function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
mouse_on_preview = pHOVER && point_in_rectangle(mx, my, 0, topbar_height, w, h - toolbar_height);
if(do_fullView) run_in(1, fullView);
do_fullView = false;
var _prev_node = getNodePreview();
d3_active = _prev_node == noone? NODE_3D.none : _prev_node.is_3D;
bg_color = lerp_color(bg_color, d3_active? COLORS.panel_3d_bg : COLORS.panel_bg_clear, 0.3);
draw_clear(bg_color);
if(canvas_bg == -1) {
if(canvas_s >= 0.1) draw_sprite_tiled_ext(s_transparent, 0, canvas_x, canvas_y, canvas_s, canvas_s, COLORS.panel_preview_transparent, 1);
} else
draw_clear(canvas_bg);
draw_set_color(COLORS._main_icon_dark);
draw_line_width(canvas_x, 0, canvas_x, h, 1);
draw_line_width(0, canvas_y, w, canvas_y, 1);
title = __txt("Preview");
getPreviewData();
if(_prev_node) {
if(d3_active) {
dragCanvas3D();
draw3D();
} else {
dragCanvas();
drawNodePreview();
}
} else dragCanvas();
drawPreviewOverlay();
var inspect_node = PANEL_INSPECTOR.getInspecting();
var tool = noone;
drawViewController();
tool_side_draw_l = false;
tool_side_draw_r = false;
if(PANEL_PREVIEW == self) {
if(inspect_node) {
tool = inspect_node.getTool();
if(tool) drawNodeTools(pFOCUS, tool);
} else
tool_current = noone;
}
if(d3_active == NODE_3D.none) drawSplitView();
drawToolBar(tool, _prev_node);
if(mouse_on_preview && mouse_press(mb_right, pFOCUS) && !key_mod_press(SHIFT)) {
menuCall("preview_context_menu", [
MENU_ITEMS.preview_new_preview_window,
-1,
MENU_ITEMS.preview_save_current_frame,
MENU_ITEMS.preview_save_all_current_frames,
-1,
MENU_ITEMS.preview_copy_current_frame,
MENU_ITEMS.preview_copy_color,
MENU_ITEMS.preview_copy_color_hex,
-1,
MENU_ITEMS.preview_group_preview_bg,
], 0, 0, fa_left, getNodePreview());
}
////////////////////////////////// File drop //////////////////////////////////
if(pHOVER) {
var _node = getNodePreview();
if(_node && _node.dropPath != noone) {
if(DRAGGING && DRAGGING.type == "Asset") {
draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1);
if(mouse_release(mb_left))
_node.dropPath(DRAGGING.data.path);
}
if(FILE_IS_DROPPING)
draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1);
if(FILE_DROPPED && !array_empty(FILE_DROPPING))
_node.dropPath(FILE_DROPPING[0]);
}
}
} #endregion
////=========== ACTION ===========
function copyCurrentFrame() {
var prevS = getNodePreviewSurface();
if(!is_surface(prevS)) return;
var buff = buffer_create(surface_get_width_safe(prevS) * surface_get_height_safe(prevS) * 4, buffer_fixed, 1);
var s = surface_create(surface_get_width_safe(prevS), surface_get_height_safe(prevS));
surface_set_target(s);
shader_set(sh_BGR);
draw_surface_safe(prevS);
shader_reset();
surface_reset_target();
buffer_get_surface(buff, s, 0);
surface_free(s);
clipboard_set_bitmap(buffer_get_address(buff), surface_get_width_safe(prevS), surface_get_height_safe(prevS));
}
function saveCurrentFrameToFocus() {
var prevS = getNodePreviewSurface();
if(!is_surface(prevS)) return;
if(!is_struct(PANEL_FILE)) return;
var _fileO = PANEL_FILE.file_focus;
if(_fileO == noone) return;
var path = _fileO.path;
if(path == "") return;
if(filename_ext(path) != ".png") path += ".png";
surface_save_safe(prevS, path);
_fileO.refreshThumbnail();
}
function saveCurrentFrame() {
var prevS = getNodePreviewSurface();
var _node = getNodePreview();
if(_node == noone) return;
if(!is_surface(prevS)) return;
var path = get_save_filename_pxc("image|*.png;*.jpg", _node.display_name == ""? "export" : _node.display_name, "Save surface as");
key_release();
if(path == "") return;
if(filename_ext(path) != ".png") path += ".png";
surface_save_safe(prevS, path);
}
function saveAllCurrentFrames() {
var _node = getNodePreview();
if(_node == noone) return;
var path = get_save_filename_pxc("image|*.png;*.jpg", _node.display_name == ""? "export" : _node.display_name, "Save surfaces as");
key_release();
if(path == "") return;
var ext = ".png";
var name = string_replace_all(path, ext, "");
var ind = 0;
var pseq = getNodePreviewSequence();
for(var i = 0; i < array_length(pseq); i++) {
var prev = pseq[i];
if(!is_surface(prev)) continue;
var _name = name + string(ind) + ext;
surface_save_safe(prev, _name);
ind++;
}
}
//// =========== Serialize ===========
static serialize = function() {
return {
name: instanceof(self),
preview_node : [ node_get_id(preview_node[0]), node_get_id(preview_node[1]) ],
canvas_x,
canvas_y,
canvas_s,
locked,
};
}
static deserialize = function(data) {
if(struct_has(data, "preview_node"))
preview_node = [ node_from_id(data.preview_node[0]), node_from_id(data.preview_node[1]) ];
canvas_x = struct_try_get(data, "canvas_x", canvas_x);
canvas_y = struct_try_get(data, "canvas_y", canvas_y);
canvas_s = struct_try_get(data, "canvas_s", canvas_s);
locked = struct_try_get(data, "locked", locked);
run_in(1, fullView)
return self;
}
}