public IEnumerator shutter(string filename)
        {
            yield return(true);                                                                   //doesn't seem to matter what this returns

            Thread.Sleep(50);                                                                     //delay before re-opening windows
            //Application.CaptureScreenshot seems insistant on plonking the picture in KSP_Data, so this next bit relocates the pic to join it's friends in the screenshot folder
            string origin_path = Paths.joined(KSPUtil.ApplicationRootPath, "KSP_Data", filename); //location where screenshot is created (as a png)
            string png_path    = Paths.joined(KerbalX.screenshot_dir, filename);                  //location where it will be moved to

            if (File.Exists((origin_path)))
            {
                KerbalX.log("moving file: " + origin_path + " to: " + png_path);
                File.Move(origin_path, png_path);
            }
            else                                                                                          //TODO find less hacky way of solving which Data folder to look in
            {
                origin_path = Paths.joined(KSPUtil.ApplicationRootPath, "KSP_x64_Data", filename);        //location where screenshot is created (as a png)
                if (File.Exists((origin_path)))
                {
                    KerbalX.log("moving file: " + origin_path + " to: " + png_path);
                    File.Move(origin_path, png_path);
                }
            }

            //re-open the KX windows (after the file has been moved so the ImageSelector will notice it).
            foreach (KerbalXWindow win in open_windows)
            {
                win.show();
            }
        }
        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";
            }
        }
        //Grab a screenshot of the craft (KX windows will be hidden for a 100ms while screenshot is taken).
        private void grab_screenshot()
        {
            string filename = "screenshot - " + string.Format("{0:yyyy-MM-dd_hh-mm-ss}", DateTime.Now) + ".png";

            KerbalX.log("grabbing screenshot: " + filename);

            //track which windows are currently open in open_windows
            open_windows.Clear();
            if (KerbalX.upload_gui && KerbalX.upload_gui.visible)
            {
                open_windows.Add(KerbalX.upload_gui);
            }
            if (KerbalX.action_group_gui && KerbalX.action_group_gui.visible)
            {
                open_windows.Add(KerbalX.action_group_gui);
            }
            open_windows.Add(this);
            //hide all the open windows
            foreach (KerbalXWindow win in open_windows)
            {
                win.hide();
            }

            maximize();
            ScreenCapture.CaptureScreenshot(filename);
            StartCoroutine(shutter(filename));        //shutter re-opens the windows. well, it's kinda the exact opposite of what a shutter does, but yeah....whatever
        }
        //prepare craft data to upload as an update to an existing craft on KerbalX
        private void update_craft()
        {
            clear_errors();
            if (ok_to_send())
            {
                before_upload("Updating....");
                int craft_id = selected_craft_id;

                WWWForm craft_data = new WWWForm();
                craft_data.AddField("craft_name", craft_name);
                craft_data.AddField("craft_file", craft_file());
                craft_data.AddField("part_data", JSONX.toJSON(part_info()));

                KerbalX.api.update_craft(craft_id, craft_data, (resp, code) => {
                    var resp_data = JSON.Parse(resp);
                    if (code == 200)
                    {
                        KerbalX.log("craft update OK");
                        update_message = "Craft Updated";
                    }
                    else if (code == 422)
                    {
                        KerbalX.log("craft update failed!");
                        KerbalX.log(resp);
                        string resp_errs = resp_data["errors"];
                        errors           = resp_errs.Split(',').ToList();
                    }
                    after_upload();
                });
            }
        }
 //Callback for when then editor resets (new craft). This is also called when loading a craft (so onEditorLoad binding is not needed)
 public void on_editor_new()
 {
     KerbalX.log("EDIOTR NEW");
     if (visible)
     {
         KerbalX.upload_gui.reset();
     }
 }
Example #6
0
        //Button Actions

        //Action for upload interface button
        private void toggle_upload_interface()
        {
            if (KerbalX.upload_gui)
            {
                KerbalX.upload_gui.toggle();
            }
            else
            {
                KerbalX.log("UploadInterface has not been started");
            }
        }
        //Prepare craft data to upload as new craft on KerbalX
        private void upload_craft()
        {
            clear_errors();
            if (ok_to_send())
            {
                before_upload("Uploading....");

                WWWForm craft_data = new WWWForm();
                craft_data.AddField("craft_name", craft_name);
                craft_data.AddField("craft_style", craft_styles[selected_style_index]);
                craft_data.AddField("craft_file", craft_file());
                craft_data.AddField("part_data", JSONX.toJSON(part_info()));
                craft_data.AddField("action_groups", JSONX.toJSON(action_groups));
                craft_data.AddField("hash_tags", hash_tags);


                int pic_count = 0;
                int url_count = 0;
                foreach (PicData pic in pictures)
                {
                    if (pic.file != null)
                    {
                        craft_data.AddField("images[image_" + pic_count++ + "]", Convert.ToBase64String(read_as_jpg(pic)));
                    }
                    else
                    {
                        craft_data.AddField("image_urls[url_" + url_count++ + "]", pic.url);
                    }
                }

                KerbalX.api.upload_craft(craft_data, (resp, code) => {
                    var resp_data = JSON.Parse(resp);
                    if (code == 200)
                    {
                        KerbalX.log("craft uploaded OK");
                        show_upload_compelte_dialog(resp_data["url"]);
                        reset();
                        fetch_existing_craft();
                    }
                    else if (code == 422)
                    {
                        KerbalX.log("craft upload failed!");
                        KerbalX.log(resp);
                        string resp_errs = resp_data["errors"];
                        errors           = resp_errs.Split(',').ToList();
                    }
                    after_upload();
                });
            }
        }
 //Takes a PicData object and reads the image bytes.
 //If the image is already a jpg then it just returns the bytes, otherwise it is converted into a jpg first
 private byte[] read_as_jpg(PicData pic)
 {
     byte[] original_image = File.ReadAllBytes(pic.file.FullName);
     if (pic.file.Extension.ToLower() == ".jpg")
     {
         return(original_image);
     }
     else
     {
         KerbalX.log("compressing: " + pic.file.Name);
         Texture2D converter = new Texture2D(2, 2);
         converter.LoadImage(original_image);
         return(converter.EncodeToJPG());
     }
 }
