2024-03-11 15:10:18 +01:00
let ui_menu_show : bool = false ;
let ui_menu_category : i32 = 0 ;
let ui_menu_category_w : i32 = 0 ;
let ui_menu_category_h : i32 = 0 ;
let ui_menu_x : i32 = 0 ;
let ui_menu_y : i32 = 0 ;
let ui_menu_elements : i32 = 0 ;
let ui_menu_keep_open : bool = false ;
let ui_menu_commands : ( ui : zui_t ) => void = null ;
let ui_menu_show_first : bool = true ;
let ui_menu_hide_flag : bool = false ;
2024-04-07 09:52:45 +02:00
let _ui_menu_render_msg : string ;
2024-05-03 21:29:39 +02:00
type update_info_t = {
version : i32 ;
version_name : string ;
};
2024-03-11 15:10:18 +01:00
function ui_menu_render() {
let ui : zui_t = base_ui_menu ;
let menu_w : i32 = ui_menu_commands != null ? math_floor ( base_default_element_w * zui_SCALE ( base_ui_menu ) * 2.3 ) : math_floor ( zui_ELEMENT_W ( ui ) * 2.3 );
2024-04-10 19:39:17 +02:00
let _BUTTON_COL : i32 = ui . ops . theme . BUTTON_COL ;
ui . ops . theme . BUTTON_COL = ui . ops . theme . SEPARATOR_COL ;
let _ELEMENT_OFFSET : i32 = ui . ops . theme . ELEMENT_OFFSET ;
ui . ops . theme . ELEMENT_OFFSET = 0 ;
let _ELEMENT_H : i32 = ui . ops . theme . ELEMENT_H ;
ui . ops . theme . ELEMENT_H = config_raw . touch_ui ? ( 28 + 2 ) : 28 ;
2024-03-11 15:10:18 +01:00
zui_begin_region ( ui , ui_menu_x , ui_menu_y , menu_w );
if ( ui_menu_commands != null ) {
2024-04-10 19:39:17 +02:00
g2_set_color ( ui . ops . theme . ACCENT_SELECT_COL );
2024-03-11 15:10:18 +01:00
zui_draw_rect ( true , ui . _x + - 1 , ui . _y + - 1 , ui . _w + 2 , zui_ELEMENT_H ( ui ) * ui_menu_elements + 2 );
2024-04-10 19:39:17 +02:00
g2_set_color ( ui . ops . theme . SEPARATOR_COL );
2024-03-11 15:10:18 +01:00
zui_draw_rect ( true , ui . _x + 0 , ui . _y + 0 , ui . _w , zui_ELEMENT_H ( ui ) * ui_menu_elements );
g2_set_color ( 0xffffffff );
ui_menu_commands ( ui );
}
else {
ui_menu_start ( ui );
if ( ui_menu_category == menu_category_t . FILE ) {
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "New .." ), map_get ( config_keymap , "file_new" ))) {
2024-03-20 16:13:54 +01:00
project_new_box ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Open..." ), map_get ( config_keymap , "file_open" ))) {
2024-03-20 16:13:54 +01:00
project_open ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Open Recent..." ), map_get ( config_keymap , "file_open_recent" ))) {
2024-03-20 16:13:54 +01:00
box_projects_show ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Save" ), map_get ( config_keymap , "file_save" ))) {
2024-03-20 16:13:54 +01:00
project_save ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Save As..." ), map_get ( config_keymap , "file_save_as" ))) {
2024-03-20 16:13:54 +01:00
project_save_as ();
}
2024-03-11 15:10:18 +01:00
ui_menu_separator ( ui );
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Import Texture..." ), map_get ( config_keymap , "file_import_assets" ))) {
2024-05-03 21:29:39 +02:00
project_import_asset ( string_array_join ( path_texture_formats , "," ), false );
2024-03-20 16:13:54 +01:00
}
2024-03-11 15:10:18 +01:00
if ( ui_menu_button ( ui , tr ( "Import Envmap..." ))) {
ui_files_show ( "hdr" , false , false , function ( path : string ) {
2024-03-20 16:13:54 +01:00
if ( ! ends_with ( path , ".hdr" )) {
2024-03-11 15:10:18 +01:00
console_error ( tr ( "Error: .hdr file expected" ));
return ;
}
2024-03-13 23:50:11 +01:00
import_asset_run ( path );
2024-03-11 15:10:18 +01:00
});
}
///if (is_paint || is_sculpt)
2024-03-20 16:13:54 +01:00
if ( ui_menu_button ( ui , tr ( "Import Font..." ))) {
project_import_asset ( "ttf,ttc,otf" );
}
if ( ui_menu_button ( ui , tr ( "Import Material..." ))) {
project_import_material ();
}
if ( ui_menu_button ( ui , tr ( "Import Brush..." ))) {
project_import_brush ();
}
2024-03-11 15:10:18 +01:00
///end
///if (is_paint || is_lab)
2024-03-20 16:13:54 +01:00
if ( ui_menu_button ( ui , tr ( "Import Swatches..." ))) {
project_import_swatches ();
}
2024-03-11 15:10:18 +01:00
///end
2024-03-20 16:13:54 +01:00
if ( ui_menu_button ( ui , tr ( "Import Mesh..." ))) {
project_import_mesh ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Reimport Mesh" ), map_get ( config_keymap , "file_reimport_mesh" ))) {
2024-03-20 16:13:54 +01:00
project_reimport_mesh ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Reimport Textures" ), map_get ( config_keymap , "file_reimport_textures" ))) {
2024-03-20 16:13:54 +01:00
project_reimport_textures ();
}
2024-03-11 15:10:18 +01:00
ui_menu_separator ( ui );
///if (is_paint || is_lab)
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Export Textures..." ), map_get ( config_keymap , "file_export_textures_as" ))) {
2024-03-11 15:10:18 +01:00
///if is_paint
context_raw . layers_export = export_mode_t . VISIBLE ;
///end
2024-03-13 23:50:11 +01:00
box_export_show_textures ();
2024-03-11 15:10:18 +01:00
}
2024-03-20 16:13:54 +01:00
if ( ui_menu_button ( ui , tr ( "Export Swatches..." ))) {
project_export_swatches ();
}
2024-03-11 15:10:18 +01:00
///end
if ( ui_menu_button ( ui , tr ( "Export Mesh..." ))) {
context_raw . export_mesh_index = 0 ; // All
2024-03-13 23:50:11 +01:00
box_export_show_mesh ();
2024-03-11 15:10:18 +01:00
}
///if is_paint
2024-03-20 16:13:54 +01:00
if ( ui_menu_button ( ui , tr ( "Bake Material..." ))) {
box_export_show_bake_material ();
}
2024-03-11 15:10:18 +01:00
///end
ui_menu_separator ( ui );
2024-03-20 16:13:54 +01:00
if ( ui_menu_button ( ui , tr ( "Exit" ))) {
sys_stop ();
}
2024-03-11 15:10:18 +01:00
}
else if ( ui_menu_category == menu_category_t . EDIT ) {
let step_undo : string = "" ;
let step_redo : string = "" ;
if ( history_undos > 0 ) {
step_undo = history_steps [ history_steps . length - 1 - history_redos ]. name ;
}
if ( history_redos > 0 ) {
step_redo = history_steps [ history_steps . length - history_redos ]. name ;
}
2024-03-21 21:06:41 +01:00
2024-03-11 15:10:18 +01:00
ui . enabled = history_undos > 0 ;
2024-03-21 21:06:41 +01:00
let vars_undo : map_t < string , string > = map_create ();
map_set ( vars_undo , "step" , step_undo );
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Undo {step}" , vars_undo ), map_get ( config_keymap , "edit_undo" ))) {
2024-03-20 16:13:54 +01:00
history_undo ();
}
2024-03-21 21:06:41 +01:00
2024-03-11 15:10:18 +01:00
ui . enabled = history_redos > 0 ;
2024-03-21 21:06:41 +01:00
let vars_redo : map_t < string , string > = map_create ();
map_set ( vars_redo , "step" , step_redo );
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Redo {step}" , vars_redo ), map_get ( config_keymap , "edit_redo" ))) {
2024-03-20 16:13:54 +01:00
history_redo ();
}
2024-03-11 15:10:18 +01:00
ui . enabled = true ;
ui_menu_separator ( ui );
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Preferences..." ), map_get ( config_keymap , "edit_prefs" ))) {
2024-03-20 16:13:54 +01:00
box_preferences_show ();
}
2024-03-11 15:10:18 +01:00
}
else if ( ui_menu_category == menu_category_t . VIEWPORT ) {
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Distract Free" ), map_get ( config_keymap , "view_distract_free" ))) {
2024-03-11 15:10:18 +01:00
ui_base_toggle_distract_free ();
ui_base_ui . is_hovered = false ;
}
///if !(krom_android || krom_ios)
if ( ui_menu_button ( ui , tr ( "Toggle Fullscreen" ), "alt+enter" )) {
base_toggle_fullscreen ();
}
///end
ui . changed = false ;
ui_menu_fill ( ui );
let p : world_data_t = scene_world ;
2024-03-24 10:26:56 +01:00
let env_handle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
env_handle . value = p . strength ;
ui_menu_align ( ui );
p . strength = zui_slider ( env_handle , tr ( "Environment" ), 0.0 , 8.0 , true );
2024-03-20 16:13:54 +01:00
if ( env_handle . changed ) {
context_raw . ddirty = 2 ;
}
2024-03-11 15:10:18 +01:00
ui_menu_fill ( ui );
2024-03-24 10:26:56 +01:00
let enva_handle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
enva_handle . value = context_raw . envmap_angle / math_pi () * 180.0 ;
if ( enva_handle . value < 0 ) {
enva_handle . value += ( math_floor ( - enva_handle . value / 360 ) + 1 ) * 360 ;
}
else if ( enva_handle . value > 360 ) {
enva_handle . value -= math_floor ( enva_handle . value / 360 ) * 360 ;
}
ui_menu_align ( ui );
context_raw . envmap_angle = zui_slider ( enva_handle , tr ( "Environment Angle" ), 0.0 , 360.0 , true , 1 ) / 180.0 * math_pi ();
2024-03-20 16:13:54 +01:00
if ( ui . is_hovered ) {
2024-03-21 21:06:41 +01:00
let vars : map_t < string , string > = map_create ();
2024-04-08 17:40:32 +02:00
map_set ( vars , "shortcut" , map_get ( config_keymap , "rotate_envmap" ));
2024-03-21 21:06:41 +01:00
zui_tooltip ( tr ( "{shortcut} and move mouse" , vars ));
2024-03-20 16:13:54 +01:00
}
if ( enva_handle . changed ) {
context_raw . ddirty = 2 ;
}
2024-03-11 15:10:18 +01:00
if ( scene_lights . length > 0 ) {
let light : light_object_t = scene_lights [ 0 ];
ui_menu_fill ( ui );
2024-03-24 10:26:56 +01:00
let lhandle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
let scale : f32 = 1333 ;
lhandle . value = light . data . strength / scale ;
lhandle . value = math_floor ( lhandle . value * 100 ) / 100 ;
ui_menu_align ( ui );
light . data . strength = zui_slider ( lhandle , tr ( "Light" ), 0.0 , 4.0 , true ) * scale ;
2024-03-20 16:13:54 +01:00
if ( lhandle . changed ) {
context_raw . ddirty = 2 ;
}
2024-03-11 15:10:18 +01:00
ui_menu_fill ( ui );
light = scene_lights [ 0 ];
2024-03-24 10:26:56 +01:00
let lahandle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
lahandle . value = context_raw . light_angle / math_pi () * 180 ;
ui_menu_align ( ui );
let new_angle : f32 = zui_slider ( lahandle , tr ( "Light Angle" ), 0.0 , 360.0 , true , 1 ) / 180 * math_pi ();
2024-03-20 16:13:54 +01:00
if ( ui . is_hovered ) {
2024-03-21 21:06:41 +01:00
let vars : map_t < string , string > = map_create ();
2024-04-08 17:40:32 +02:00
map_set ( vars , "shortcut" , map_get ( config_keymap , "rotate_light" ));
2024-03-21 21:06:41 +01:00
zui_tooltip ( tr ( "{shortcut} and move mouse" , vars ));
2024-03-20 16:13:54 +01:00
}
2024-03-11 15:10:18 +01:00
let ldiff : f32 = new_angle - context_raw . light_angle ;
if ( math_abs ( ldiff ) > 0.005 ) {
2024-03-20 16:13:54 +01:00
if ( new_angle < 0 ) {
new_angle += ( math_floor ( - new_angle / ( 2 * math_pi ())) + 1 ) * 2 * math_pi ();
}
else if ( new_angle > 2 * math_pi ()) {
new_angle -= math_floor ( new_angle / ( 2 * math_pi ())) * 2 * math_pi ();
}
2024-03-11 15:10:18 +01:00
context_raw . light_angle = new_angle ;
let m : mat4_t = mat4_rot_z ( ldiff );
mat4_mult_mat ( light . base . transform . local , m );
transform_decompose ( light . base . transform );
context_raw . ddirty = 2 ;
}
ui_menu_fill ( ui );
2024-03-24 10:26:56 +01:00
let sxhandle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
sxhandle . value = light . data . size ;
ui_menu_align ( ui );
light . data . size = zui_slider ( sxhandle , tr ( "Light Size" ), 0.0 , 4.0 , true );
2024-03-20 16:13:54 +01:00
if ( sxhandle . changed ) {
context_raw . ddirty = 2 ;
}
2024-03-11 15:10:18 +01:00
}
///if (is_paint || is_sculpt)
ui_menu_fill ( ui );
2024-05-03 21:29:39 +02:00
let split_view_handle : zui_handle_t = zui_handle ( __ID__ );
2024-04-24 12:14:47 +02:00
if ( split_view_handle . init ) {
split_view_handle . selected = context_raw . split_view ;
}
2024-03-11 15:10:18 +01:00
context_raw . split_view = zui_check ( split_view_handle , " " + tr ( "Split View" ));
if ( split_view_handle . changed ) {
base_resize ();
}
///end
///if is_lab
ui_menu_fill ( ui );
2024-04-24 12:14:47 +02:00
let brush_scale_handle : zui_handle_t = zui_handle ( __ID__ );
if ( brush_scale_handle . init ) {
brush_scale_handle . value = context_raw . brush_scale ;
}
2024-03-11 15:10:18 +01:00
ui_menu_align ( ui );
context_raw . brush_scale = zui_slider ( brush_scale_handle , tr ( "UV Scale" ), 0.01 , 5.0 , true );
if ( brush_scale_handle . changed ) {
2024-03-14 15:31:22 +01:00
make_material_parse_mesh_material ();
2024-03-11 15:10:18 +01:00
///if (krom_direct3d12 || krom_vulkan || krom_metal)
2024-03-13 23:50:11 +01:00
render_path_raytrace_uv_scale = context_raw . brush_scale ;
render_path_raytrace_ready = false ;
2024-03-11 15:10:18 +01:00
///end
}
///end
ui_menu_fill ( ui );
2024-04-24 12:14:47 +02:00
let cull_handle : zui_handle_t = zui_handle ( __ID__ );
if ( cull_handle . init ) {
cull_handle . selected = context_raw . cull_backfaces ;
}
2024-03-11 15:10:18 +01:00
context_raw . cull_backfaces = zui_check ( cull_handle , " " + tr ( "Cull Backfaces" ));
if ( cull_handle . changed ) {
2024-03-14 15:31:22 +01:00
make_material_parse_mesh_material ();
2024-03-11 15:10:18 +01:00
}
ui_menu_fill ( ui );
2024-04-24 12:14:47 +02:00
let filter_handle : zui_handle_t = zui_handle ( __ID__ );
if ( filter_handle . init ) {
filter_handle . selected = context_raw . texture_filter ;
}
2024-03-11 15:10:18 +01:00
context_raw . texture_filter = zui_check ( filter_handle , " " + tr ( "Filter Textures" ));
if ( filter_handle . changed ) {
2024-03-14 15:31:22 +01:00
make_material_parse_paint_material ();
make_material_parse_mesh_material ();
2024-03-11 15:10:18 +01:00
}
///if (is_paint || is_sculpt)
ui_menu_fill ( ui );
context_raw . draw_wireframe = zui_check ( context_raw . wireframe_handle , " " + tr ( "Wireframe" ));
if ( context_raw . wireframe_handle . changed ) {
let current : image_t = _g2_current ;
g2_end ();
util_uv_cache_uv_map ();
g2_begin ( current );
2024-03-14 15:31:22 +01:00
make_material_parse_mesh_material ();
2024-03-11 15:10:18 +01:00
}
///end
///if is_paint
ui_menu_fill ( ui );
context_raw . draw_texels = zui_check ( context_raw . texels_handle , " " + tr ( "Texels" ));
if ( context_raw . texels_handle . changed ) {
2024-03-14 15:31:22 +01:00
make_material_parse_mesh_material ();
2024-03-11 15:10:18 +01:00
}
///end
ui_menu_fill ( ui );
2024-04-24 12:14:47 +02:00
let compass_handle : zui_handle_t = zui_handle ( __ID__ );
if ( compass_handle . init ) {
compass_handle . selected = context_raw . show_compass ;
}
2024-03-11 15:10:18 +01:00
context_raw . show_compass = zui_check ( compass_handle , " " + tr ( "Compass" ));
2024-03-20 16:13:54 +01:00
if ( compass_handle . changed ) {
context_raw . ddirty = 2 ;
}
2024-03-11 15:10:18 +01:00
ui_menu_fill ( ui );
context_raw . show_envmap = zui_check ( context_raw . show_envmap_handle , " " + tr ( "Envmap" ));
if ( context_raw . show_envmap_handle . changed ) {
context_load_envmap ();
context_raw . ddirty = 2 ;
}
ui_menu_fill ( ui );
context_raw . show_envmap_blur = zui_check ( context_raw . show_envmap_blur_handle , " " + tr ( "Blur Envmap" ));
2024-03-20 16:13:54 +01:00
if ( context_raw . show_envmap_blur_handle . changed ) {
context_raw . ddirty = 2 ;
}
2024-03-11 15:10:18 +01:00
context_update_envmap ();
2024-03-20 16:13:54 +01:00
if ( ui . changed ) {
ui_menu_keep_open = true ;
}
2024-03-11 15:10:18 +01:00
}
else if ( ui_menu_category == menu_category_t . MODE ) {
2024-03-24 10:26:56 +01:00
let mode_handle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
mode_handle . position = context_raw . viewport_mode ;
let modes : string [] = [
tr ( "Lit" ),
tr ( "Base Color" ),
///if (is_paint || is_lab)
tr ( "Normal" ),
tr ( "Occlusion" ),
tr ( "Roughness" ),
tr ( "Metallic" ),
tr ( "Opacity" ),
tr ( "Height" ),
///end
///if (is_paint)
tr ( "Emission" ),
tr ( "Subsurface" ),
///end
///if (is_paint || is_sculpt)
tr ( "TexCoord" ),
tr ( "Object Normal" ),
tr ( "Material ID" ),
tr ( "Object ID" ),
tr ( "Mask" )
///end
];
let shortcuts : string [] = [ "l" , "b" , "n" , "o" , "r" , "m" , "a" , "h" , "e" , "s" , "t" , "1" , "2" , "3" , "4" ];
///if (krom_direct3d12 || krom_vulkan || krom_metal)
if ( krom_raytrace_supported ()) {
2024-03-20 16:13:54 +01:00
array_push ( modes , tr ( "Path Traced" ));
array_push ( shortcuts , "p" );
2024-03-11 15:10:18 +01:00
}
///end
for ( let i : i32 = 0 ; i < modes . length ; ++ i ) {
ui_menu_fill ( ui );
2024-04-08 17:40:32 +02:00
let shortcut : string = config_raw . touch_ui ? "" : map_get ( config_keymap , "viewport_mode" ) + ", " + shortcuts [ i ];
2024-03-11 15:10:18 +01:00
zui_radio ( mode_handle , i , modes [ i ], shortcut );
}
if ( mode_handle . changed ) {
context_set_viewport_mode ( mode_handle . position );
// TODO: rotate mode is not supported for path tracing yet
if ( mode_handle . position == viewport_mode_t . PATH_TRACE && context_raw . camera_controls == camera_controls_t . ROTATE ) {
context_raw . camera_controls = camera_controls_t . ORBIT ;
viewport_reset ();
}
}
}
else if ( ui_menu_category == menu_category_t . CAMERA ) {
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Reset" ), map_get ( config_keymap , "view_reset" ))) {
2024-03-11 15:10:18 +01:00
viewport_reset ();
viewport_scale_to_bounds ();
}
ui_menu_separator ( ui );
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Front" ), map_get ( config_keymap , "view_front" ))) {
2024-03-11 15:10:18 +01:00
viewport_set_view ( 0 , - 1 , 0 , math_pi () / 2 , 0 , 0 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Back" ), map_get ( config_keymap , "view_back" ))) {
2024-03-11 15:10:18 +01:00
viewport_set_view ( 0 , 1 , 0 , math_pi () / 2 , 0 , math_pi ());
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Right" ), map_get ( config_keymap , "view_right" ))) {
2024-03-11 15:10:18 +01:00
viewport_set_view ( 1 , 0 , 0 , math_pi () / 2 , 0 , math_pi () / 2 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Left" ), map_get ( config_keymap , "view_left" ))) {
2024-03-11 15:10:18 +01:00
viewport_set_view ( - 1 , 0 , 0 , math_pi () / 2 , 0 , - math_pi () / 2 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Top" ), map_get ( config_keymap , "view_top" ))) {
2024-03-11 15:10:18 +01:00
viewport_set_view ( 0 , 0 , 1 , 0 , 0 , 0 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Bottom" ), map_get ( config_keymap , "view_bottom" ))) {
2024-03-11 15:10:18 +01:00
viewport_set_view ( 0 , 0 , - 1 , math_pi (), 0 , math_pi ());
}
ui_menu_separator ( ui );
ui . changed = false ;
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Orbit Left" ), map_get ( config_keymap , "view_orbit_left" ))) {
2024-03-11 15:10:18 +01:00
viewport_orbit ( - math_pi () / 12 , 0 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Orbit Right" ), map_get ( config_keymap , "view_orbit_right" ))) {
2024-03-11 15:10:18 +01:00
viewport_orbit ( math_pi () / 12 , 0 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Orbit Up" ), map_get ( config_keymap , "view_orbit_up" ))) {
2024-03-11 15:10:18 +01:00
viewport_orbit ( 0 , - math_pi () / 12 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Orbit Down" ), map_get ( config_keymap , "view_orbit_down" ))) {
2024-03-11 15:10:18 +01:00
viewport_orbit ( 0 , math_pi () / 12 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Orbit Opposite" ), map_get ( config_keymap , "view_orbit_opposite" ))) {
2024-03-11 15:10:18 +01:00
viewport_orbit_opposite ();
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Zoom In" ), map_get ( config_keymap , "view_zoom_in" ))) {
2024-03-11 15:10:18 +01:00
viewport_zoom ( 0.2 );
}
2024-04-08 17:40:32 +02:00
if ( ui_menu_button ( ui , tr ( "Zoom Out" ), map_get ( config_keymap , "view_zoom_out" ))) {
2024-03-11 15:10:18 +01:00
viewport_zoom ( - 0.2 );
}
// menuSeparator(ui);
ui_menu_fill ( ui );
let cam : camera_object_t = scene_camera ;
2024-04-24 12:14:47 +02:00
context_raw . fov_handle = zui_handle ( __ID__ );
if ( context_raw . fov_handle . init ) {
context_raw . fov_handle . value = math_floor ( cam . data . fov * 100 ) / 100 ;
}
2024-03-11 15:10:18 +01:00
ui_menu_align ( ui );
cam . data . fov = zui_slider ( context_raw . fov_handle , tr ( "FoV" ), 0.3 , 1.4 , true );
if ( context_raw . fov_handle . changed ) {
viewport_update_camera_type ( context_raw . camera_type );
}
ui_menu_fill ( ui );
ui_menu_align ( ui );
2024-03-24 10:26:56 +01:00
let camera_controls_handle : zui_handle_t = zui_handle ( __ID__ );
2024-03-11 15:10:18 +01:00
camera_controls_handle . position = context_raw . camera_controls ;
2024-05-03 21:29:39 +02:00
let camera_controls_items : string [] = [ tr ( "Orbit" ), tr ( "Rotate" ), tr ( "Fly" )];
context_raw . camera_controls = zui_inline_radio ( camera_controls_handle , camera_controls_items , zui_align_t . LEFT );
2024-03-11 15:10:18 +01:00
2024-03-21 21:06:41 +01:00
let vars : map_t < string , string > = map_create ();
2024-04-08 17:40:32 +02:00
map_set ( vars , "rotate_shortcut" , map_get ( config_keymap , "action_rotate" ));
map_set ( vars , "zoom_shortcut" , map_get ( config_keymap , "action_zoom" ));
map_set ( vars , "pan_shortcut" , map_get ( config_keymap , "action_pan" ));
2024-03-21 21:06:41 +01:00
let orbit_and_rotate_tooltip : string = tr ( "Orbit and Rotate mode:\n{rotate_shortcut} or move right mouse button to rotate.\n{zoom_shortcut} or scroll to zoom.\n{pan_shortcut} or move middle mouse to pan." , vars );
2024-03-11 15:10:18 +01:00
let fly_tooltip : string = tr ( "Fly mode:\nHold the right mouse button and one of the following commands:\nmove mouse to rotate.\nw, up or scroll up to move forward.\ns, down or scroll down to move backward.\na or left to move left.\nd or right to move right.\ne to move up.\nq to move down.\nHold shift to move faster or alt to move slower." );
2024-03-20 16:13:54 +01:00
if ( ui . is_hovered ) {
zui_tooltip ( orbit_and_rotate_tooltip + "\n\n" + fly_tooltip );
}
2024-03-11 15:10:18 +01:00
ui_menu_fill ( ui );
ui_menu_align ( ui );
2024-05-03 21:29:39 +02:00
let camera_type_items : string [] = [ tr ( "Perspective" ), tr ( "Orthographic" )];
context_raw . camera_type = zui_inline_radio ( context_raw . cam_handle , camera_type_items , zui_align_t . LEFT );
2024-03-20 16:13:54 +01:00
if ( ui . is_hovered ) {
2024-04-08 17:40:32 +02:00
zui_tooltip ( tr ( "Camera Type" ) + " (" + map_get ( config_keymap , "view_camera_type" ) + ")" );
2024-03-20 16:13:54 +01:00
}
2024-03-11 15:10:18 +01:00
if ( context_raw . cam_handle . changed ) {
viewport_update_camera_type ( context_raw . camera_type );
}
2024-03-20 16:13:54 +01:00
if ( ui . changed ) {
ui_menu_keep_open = true ;
}
2024-03-11 15:10:18 +01:00
}
else if ( ui_menu_category == menu_category_t . HELP ) {
if ( ui_menu_button ( ui , tr ( "Manual" ))) {
file_load_url ( manifest_url + "/manual" );
}
if ( ui_menu_button ( ui , tr ( "How To" ))) {
file_load_url ( manifest_url + "/howto" );
}
if ( ui_menu_button ( ui , tr ( "What's New" ))) {
file_load_url ( manifest_url + "/notes" );
}
if ( ui_menu_button ( ui , tr ( "Issue Tracker" ))) {
file_load_url ( "https://github.com/armory3d/armortools/issues" );
}
if ( ui_menu_button ( ui , tr ( "Report Bug" ))) {
///if (krom_darwin || krom_ios) // Limited url length
file_load_url ( "https://github.com/armory3d/armortools/issues/new?labels=bug&template=bug_report.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha () + ",%20" + sys_system_id ());
///else
file_load_url ( "https://github.com/armory3d/armortools/issues/new?labels=bug&template=bug_report.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha () + ",%20" + sys_system_id () + "*%0A%0A**Issue description:**%0A%0A**Steps to reproduce:**%0A%0A" );
///end
}
if ( ui_menu_button ( ui , tr ( "Request Feature" ))) {
///if (krom_darwin || krom_ios) // Limited url length
file_load_url ( "https://github.com/armory3d/armortools/issues/new?labels=feature%20request&template=feature_request.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha () + ",%20" + sys_system_id ());
///else
file_load_url ( "https://github.com/armory3d/armortools/issues/new?labels=feature%20request&template=feature_request.md&body=*" + manifest_title + "%20" + manifest_version + "-" + config_get_sha () + ",%20" + sys_system_id () + "*%0A%0A**Feature description:**%0A%0A" );
///end
}
ui_menu_separator ( ui );
if ( ui_menu_button ( ui , tr ( "Check for Updates..." ))) {
///if krom_android
file_load_url ( manifest_url_android );
///elseif krom_ios
file_load_url ( manifest_url_ios );
///else
// Retrieve latest version number
2024-04-07 09:52:45 +02:00
file_download_bytes ( "https://server.armorpaint.org/" + to_lower_case ( manifest_title ) + ".html" , function ( url : string , buffer : buffer_t ) {
2024-03-11 15:10:18 +01:00
if ( buffer != null ) {
// Compare versions
2024-05-03 21:29:39 +02:00
let update : update_info_t = json_parse ( sys_buffer_to_string ( buffer ));
2024-03-11 15:10:18 +01:00
let update_version : i32 = math_floor ( update . version );
if ( update_version > 0 ) {
2024-03-20 16:13:54 +01:00
let date : string = config_get_date (); // 2019 -> 19
date = substring ( date , 2 , date . length );
2024-03-21 21:06:41 +01:00
let date_int : i32 = parse_int ( string_replace_all ( date , "-" , "" ));
2024-03-11 15:10:18 +01:00
if ( update_version > date_int ) {
2024-03-21 21:06:41 +01:00
let vars : map_t < string , string > = map_create ();
map_set ( vars , "url" , manifest_url );
ui_box_show_message ( tr ( "Update" ), tr ( "Update is available!\nPlease visit {url}." , vars ));
2024-03-11 15:10:18 +01:00
}
else {
ui_box_show_message ( tr ( "Update" ), tr ( "You are up to date!" ));
}
}
}
else {
2024-03-21 21:06:41 +01:00
let vars : map_t < string , string > = map_create ();
map_set ( vars , "url" , manifest_url );
ui_box_show_message ( tr ( "Update" ), tr ( "Unable to check for updates.\nPlease visit {url}." , vars ));
2024-03-11 15:10:18 +01:00
}
});
///end
}
if ( ui_menu_button ( ui , tr ( "About..." ))) {
let msg : string = manifest_title + ".org - v" + manifest_version + " (" + config_get_date () + ") - " + config_get_sha () + "\n" ;
msg += sys_system_id () + " - " + strings_graphics_api ();
///if krom_windows
let save : string = ( path_is_protected () ? krom_save_path () : path_data ()) + path_sep + "tmp.txt" ;
2024-03-22 14:17:49 +01:00
krom_sys_command ( "wmic path win32_VideoController get name > \"" + save + "\"" );
2024-03-11 15:10:18 +01:00
let blob : buffer_t = krom_load_blob ( save );
2024-03-21 21:06:41 +01:00
let u8 : u8_array_t = u8_array_create_from_buffer ( blob );
2024-03-11 15:10:18 +01:00
let gpu_raw : string = "" ;
for ( let i : i32 = 0 ; i < math_floor ( u8 . length / 2 ); ++ i ) {
2024-03-20 16:13:54 +01:00
let c : string = string_from_char_code ( u8 [ i * 2 ]);
2024-03-11 15:10:18 +01:00
gpu_raw += c ;
}
2024-03-20 16:13:54 +01:00
let gpus : string [] = string_split ( gpu_raw , "\n" );
array_splice ( gpus , 1 , gpus . length - 2 );
2024-03-11 15:10:18 +01:00
let gpu : string = "" ;
2024-03-21 21:06:41 +01:00
for ( let i : i32 = 0 ; i < gpus . length ; ++ i ) {
let g : string = gpus [ i ];
2024-03-11 15:10:18 +01:00
gpu += trim_end ( g ) + ", " ;
}
2024-03-20 16:13:54 +01:00
gpu = substring ( gpu , 0 , gpu . length - 2 );
2024-03-22 14:17:49 +01:00
msg += "\n" + gpu ;
2024-03-11 15:10:18 +01:00
///else
// { lshw -C display }
///end
2024-04-07 09:52:45 +02:00
_ui_menu_render_msg = msg ;
2024-03-11 15:10:18 +01:00
ui_box_show_custom ( function ( ui : zui_t ) {
let tab_vertical : bool = config_raw . touch_ui ;
2024-03-24 10:26:56 +01:00
if ( zui_tab ( zui_handle ( __ID__ ), tr ( "About" ), tab_vertical )) {
2024-03-11 15:10:18 +01:00
let img : image_t = data_get_image ( "badge.k" );
2024-05-03 21:29:39 +02:00
_zui_image ( img );
2024-03-11 15:10:18 +01:00
zui_end_element ();
2024-04-24 12:14:47 +02:00
let h : zui_handle_t = zui_handle ( __ID__ );
if ( h . init ) {
h . text = _ui_menu_render_msg ;
}
zui_text_area ( h , zui_align_t . LEFT , false );
2024-03-11 15:10:18 +01:00
2024-04-25 22:04:43 +02:00
let row : f32 [] = [ 1 / 3 , 1 / 3 , 1 / 3 ];
zui_row ( row );
2024-03-11 15:10:18 +01:00
///if (krom_windows || krom_linux || krom_darwin)
if ( zui_button ( tr ( "Copy" ))) {
2024-04-07 09:52:45 +02:00
krom_copy_to_clipboard ( _ui_menu_render_msg );
2024-03-11 15:10:18 +01:00
}
///else
zui_end_element ();
///end
if ( zui_button ( tr ( "Contributors" ))) {
file_load_url ( "https://github.com/armory3d/armortools/graphs/contributors" );
}
if ( zui_button ( tr ( "OK" ))) {
ui_box_hide ();
}
}
}, 400 , 320 );
}
}
}
2024-05-03 21:29:39 +02:00
ui_menu_hide_flag = ui . combo_selected_handle == null && ! ui_menu_keep_open && ! ui_menu_show_first && ( ui . changed || ui . input_released || ui . input_released_r || ui . is_escape_down );
2024-03-11 15:10:18 +01:00
ui_menu_show_first = false ;
ui_menu_keep_open = false ;
2024-04-10 19:39:17 +02:00
ui . ops . theme . BUTTON_COL = _BUTTON_COL ;
ui . ops . theme . ELEMENT_OFFSET = _ELEMENT_OFFSET ;
ui . ops . theme . ELEMENT_H = _ELEMENT_H ;
2024-03-11 15:10:18 +01:00
zui_end_region ();
if ( ui_menu_hide_flag ) {
ui_menu_hide ();
ui_menu_show_first = true ;
ui_menu_commands = null ;
}
}
function ui_menu_hide() {
ui_menu_show = false ;
base_redraw_ui ();
}
function ui_menu_draw ( commands : ( ui : zui_t ) => void = null , elements : i32 , x : i32 = - 1 , y : i32 = - 1 ) {
zui_end_input ();
ui_menu_show = true ;
ui_menu_commands = commands ;
ui_menu_elements = elements ;
ui_menu_x = x > - 1 ? x : math_floor ( mouse_x + 1 );
ui_menu_y = y > - 1 ? y : math_floor ( mouse_y + 1 );
ui_menu_fit_to_screen ();
}
function ui_menu_fit_to_screen() {
// Prevent the menu going out of screen
let menu_w : f32 = base_default_element_w * zui_SCALE ( base_ui_menu ) * 2.3 ;
if ( ui_menu_x + menu_w > sys_width ()) {
if ( ui_menu_x - menu_w > 0 ) {
ui_menu_x = math_floor ( ui_menu_x - menu_w );
}
else {
ui_menu_x = math_floor ( sys_width () - menu_w );
}
}
2024-04-10 19:39:17 +02:00
let menu_h : f32 = math_floor ( ui_menu_elements * 30 * zui_SCALE ( base_ui_menu )); // ui.ops.theme.ELEMENT_H
2024-03-11 15:10:18 +01:00
if ( ui_menu_y + menu_h > sys_height ()) {
if ( ui_menu_y - menu_h > 0 ) {
ui_menu_y = math_floor ( ui_menu_y - menu_h );
}
else {
ui_menu_y = sys_height () - menu_h ;
}
ui_menu_x += 1 ; // Move out of mouse focus
}
}
function ui_menu_fill ( ui : zui_t ) {
2024-04-10 19:39:17 +02:00
g2_set_color ( ui . ops . theme . ACCENT_SELECT_COL );
2024-03-11 15:10:18 +01:00
g2_fill_rect ( ui . _x - 1 , ui . _y , ui . _w + 2 , zui_ELEMENT_H ( ui ) + 1 + 1 );
2024-04-10 19:39:17 +02:00
g2_set_color ( ui . ops . theme . SEPARATOR_COL );
2024-03-11 15:10:18 +01:00
g2_fill_rect ( ui . _x , ui . _y , ui . _w , zui_ELEMENT_H ( ui ) + 1 );
g2_set_color ( 0xffffffff );
}
function ui_menu_separator ( ui : zui_t ) {
ui . _y ++ ;
if ( config_raw . touch_ui ) {
2024-04-10 19:39:17 +02:00
zui_fill ( 0 , 0 , ui . _w / zui_SCALE ( ui ), 1 , ui . ops . theme . ACCENT_SELECT_COL );
2024-03-11 15:10:18 +01:00
}
else {
2024-04-10 19:39:17 +02:00
zui_fill ( 26 , 0 , ui . _w / zui_SCALE ( ui ) - 26 , 1 , ui . ops . theme . ACCENT_SELECT_COL );
2024-03-11 15:10:18 +01:00
}
}
2024-03-20 16:13:54 +01:00
function ui_menu_button ( ui : zui_t , text : string , label : string = "" ) : bool {
2024-03-11 15:10:18 +01:00
ui_menu_fill ( ui );
if ( config_raw . touch_ui ) {
label = "" ;
}
// let icons: image_t = icon > -1 ? get("icons.k") : null;
// let r: rect_t = tile25(icons, icon, 8);
// return Zui.button(config_button_spacing + text, config_button_align, label, icons, r.x, r.y, r.w, r.h);
return zui_button ( config_button_spacing + text , config_button_align , label );
}
function ui_menu_align ( ui : zui_t ) {
if ( ! config_raw . touch_ui ) {
2024-04-25 22:04:43 +02:00
let row : f32 [] = [ 12 / 100 , 88 / 100 ];
zui_row ( row );
2024-03-11 15:10:18 +01:00
zui_end_element ();
}
}
function ui_menu_start ( ui : zui_t ) {
// Draw top border
2024-04-10 19:39:17 +02:00
g2_set_color ( ui . ops . theme . ACCENT_SELECT_COL );
2024-03-11 15:10:18 +01:00
if ( config_raw . touch_ui ) {
g2_fill_rect ( ui . _x + ui . _w / 2 + ui_menu_category_w / 2 , ui . _y - 1 , ui . _w / 2 - ui_menu_category_w / 2 + 1 , 1 );
g2_fill_rect ( ui . _x - 1 , ui . _y - 1 , ui . _w / 2 - ui_menu_category_w / 2 + 1 , 1 );
g2_fill_rect ( ui . _x + ui . _w / 2 - ui_menu_category_w / 2 , ui . _y - ui_menu_category_h , ui_menu_category_w , 1 );
g2_fill_rect ( ui . _x + ui . _w / 2 - ui_menu_category_w / 2 , ui . _y - ui_menu_category_h , 1 , ui_menu_category_h );
g2_fill_rect ( ui . _x + ui . _w / 2 + ui_menu_category_w / 2 , ui . _y - ui_menu_category_h , 1 , ui_menu_category_h );
}
else {
g2_fill_rect ( ui . _x - 1 + ui_menu_category_w , ui . _y - 1 , ui . _w + 2 - ui_menu_category_w , 1 );
g2_fill_rect ( ui . _x - 1 , ui . _y - ui_menu_category_h , ui_menu_category_w , 1 );
g2_fill_rect ( ui . _x - 1 , ui . _y - ui_menu_category_h , 1 , ui_menu_category_h );
g2_fill_rect ( ui . _x - 1 + ui_menu_category_w , ui . _y - ui_menu_category_h , 1 , ui_menu_category_h );
}
g2_set_color ( 0xffffffff );
}