public void show_bulk_download_complete_dialog(List <int> loaded_ids, Dictionary <int, Dictionary <string, string> > craft_data) { KerbalXDialog dialog = show_dialog(d => { d.footer = true; GUILayout.Label("You craft have been downloaded", "h2"); GUILayout.Label("these ones to be precise:", "small"); dl_scroll_height = 62 * loaded_ids.Count; if (dl_scroll_height > 372f) { dl_scroll_height = 372f; } dl_scroll_pos = scroll(dl_scroll_pos, 500f, dl_scroll_height, sw => { foreach (int id in loaded_ids) { style_override = GUI.skin.GetStyle("background.dark.margin"); v_section(w => { GUILayout.Label(craft_data[id]["name"], "h3"); GUILayout.Label("saved to: " + craft_data[id]["short_path"]); }); } }); section(w => { GUILayout.FlexibleSpace(); if (GUILayout.Button("Done", "button.bold", width((150f)))) { close_dialog(); } }); }); dialog.window_title = "Download Summary"; }
//opens a dialog window which is populated by the lambda statement passed to show_dialog ie: //show_dialog((d) => { // GUILayout.Label("hello I'm a dialog"); //}) //The dialog instance is returned by show_dialog, and it's also passed into the lambda. protected KerbalXDialog show_dialog(DialogContent content) { KerbalXDialog dialog = gameObject.AddOrGetComponent <KerbalXDialog>(); dialog.content = content; return(dialog); }
public void show_new_save_dialog() { KerbalXDialog dialog = show_dialog(d => { GUILayout.Label("This looks like a new save", "h2"); GUILayout.Label("Would you like to fetch your craft from KerbalX for version " + ksp_ver, "h3"); section(w => { if (GUILayout.Button("No", "button.bold")) { close_dialog(); } if (GUILayout.Button("Let me pick", "button.bold")) { close_dialog(); KerbalXDownloadController.instance.fetch_users_craft(); } if (GUILayout.Button("Yep, fetch all my " + ksp_ver + " craft", "button.bold")) { close_dialog(); KerbalXDownloadController.instance.auto_load_users_craft(); } }); }); dialog.window_title = "Populate new save?"; }
private void toggle_large_viewer() { if (large_viewer) { GameObject.Destroy(large_viewer); } else { float viewer_width = 500f; large_viewer = show_dialog(d => { PicData pic = KerbalX.image_selector.pictures[KerbalX.image_selector.large_viewer_index]; v_section(viewer_width, outer => { section(w2 => { if (GUILayout.Button("<", "button.large.bold", width(viewer_width * 0.1f))) { KerbalX.image_selector.large_viewer_index--; if (KerbalX.image_selector.large_viewer_index < 0) { KerbalX.image_selector.large_viewer_index = 0; } } GUILayout.FlexibleSpace(); if (GUILayout.Button("Add Pic", "button.large.bold", width(viewer_width * 0.6f))) { toggle_pic(pic); } GUILayout.FlexibleSpace(); if (GUILayout.Button(">", "button.large.bold", width(viewer_width * 0.1f))) { KerbalX.image_selector.large_viewer_index++; if (KerbalX.image_selector.large_viewer_index > KerbalX.image_selector.pictures.Count - 1) { KerbalX.image_selector.large_viewer_index = KerbalX.image_selector.pictures.Count - 1; } } GUILayout.FlexibleSpace(); if (GUILayout.Button("X", "button.large.bold", width(viewer_width * 0.1f))) { close_dialog(); } }); if (KerbalX.image_selector.loaded_pics[pic.id] != true) { KerbalX.log("loading pic"); KerbalX.image_selector.loaded_pics[pic.id] = true; StartCoroutine(KerbalX.image_selector.load_image(pic.file.FullName, pic.texture)); } GUILayout.Label("Picture " + (large_viewer_index + 1) + "/" + pictures.Count().ToString()); section(viewer_width, w2 => { float h = pic.texture.height / (new [] { pic.texture.width, w2 }.Max() / w2); GUILayout.Label(pic.texture, width(viewer_width), height(h)); d.window_pos.height = h + 110; }); }); }); large_viewer.window_pos = new Rect(this.window_pos.x + this.window_pos.width, KerbalX.upload_gui.window_pos.y + KerbalX.upload_gui.window_pos.height, viewer_width, 20); large_viewer.window_title = "Image Viewer"; } }
//Dialog box to display once an upload has compelted. private void show_upload_compelte_dialog(string craft_path) { KerbalXDialog dialog = show_dialog((d) => { v_section(w => { GUILayout.Label("Your craft has uploaded!", "h1"); string craft_url = KerbalX.api.url_to(craft_path); GUILayout.Space(10f); if (GUILayout.Button(craft_url, "hyperlink.h2", width(500f))) { Application.OpenURL(craft_url); close_dialog(); } section(w2 => { GUILayout.Space(60f); if (GUILayout.Button(StyleSheet.assets["logo large"], "no_style", width(450f), height(81.32f))) { Application.OpenURL(craft_url); close_dialog(); } }); GUILayout.Label("Click the link (or logo) to view your craft.\nIf you want to change the page layout click the \"Edit Craft\" link at the top of the page.", "centered"); section(w3 => { GUILayout.FlexibleSpace(); if (GUILayout.Button("close", "button.bold", width(50f), height(20f))) { close_dialog(); } }); }); }); dialog.window_title = ""; dialog.window_pos = new Rect((Screen.width / 2 - 600f / 2), Screen.height / 4, 600f, 5); }
protected override void OnDestroy() { base.OnDestroy(); //releases any UI locks on the editor GameEvents.onEditorRestart.Remove(this.on_editor_new); KerbalXActionGroupInterface.close(); //destroy action group interface (if it is open) KerbalXImageSelector.close(); //destroy image selector (if it is open) KerbalXDialog.close(); //destroy dialog (if one is open) }
//reset interface internal void reset() { KerbalX.log("Resetting UploadInterface"); KerbalXActionGroupInterface.close(); //destroy action group interface (if it is open) KerbalXImageSelector.close(); //destroy image selector (if it is open) KerbalXDialog.close(); //destroy dialog (if one is open) pictures.Clear(); //remove all selected pictures selected_style_index = 0; //reset selected craft style to default (Ship) selected_craft_id = 0; //reset selected_craft_id (0 is non-value Database ID) update_message = null; List <string> keys = new List <string>(action_groups.Keys); foreach (string key in keys) //revert all values for action groups back to empty string { action_groups[key] = ""; } clear_errors(); //remove all errors (will also call autoheight, which is why this is called last) }
private void download_craft(int id, bool force_download) { if (force_download) { KerbalXDownloadController.instance.download_craft(id, craft_list[id]); } else { if (File.Exists(craft_list[id]["path"])) { KerbalXDialog dialog = show_dialog(d => { style_override = GUI.skin.GetStyle("background.dark"); v_section(w => { GUILayout.Label("A craft with this name already exists", "h2"); GUILayout.Label("You have a craft at: " + craft_list[id]["short_path"], "small"); }); section(w => { GUILayout.FlexibleSpace(); if (GUILayout.Button("Cancel", "button.bold", width(w * 0.2f))) { close_dialog(); } if (GUILayout.Button("Replace", "button.bold", width(w * 0.2f))) { KerbalXDownloadController.instance.download_craft(id, craft_list[id]); close_dialog(); } }); }); dialog.window_pos.width = 400f; dialog.window_pos.y = Screen.height - Input.mousePosition.y - 42; //42 just seemed like the answer, for some reason. dialog.window_pos.x = (window_pos.x + window_pos.width / 2) - dialog.window_pos.width / 2; dialog.window_title = "Replace Existing?"; } else { KerbalXDownloadController.instance.download_craft(id, craft_list[id]); } } }
protected override void WindowContent(int win_id) { if (mode == "url_entry") { v_section(w => { section(w2 => { GUILayout.Label("Enter the URL to your image", "h2", width(w2 - 100f)); if (GUILayout.Button("close", width(100f), height(30))) { this.hide(); } }); GUILayout.Label("note: one of 'em urls what end with an extension ie .jpg"); section(w2 => { pic_url = GUILayout.TextField(pic_url, width(w2 - 100f)); if (GUILayout.Button("Add url", width(100f))) { show_content_type_error = false; // HTTP.verify_image(pic_url, (content_type) =>{ // Debug.Log("resp: " + content_type); // if(content_type.StartsWith("image/")){ // PicData pic = new PicData(); // pic.url = pic_url; // KerbalX.upload_gui.add_picture(pic); // this.hide(); // } else{ // show_content_type_error = true; // } // }); } ; }); if (show_content_type_error) { GUILayout.Label("The entered URL does not return the content-type for an image", "alert"); } if (GUILayout.Button("or pic a pic from your pics.", height(40f))) { change_mode("pic_selector"); } }); } else { if (!minimized) { section(w => { v_section(w - 100f, w2 => { GUILayout.Label("Select a picture for your craft", "h2", width(w2)); GUILayout.Label("Click on pics below to add them", width(w2)); }); v_section(100f, w2 => { if (GUILayout.Button("or enter a url", width(w2), height(30))) { change_mode("url_entry"); } if (GUILayout.Button("close", width(w2), height(30))) { this.hide(); } }); }); } section(w => { if (GUILayout.Button("Take Screenshot now", "button.large", width(w - 40f))) { grab_screenshot(); } if (GUILayout.Button((minimized ? ">>" : "<<"), "button.large.bold", width(40f))) { minimized = !minimized; if (minimized) { minimize(); } else { maximize(); } } }); if (!minimized) { GUILayout.Label("Grabs a screen shot of the current view (KX windows will hide while taking the pic).", "small"); } section(w => { GUILayout.Label("pics directory: " + KerbalX.screenshot_dir.Replace(KSPUtil.ApplicationRootPath, ""), width(w - 20f)); if (GUILayout.Button("?", width(20f))) { if (tip) { GameObject.Destroy(tip); } else { tip = show_dialog(d => { GUILayout.Label("The default location for loading and saving pictures is the Screenshots folder in your KSP install directory."); GUILayout.Label("You can change where the KerbalX mod will save and load pictures from by changing the path in the settings.cfg file in GameData/KerbalX"); section(w2 => { GUILayout.FlexibleSpace(); if (GUILayout.Button("close", width(50f))) { close_dialog(); } }); }); tip.window_title = "Picture Location"; tip.window_pos = new Rect(this.window_pos.x + this.window_pos.width, Screen.height - Input.mousePosition.y, 400, 30); } } }); //Display picture selector - scrolling container of selectable pictures. //picture files will have already been selected and sorted (by prepare_pics()) and then grouped into rows of 4 pics per row (by group_pics()) //but the files won't have been read yet, so the picture textures haven't been set. Trying to load all picture textures on load is very time consuming. //so instead pictures are loaded and have their texture set row by row, on demand as the user scrolls down. if (pictures.Count == 0 && !minimized) { GUILayout.Label("You don't have any screen shots in your screen shots folder", "h3"); GUILayout.Label("Click Take Screenshot to take one now"); } if (pictures.Count > 0 && !minimized) { int n = 0; foreach (bool p in loaded_pics) { if (p) { n++; } } List <string> files = new List <string>(); foreach (PicData selected_pic in KerbalX.upload_gui.pictures) { files.Add(selected_pic.file.FullName); } section(w => { GUILayout.Label("loaded " + n + " of " + pictures.Count.ToString() + " pictures"); if (GUILayout.Button("large viewer", width(100f))) { toggle_large_viewer(); } if (GUILayout.Button("refresh", width(100f))) { prepare_pics(); } }); pics_scroll_height = pictures.Count <= 4 ? 150f : 300f; //adjust image selector height if 4 or less images scroll_pos = scroll(scroll_pos, 620f, pics_scroll_height, w => { int row_n = 1; foreach (List <PicData> row in groups) { //On demand loading of textures. As each row comes into focus it's picture's textures are loaded //row_n * 150 (the height of each row) defines it's bottom offset. when that value minus the current scroll pos is less than //the threshold (height of scroll container 300, plus 100 so images load before their in full view), then load the pictures on this row. if ((row_n * 150) - scroll_pos.y <= 400) { foreach (PicData pic in row) { if (loaded_pics[pic.id] != true) { loaded_pics[pic.id] = true; //bool array used to track which pictures have been loaded. checking the texture isn't good enough because of the coroutine StartCoroutine(load_image(pic.file.FullName, pic.texture)); //Use a Coroutine to load the picture texture with as little interface lag as possible. } } } row_n++;//increment row count //Draw each row, regardless of wheter picture textures have been loaded (will prob add a 'not yet loaded' texture in at some point TODO) style_override = GUI.skin.GetStyle("background.dark"); section(600f, sw => { //horizontal section....sorry, BeginHorizontal container for the row (slightly narrower than outter container to account for scroll bar) foreach (PicData pic in row) { v_section(150f, w2 => { //vertical section, ahem, BeginVertical container for each pic. Contains two restyled buttons, each will call select_pic. var style = (hover_ele == pic.file.FullName ? "pic.hover" : "pic.link"); //flip-flop style depending on hover_ele, being == to file name (because I can't figure out how to make style.hover work yet) if (files.Contains(pic.file.FullName)) { style = (hover_ele == pic.file.FullName ? "pic.selected.highlighted" : "pic.selected"); } if (GUILayout.Button(pic.texture, style, width(w2), height(w2 * 0.75f))) { toggle_pic(pic); } if (GUILayout.Button(pic.name, style, width(w2), height(37.5f))) { toggle_pic(pic); } }); Vector2 mouse_pos = Input.mousePosition; mouse_pos.y = Screen.height - mouse_pos.y; if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) && mouse_pos.y < window_pos.y + window_pos.height) //detect if mouse is over the last vertical section { KerbalX.log("image hover"); hover_ele = pic.file.FullName; //and hover_ele to that pics filename. used to set on hover style KerbalX.image_selector.large_viewer_index = pictures.IndexOf(pic); } } }); } }); } } }
private void Start() { KerbalXDialog.instance = this; footer = false; is_dialog = true; }
//close instance of dialog if it exists. protected void close_dialog() { KerbalXDialog.close(); }
//Main Upload/Update interface! protected override void WindowContent(int win_id) { show_upload_bttn = true; //get the craft name from the editor field, but allow the user to set a alternative name to upload as without changing the editor field //but if the user changes the editor field then reset the craft_name to that. make sense? good, shutup. if (editor_craft_name != EditorLogic.fetch.ship.shipName) { craft_name = EditorLogic.fetch.ship.shipName; check_for_matching_craft_name(); } editor_craft_name = EditorLogic.fetch.ship.shipName; //Perform checks to see if there is a craft, its not untitled and a craft file for it exists. string trimmed_lowered_name = editor_craft_name.Trim().ToLower().Replace(" ", ""); if (part_info().Count == 0) { GUILayout.Label("No craft loaded. Create or load a craft to continue.", "h3"); } else if (trimmed_lowered_name == "untitledspacecraft" || trimmed_lowered_name == EditorLogic.autoShipName) { GUILayout.Label(editor_craft_name + "? Really?\nHow about you name the poor thing before uploading!", "h3"); } else if (!craft_file_exists()) { section(w => { GUILayout.Label("This craft hasn't been saved yet\nNo craft file found for " + editor_craft_name, "h3", width(w * 0.7f)); if (GUILayout.Button("Save it now", width(w * 0.3f), height(40))) { EditorLogic.fetch.saveBtn.onClick.Invoke(); } }); } else { //if checks pass continue with drawing rest of interface string mode_title = new CultureInfo("en-US", false).TextInfo.ToTitleCase(mode); if (fetching_craft) { GUILayout.Label("Getting your craft list from KerbalX...", "h3"); } else { GUILayout.Label(mode_title + " '" + craft_name + "' " + (mode == "update" ? "on" : "to") + " KerbalX", "h3"); if (mode == "upload") { section(w => { GUILayout.Label("Enter details about your craft", width(w * 0.45f)); GUILayout.Label("OR", "centered", width(w * 0.1f)); if (GUILayout.Button("Update An Existing Craft", width(w * 0.45f))) { change_mode("update"); if (matching_craft_ids.Count != 1) { selected_craft_id = 0; } } }); //textfield for craft name, if value is changed it is checked against existing craft (and if match, mode is switched to update). section(w => { string current_craft_name = craft_name; //used to detect if user changes craft_name field (GUI.changed gets triggered by above button) GUILayout.Label("Craft name:", width(80f)); craft_name = GUILayout.TextField(craft_name, 255, width(w - 80)); if (craft_name != current_craft_name) { check_for_matching_craft_name();//check for matching existing craft } }); section(w => { GUILayout.Label("#tags:", width(80f)); hash_tags = GUILayout.TextField(hash_tags, 255, width(w - 80)); }); //drop down select for craft type section(w => { GUILayout.Label("Select craft type:", width(100f)); combobox("craft_style_select", craft_styles, selected_style_index, 100f, 150f, this, id => { selected_style_index = id; }); if (GUILayout.Button("Edit Description")) { KerbalXDialog dialog = show_dialog(d => { GUILayout.Label("Edit your craft's description", "h2"); GUILayout.Label("this field edits the description text stored on the craft file, this just provides a larger interface", "small"); EditorLogic.fetch.shipDescriptionField.text = GUILayout.TextArea(EditorLogic.fetch.shipDescriptionField.text, height(350f)); if (GUILayout.Button("Close", "button.bold")) { EditorLogic.fetch.saveBtn.onClick.Invoke(); close_dialog(); } GUILayout.Label("Note: closing this also saves the craft, so changes to the description are kept", "small"); }); dialog.window_pos = new Rect(Screen.width / 2 - 300, 200, 600, 400); dialog.window_title = "Edit Description"; } }); //buttons for setting action groups and adding pictures. section(w => { if (GUILayout.Button("Edit Action Group info", width(w * 0.5f), height(30))) { if (KerbalX.action_group_gui) { KerbalX.action_group_gui.toggle(); } else { launch("ActionGroupEditor"); } } if (GUILayout.Button("Add Pictures", width(w * 0.5f), height(30))) { if (KerbalX.image_selector) { KerbalX.image_selector.toggle(); } else { launch("ImageSelector"); } } }); //Display of selected pictures (and/or image urls) v_section(w => { section(w2 => { foreach (PicData pic in pictures) //display selected pictures { v_section(80f, w3 => { if (pic.file != null) { GUILayout.Label(pic.texture, width(w3), height(w3 * 0.75f)); if (GUILayout.Button("remove")) { remove_picture(pic); } } }); } }); foreach (PicData pic in pictures) //display entered image urls. { section(w2 => { if (pic.url != null) { GUILayout.Label(pic.url, width(w2 - 80f)); if (GUILayout.Button("remove", width(80f))) { remove_picture(pic); } } }); } }); } else if (mode == "update") { if (KerbalX.existing_craft.Count == 0) //show message if the user doesn't have any craft on KerbalX yet. { show_upload_bttn = false; GUILayout.Label("You haven't uploaded any craft yet", "h2"); GUILayout.Label("Once you've uploaded craft they will appear here and you'll be able to select them to update"); section(w => { GUILayout.FlexibleSpace(); if (GUILayout.Button("refresh", width(60f))) { fetch_existing_craft(); } }); if (GUILayout.Button("Upload a Craft", height(30f))) { change_mode("upload"); } } else { //Show message if the current craft name matches the name of one of the users craft on KerbalX if (matching_craft_ids.Count > 0) { string label_text = "This craft's name matches the name of " + (matching_craft_ids.Count == 1 ? "a" : "several") + " craft you've already uploaded."; if (matching_craft_ids.Count > 1) { label_text = label_text + " Select which one you want to update"; //in the case of more than one match. } GUILayout.Label(label_text); } section(w => { v_section(w * 0.7f, inner_w => { section(inner_w, inner_w2 => { GUILayout.Label("Select Craft on KerbalX to update:"); }); combobox("craft_select", remote_craft, selected_craft_id, inner_w, 150f, this, id => { selected_craft_id = id; autoheight(); }); }); section(w * 0.3f, inner_w2 => { if (GUILayout.Button("OR upload this as a new craft", "button.wrapped", height(50))) { change_mode("upload"); } }); }); if (selected_craft_id != 0) { style_override = GUI.skin.GetStyle("background.dark.margin"); v_section(w => { GUILayout.Label("Pressing Update will update the this craft on KerbalX:", "h3"); GUILayout.Label(KerbalX.existing_craft[selected_craft_id]["name"] + " (id: " + selected_craft_id + ")", "h3"); string craft_url = KerbalX.api.url_to(KerbalX.existing_craft[selected_craft_id]["url"]); if (GUILayout.Button(craft_url, "hyperlink.h3")) { Application.OpenURL(craft_url); } GUILayout.Label("Make sure this is the craft you want update!"); }); } } } } //Display any errors preventing upload if (errors.Count() > 0) { style_override = GUI.skin.GetStyle("background.dark.margin"); v_section(w => { foreach (string error in errors) { GUILayout.Label(error.Trim(), "alert", width(w)); } }); } //The great big ol' thing what you whack to make stuff happen if (show_upload_bttn && !fetching_craft) { GUI.enabled = enable_upload_bttn; section(w => { if (GUILayout.Button(mode_title + "!", "button.upload")) { if (mode == "update") { update_craft(); } else { upload_craft(); } } }); GUI.enabled = true; } //display some feedback to show that upload/update is happening if (transfer_activity != null || fetching_craft) { v_section(w => { if (transfer_activity != null) { GUILayout.Label(transfer_activity, "h2"); } progress_spinner(w, 5, 20); }); } if (update_message != null) { GUILayout.Label(update_message, "h2.centered"); } } }