Example #9
0
 //Action for download interface button
 private void toggle_download_interface()
 {
     if (KerbalX.download_gui)
     {
         if (KerbalX.download_gui.visible)
         {
             KerbalX.download_gui.hide();
         }
         else
         {
             KerbalXDownloadController.instance.fetch_download_queue(true);
         }
     }
     else
     {
         KerbalX.log("DownloadInterface has not been started");
     }
 }
        //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)
        }
Example #11
0
 //remove any existing KX buttons from the toolbar
 private void remove_from_toolbar()
 {
     KerbalX.log("Removing buttons from toolbar");
     if (KerbalX.upload_gui_toolbar_button)
     {
         ApplicationLauncher.Instance.RemoveModApplication(KerbalX.upload_gui_toolbar_button);
         KerbalX.upload_gui_toolbar_button = null;
     }
     if (KerbalX.download_gui_toolbar_button)
     {
         ApplicationLauncher.Instance.RemoveModApplication(KerbalX.download_gui_toolbar_button);
         KerbalX.download_gui_toolbar_button = null;
     }
     if (KerbalX.console_button)
     {
         ApplicationLauncher.Instance.RemoveModApplication(KerbalX.console_button);
         KerbalX.console_button = null;
     }
 }
 //check if craft_name matches any of the user's existing craft.  Sets matching_craft_ids to contain KX database ids of any matching craft
 //if only one match is found then selected_craft_id is also set to the matched id (which them selects the craft in the select menu)
 private void check_for_matching_craft_name()
 {
     if (!String.IsNullOrEmpty(craft_name))
     {
         KerbalX.log("checking for matching craft - " + craft_name);
         string lower_name = craft_name.Trim().ToLower();
         matching_craft_ids.Clear();
         foreach (KeyValuePair <int, string> craft in remote_craft)
         {
             string rc_lower = craft.Value.Trim().ToLower();
             if (lower_name == rc_lower || lower_name == rc_lower.Replace("-", " "))
             {
                 matching_craft_ids.Add(craft.Key);
             }
         }
         change_mode(matching_craft_ids.Count > 0 ? "update" : "upload");
         if (matching_craft_ids.Count == 1)
         {
             selected_craft_id = matching_craft_ids.First();
         }
     }
 }
Example #13
0
        //Bind events to add buttons to the toolbar
        private void add_to_toolbar()
        {
            ApplicationLauncher.Instance.AddOnHideCallback(this.toolbar_on_hide);     //bind events to close guis when toolbar hides

            KerbalX.log("Adding buttons to toolbar");

            if (!KerbalX.upload_gui_toolbar_button)
            {
                KerbalX.upload_gui_toolbar_button = ApplicationLauncher.Instance.AddModApplication(
                    toggle_upload_interface, toggle_upload_interface,
                    upload_btn_hover_on, upload_btn_hover_off,
                    null, null,
                    ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.SPH,
                    StyleSheet.assets["upload_toolbar_btn"]
                    );
            }
            if (!KerbalX.download_gui_toolbar_button)
            {
                KerbalX.download_gui_toolbar_button = ApplicationLauncher.Instance.AddModApplication(
                    toggle_download_interface, toggle_download_interface,
                    download_btn_hover_on, download_btn_hover_off,
                    null, null,
                    ApplicationLauncher.AppScenes.SPACECENTER,
                    StyleSheet.assets["dnload_toolbar_btn"]
                    );
            }
//            if(!KerbalX.console_button){
//                KerbalX.console_button = ApplicationLauncher.Instance.AddModApplication(
//                    toggle_console, toggle_console,
//                    null, null,
//                    null, null,
//                    ApplicationLauncher.AppScenes.SPACECENTER | ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.SPH,
//                    GameDatabase.Instance.GetTexture(Paths.joined("KerbalX", "Assets", "console_button"), false)
//                );
//            }
        }
        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);
                                    }
                                }
                            });
                        }
                    });
                }
            }
        }