static void Render_file(Panel p, uint partId, string filename, File file, Drive drive, bool short_strings, Vessel v) { // get experiment info ExperimentInfo exp = Science.Experiment(filename); double rate = Cache.VesselInfo(v).connection.rate; // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(ExperimentInfo.Situation(filename), Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", ExperimentInfo.Situation(filename), "</color>" ); double exp_value = Science.Value(filename, file.size); if (exp_value >= 0.1) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); } if (rate > 0) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<i>" + Lib.HumanReadableDuration(file.size / rate) + "</i>"); } p.AddContent(exp_label, Lib.HumanReadableDataSize(file.size), exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan)); bool send = drive.GetFileSend(filename); p.AddIcon(send ? Icons.send_cyan : Icons.send_black, "Flag the file for transmission to <b>DSN</b>", () => { drive.Send(filename, !send); }); p.AddIcon(Icons.toggle_red, "Delete the file", () => { Lib.Popup("Warning!", Lib.BuildString("Do you really want to delete ", exp.FullName(filename), "?"), new DialogGUIButton("Delete it", () => drive.Delete_file(filename, double.MaxValue, v.protoVessel)), new DialogGUIButton("Keep it", () => { })); } ); }
// ctor public Message() { // enable global access instance = this; // setup style style = new GUIStyle(); style.normal.background = Lib.GetTexture("black-background"); style.normal.textColor = new Color(0.66f, 0.66f, 0.66f, 1.0f); style.richText = true; style.stretchWidth = true; style.stretchHeight = true; style.fixedWidth = 0; style.fixedHeight = 0; style.fontSize = Styles.ScaleInteger(12); style.alignment = TextAnchor.MiddleCenter; style.border = new RectOffset(0, 0, 0, 0); style.padding = new RectOffset(Styles.ScaleInteger(2), Styles.ScaleInteger(2), Styles.ScaleInteger(2), Styles.ScaleInteger(2)); if (all_logs == null) { all_logs = new List<MessageObject>(); } }
/// <summary> /// If short_strings parameter is true then the strings used for display of the data will be shorter when inflight. /// </summary> public static void Fileman(this Panel p, Vessel v, bool short_strings = false) { // avoid corner-case when this is called in a lambda after scene changes v = FlightGlobals.FindVessel(v.id); // if vessel doesn't exist anymore, leave the panel empty if (v == null) { return; } // get info from the cache Vessel_info vi = Cache.VesselInfo(v); // if not a valid vessel, leave the panel empty if (!vi.is_valid) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " <color=#cccccc>FILE MANAGER</color>")); p.Width(Styles.ScaleWidthFloat(465.0f)); p.paneltype = Panel.PanelType.data; // time-out simulation if (p.Timeout(vi)) { return; } var drives = Drive.GetDriveParts(v); int filesCount = 0; double usedDataCapacity = 0; double totalDataCapacity = 0; int samplesCount = 0; int usedSlots = 0; int totalSlots = 0; double totalMass = 0; bool unlimitedData = false; bool unlimitedSamples = false; foreach (var idDrivePair in drives) { var drive = idDrivePair.Value; if (!drive.is_private) { usedDataCapacity += drive.FilesSize(); totalDataCapacity += drive.dataCapacity; unlimitedData |= drive.dataCapacity < 0; unlimitedSamples |= drive.sampleCapacity < 0; usedSlots += drive.SamplesSize(); totalSlots += drive.sampleCapacity; } filesCount += drive.files.Count; samplesCount += drive.samples.Count; foreach (var sample in drive.samples.Values) { totalMass += sample.mass; } } if (filesCount > 0 || totalDataCapacity > 0) { var title = "DATA " + Lib.HumanReadableDataSize(usedDataCapacity); if (!unlimitedData) { title += Lib.BuildString(" (", Lib.HumanReadablePerc((totalDataCapacity - usedDataCapacity) / totalDataCapacity), " available)"); } p.AddSection(title); foreach (var idDrivePair in drives) { uint partId = idDrivePair.Key; var drive = idDrivePair.Value; foreach (var pair in drive.files) { string filename = pair.Key; File file = pair.Value; Render_file(p, partId, filename, file, drive, short_strings && Lib.IsFlight(), v); } } if (filesCount == 0) { p.AddContent("<i>no files</i>", string.Empty); } } if (samplesCount > 0 || totalSlots > 0) { var title = "SAMPLES " + Lib.HumanReadableMass(totalMass) + " " + Lib.HumanReadableSampleSize(usedSlots); if (totalSlots > 0 && !unlimitedSamples) { title += ", " + Lib.HumanReadableSampleSize(totalSlots) + " available"; } p.AddSection(title); foreach (var idDrivePair in drives) { uint partId = idDrivePair.Key; var drive = idDrivePair.Value; foreach (var pair in drive.samples) { string samplename = pair.Key; Sample sample = pair.Value; Render_sample(p, partId, samplename, sample, drive, short_strings && Lib.IsFlight()); } } if (samplesCount == 0) { p.AddContent("<i>no samples</i>", string.Empty); } } }
public void Update() { var exp = Science.Experiment(experiment_id); // in flight if (Lib.IsFlight()) { Vessel v = FlightGlobals.ActiveVessel; if (v == null || EVA.IsDead(v)) { return; } // get info from cache Vessel_info vi = Cache.VesselInfo(vessel); // do nothing if vessel is invalid if (!vi.is_valid) { return; } var sampleSize = exp.max_amount; var eta = data_rate < double.Epsilon || Done(exp, dataSampled) ? " done" : " " + Lib.HumanReadableCountdown((sampleSize - dataSampled) / data_rate); // update ui var title = Lib.Ellipsis(exp.name, Styles.ScaleStringLength(24)); if (scienceValue > 0.1) { title += " •<b>" + scienceValue.ToString("F1") + "</b>"; } string statusString = string.Empty; switch (state) { case State.ISSUE: statusString = Lib.Color("yellow", issue); break; case State.RUNNING: statusString = Lib.HumanReadablePerc(dataSampled / sampleSize) + eta; break; case State.WAITING: statusString = "waiting" + eta; break; case State.STOPPED: statusString = "stopped"; break; } Events["Toggle"].guiName = Lib.StatusToggle(title, statusString); Events["Toggle"].active = (prepare_cs == null || didPrepare); Events["Prepare"].guiName = Lib.BuildString("Prepare <b>", exp.name, "</b>"); Events["Prepare"].active = !didPrepare && prepare_cs != null && string.IsNullOrEmpty(last_subject_id); Events["Reset"].guiName = Lib.BuildString("Reset <b>", exp.name, "</b>"); // we need a reset either if we have recorded data or did a setup bool resetActive = (reset_cs != null || prepare_cs != null) && !string.IsNullOrEmpty(last_subject_id); Events["Reset"].active = resetActive; if (issue.Length > 0 && hide_when_unavailable && issue != insufficient_storage) { Events["Toggle"].active = false; } } // in the editor else if (Lib.IsEditor()) { // update ui Events["Toggle"].guiName = Lib.StatusToggle(exp.name, recording ? "recording" : "stopped"); Events["Reset"].active = false; Events["Prepare"].active = false; } }
public static void Body_info(this Panel p) { // only show in mapview if (!MapView.MapIsEnabled) return; // only show if there is a selected body and that body is not the sun CelestialBody body = Lib.SelectedBody(); if (body == null || (body.flightGlobalsIndex == 0 && !Features.Radiation)) return; // shortcut CelestialBody sun = FlightGlobals.Bodies[0]; // for all bodies except the sun if (body != sun) { // calculate simulation values double atmo_factor = Sim.AtmosphereFactor(body, 0.7071); double gamma_factor = Sim.GammaTransparency(body, 0.0); double sun_dist = Sim.Apoapsis(Lib.PlanetarySystem(body)) - sun.Radius - body.Radius; Vector3d sun_dir = (sun.position - body.position).normalized; double solar_flux = Sim.SolarFlux(sun_dist) * atmo_factor; double albedo_flux = Sim.AlbedoFlux(body, body.position + sun_dir * body.Radius); double body_flux = Sim.BodyFlux(body, 0.0); double total_flux = solar_flux + albedo_flux + body_flux + Sim.BackgroundFlux(); double temperature = body.atmosphere ? body.GetTemperature(0.0) : Sim.BlackBodyTemperature(total_flux); // calculate night-side temperature double total_flux_min = Sim.AlbedoFlux(body, body.position - sun_dir * body.Radius) + body_flux + Sim.BackgroundFlux(); double temperature_min = Sim.BlackBodyTemperature(total_flux_min); // calculate radiation at body surface double radiation = Radiation.ComputeSurface(body, gamma_factor); // surface panel string temperature_str = body.atmosphere ? Lib.HumanReadableTemp(temperature) : Lib.BuildString(Lib.HumanReadableTemp(temperature_min), " / ", Lib.HumanReadableTemp(temperature)); p.AddSection("SURFACE"); p.AddContent("temperature", temperature_str); p.AddContent("solar flux", Lib.HumanReadableFlux(solar_flux)); if (Features.Radiation) p.AddContent("radiation", Lib.HumanReadableRadiation(radiation)); // atmosphere panel if (body.atmosphere) { p.AddSection("ATMOSPHERE"); p.AddContent("breathable", Sim.Breathable(body) ? "yes" : "no"); p.AddContent("light absorption", Lib.HumanReadablePerc(1.0 - Sim.AtmosphereFactor(body, 0.7071))); if (Features.Radiation) p.AddContent("gamma absorption", Lib.HumanReadablePerc(1.0 - Sim.GammaTransparency(body, 0.0))); } } // rendering panel if (Features.Radiation) { p.AddSection("RENDERING"); p.AddContent("inner belt", Radiation.show_inner ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.Toggle(ref Radiation.show_inner)); p.AddContent("outer belt", Radiation.show_outer ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.Toggle(ref Radiation.show_outer)); p.AddContent("magnetopause", Radiation.show_pause ? "<color=green>show</color>" : "<color=red>hide</color>", string.Empty, () => p.Toggle(ref Radiation.show_pause)); } // explain the user how to toggle the BodyInfo window p.AddContent(string.Empty); p.AddContent("<i>Press <b>B</b> to open this window again</i>"); // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(body.bodyName, Styles.ScaleStringLength(24)), " <color=#cccccc>BODY INFO</color>")); }
static Styles() { blackBackground = Lib.GetTexture("black-background"); // window container win = new GUIStyle(HighLogic.Skin.window) { padding = { left = ScaleInteger(6), right = ScaleInteger(6), top = 0, bottom = 0 } }; // window title container title_container = new GUIStyle { stretchWidth = true, fixedHeight = ScaleFloat(16.0f), margin = { bottom = ScaleInteger(2), top = ScaleInteger(2) } }; // window title text title_text = new GUIStyle { fontStyle = FontStyle.Bold, fontSize = ScaleInteger(10), fixedHeight = ScaleFloat(16.0f), alignment = TextAnchor.MiddleCenter }; // subsection title container section_container = new GUIStyle { stretchWidth = true, fixedHeight = ScaleFloat(16.0f), normal = { background = blackBackground }, margin = { bottom = ScaleInteger(4), top = ScaleInteger(4) } }; // subsection title text section_text = new GUIStyle(HighLogic.Skin.label) { stretchWidth = true, stretchHeight = true, fontSize = ScaleInteger(12), alignment = TextAnchor.MiddleCenter, normal = { textColor = Color.white } }; // entry row container entry_container = new GUIStyle { stretchWidth = true, fixedHeight = ScaleFloat(16.0f) }; // entry label text entry_label = new GUIStyle(HighLogic.Skin.label) { richText = true, stretchWidth = true, stretchHeight = true, fontSize = ScaleInteger(12), alignment = TextAnchor.MiddleLeft, normal = { textColor = Color.white } }; entry_label_nowrap = new GUIStyle(HighLogic.Skin.label) { richText = true, wordWrap = false, stretchWidth = true, stretchHeight = true, fontSize = ScaleInteger(12), alignment = TextAnchor.MiddleLeft, normal = { textColor = Color.white } }; // entry value text entry_value = new GUIStyle(HighLogic.Skin.label) { richText = true, stretchWidth = true, stretchHeight = true, fontStyle = FontStyle.Bold, fontSize = ScaleInteger(12), alignment = TextAnchor.MiddleRight, normal = { textColor = Color.white } }; // desc row container desc_container = new GUIStyle { stretchWidth = true, stretchHeight = true }; // entry multi-line description desc = new GUIStyle(entry_label) { fontStyle = FontStyle.Italic, alignment = TextAnchor.UpperLeft, margin = { top = 0, bottom = 0 }, padding = { top = 0, bottom = ScaleInteger(10) } }; // left icon left_icon = new GUIStyle { stretchWidth = true, stretchHeight = true, fixedWidth = ScaleFloat(16.0f), alignment = TextAnchor.MiddleLeft }; // right icon right_icon = new GUIStyle { stretchWidth = true, stretchHeight = true, margin = { left = ScaleInteger(8) }, fixedWidth = ScaleFloat(16.0f), alignment = TextAnchor.MiddleRight }; // tooltip label style tooltip = new GUIStyle(HighLogic.Skin.label) { stretchWidth = true, stretchHeight = true, fontSize = ScaleInteger(12), alignment = TextAnchor.MiddleCenter, border = new RectOffset(0, 0, 0, 0), normal = { textColor = Color.white, background = blackBackground }, margin = new RectOffset(0, 0, 0, 0), padding = new RectOffset(ScaleInteger(6), ScaleInteger(6), ScaleInteger(3), ScaleInteger(3)) }; tooltip.normal.background.wrapMode = TextureWrapMode.Repeat; // tooltip container style tooltip_container = new GUIStyle { stretchWidth = true, stretchHeight = true }; smallStationHead = new GUIStyle(HighLogic.Skin.label) { fontSize = ScaleInteger(12) }; smallStationText = new GUIStyle(HighLogic.Skin.label) { fontSize = ScaleInteger(12), normal = { textColor = Color.white } }; message = new GUIStyle() { normal = { background = blackBackground, textColor = new Color(0.66f, 0.66f, 0.66f, 1.0f) }, richText = true, stretchWidth = true, stretchHeight = true, fixedWidth = 0, fixedHeight = 0, fontSize = Styles.ScaleInteger(12), alignment = TextAnchor.MiddleCenter, border = new RectOffset(0, 0, 0, 0), padding = new RectOffset(Styles.ScaleInteger(2), Styles.ScaleInteger(2), Styles.ScaleInteger(2), Styles.ScaleInteger(2)) }; }
// called every frame public void On_gui() { // do nothing if GUI has not been initialized if (!ui_initialized) { return; } // render the window if (vesselListLauncher.toggleButton.Value || vesselListLauncher.IsHovering || (win_rect.width > 0f && win_rect.Contains(Mouse.screenPos))) { // hard-coded offsets // note: there is a bug in stock that only set appscale properly in non-flight-mode after you go in flight-mode at least once float at_top_offset_x = 40.0f * GameSettings.UI_SCALE * GameSettings.UI_SCALE_APPS; float at_top_offset_y = 0.0f * GameSettings.UI_SCALE * GameSettings.UI_SCALE_APPS; float at_bottom_offset_x = 0.0f * GameSettings.UI_SCALE * GameSettings.UI_SCALE_APPS; float at_bottom_offset_y = 40.0f * GameSettings.UI_SCALE * GameSettings.UI_SCALE_APPS; float at_bottom_editor_offset_x = 66.0f * GameSettings.UI_SCALE * GameSettings.UI_SCALE_APPS; // get screen size float screen_width = Screen.width; float screen_height = Screen.height; // determine app launcher position; bool is_at_top = ApplicationLauncher.Instance.IsPositionedAtTop; // get window size float width = Lib.IsEditor() ? Planner.Planner.Width() : monitor.Width(); float height = Lib.IsEditor() ? Planner.Planner.Height() : monitor.Height(); // calculate window position float left = screen_width - width; float top = is_at_top ? 0.0f : screen_height - height; if (is_at_top) { left -= at_top_offset_x; top += at_top_offset_y; } else { left -= !Lib.IsEditor() ? at_bottom_offset_x : at_bottom_editor_offset_x; top -= at_bottom_offset_y; } // store window geometry win_rect = new Rect(left, top, width, height); // begin window area GUILayout.BeginArea(win_rect, Styles.win); // a bit of spacing between title and content GUILayout.Space(Styles.ScaleFloat(10.0f)); // draw planner in the editors, monitor everywhere else if (!Lib.IsEditor()) { monitor.Render(); } else { Planner.Planner.Render(); } // end window area GUILayout.EndArea(); // draw tooltip tooltip.Draw(new Rect(0.0f, 0.0f, Screen.width, Screen.height)); } else { // set zero area win_rect win_rect.width = 0f; } // get mouse over state // bool mouse_over = win_rect.Contains(Event.current.mousePosition); bool mouse_over = win_rect.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y)); // disable camera mouse scrolling on mouse over if (mouse_over) { GameSettings.AXIS_MOUSEWHEEL.primary.scale = 0.0f; } // Disable Click through if (mouse_over && !clickThroughLocked) { InputLockManager.SetControlLock(MainGUILockTypes, "KerbalismMainGUILock"); clickThroughLocked = true; } if (!mouse_over && clickThroughLocked) { InputLockManager.RemoveControlLock("KerbalismMainGUILock"); clickThroughLocked = false; } }
internal static Texture2D GetTexture(string name, int width = 16, int height = 16, float prescalar = 1.0f) { return(Styles.GetUIScaledTexture(name, width, height, prescalar)); }
public static void Devman(this Panel p, Vessel v) { // avoid corner-case when this is called in a lambda after scene changes v = FlightGlobals.FindVessel(v.id); // if vessel doesn't exist anymore, leave the panel empty if (v == null) { return; } // get data VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), Lib.Color(Local.UI_devman, Lib.Kolor.LightGrey))); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.scripts; // time-out simulation if (!Lib.IsControlUnit(v) && p.Timeout(vd)) { return; } // get devices List <Device> devices = Computer.GetModuleDevices(v); int deviceCount = 0; // direct control if (script_index == 0) { // draw section title and desc p.AddSection ( Local.UI_devices, Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last), false ); bool hasVesselDeviceSection = false; bool hasModuleDeviceSection = false; // for each device for (int i = devices.Count - 1; i >= 0; i--) { Device dev = devices[i]; dev.OnUpdate(); if (!dev.IsVisible) { continue; } // create vessel device section if necessary if (dev is VesselDevice) { if (!hasVesselDeviceSection) { p.AddSection(Local.DevManager_VESSELDEVICES); //"VESSEL DEVICES" hasVesselDeviceSection = true; } } // create module device section if necessary else { if (!hasModuleDeviceSection) { p.AddSection(Local.DevManager_MODULEDEVICES); //"MODULE DEVICES" hasModuleDeviceSection = true; } } if (dev.PartId != 0u) { p.AddContent(dev.DisplayName, dev.Status, dev.Tooltip, dev.Toggle, () => Highlighter.Set(dev.PartId, Color.cyan)); } else { p.AddContent(dev.DisplayName, dev.Status, dev.Tooltip, dev.Toggle); } if (dev.Icon != null) { p.SetLeftIcon(dev.Icon.texture, dev.Icon.tooltip, dev.Icon.onClick); } deviceCount++; } } // script editor else { // get script ScriptType script_type = (ScriptType)script_index; string script_name = Name().ToUpper(); Script script = v.KerbalismData().computer.Get(script_type); // draw section title and desc p.AddSection ( script_name, Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last) ); bool hasVesselDeviceSection = false; bool hasModuleDeviceSection = false; // for each device for (int i = devices.Count - 1; i >= 0; i--) { Device dev = devices[i]; dev.OnUpdate(); if (!dev.IsVisible) { continue; } // determine tribool state int state = !script.states.ContainsKey(dev.Id) ? -1 : !script.states[dev.Id] ? 0 : 1; // create vessel device section if necessary if (dev is VesselDevice) { if (!hasVesselDeviceSection) { p.AddSection(Local.DevManager_VESSELDEVICES); //"VESSEL DEVICES" hasVesselDeviceSection = true; } } // create module device section if necessary else { if (!hasModuleDeviceSection) { p.AddSection(Local.DevManager_MODULEDEVICES); //"MODULE DEVICES" hasModuleDeviceSection = true; } } // render device entry p.AddContent ( dev.DisplayName, state == -1 ? Lib.Color(Local.UI_dontcare, Lib.Kolor.DarkGrey) : Lib.Color(state == 0, Local.Generic_OFF, Lib.Kolor.Yellow, Local.Generic_ON, Lib.Kolor.Green), string.Empty, () => { switch (state) { case -1: script.Set(dev, true); break; case 0: script.Set(dev, null); break; case 1: script.Set(dev, false); break; } }, () => Highlighter.Set(dev.PartId, Color.cyan) ); deviceCount++; } } // no devices case if (deviceCount == 0) { p.AddContent("<i>" + Local.DevManager_nodevices + "</i>"); //no devices } }
// to be called as window refresh function void Window_body(Panel p) { // outside the editor if (!Lib.IsEditor()) { // if part doesn't exist anymore if (part.flightID == 0 || FlightGlobals.FindPartByID(part.flightID) == null) { return; } } // inside the editor else { // if the part doesn't exist anymore (eg: removed, user hit undo) if (GetInstanceID() == 0) { return; } } // for each selected setup for (int selected_i = 0; selected_i < selected.Count; ++selected_i) { // find index in unlocked setups for (int setup_i = 0; setup_i < unlocked.Count; ++setup_i) { if (unlocked[setup_i].name == selected[selected_i]) { // commit panel Render_panel(p, unlocked[setup_i], selected_i, setup_i); } } } // set metadata p.Title(Lib.BuildString(Local.Module_Configure, " ", "<color=#cccccc>", Lib.Ellipsis(title, Styles.ScaleStringLength(40)), "</color>")); //Configure p.Width(Styles.ScaleWidthFloat(300.0f)); }
internal static Texture2D GetTexture(string name) { return(Styles.GetUIScaledTexture(name)); }
public override void OnLoad(ConfigNode node) { // everything in there will be called only one time : the first time a game is loaded from the main menu if (!IsCoreGameInitDone) { try { // core game systems Sim.Init(); // find suns (Kopernicus support) Radiation.Init(); // create the radiation fields ScienceDB.Init(); // build the science database (needs Sim.Init() and Radiation.Init() first) Science.Init(); // register the science hijacker // static graphic components LineRenderer.Init(); ParticleRenderer.Init(); Highlighter.Init(); // UI Textures.Init(); // set up the icon textures UI.Init(); // message system, main gui, launcher KsmGui.KsmGuiMasterController.Init(); // setup the new gui framework // part prefabs hacks Profile.SetupPods(); // add supply resources to pods Misc.PartPrefabsTweaks(); // part prefabs tweaks, must be called after ScienceDB.Init() // Create KsmGui windows new ScienceArchiveWindow(); // GameEvents callbacks Callbacks = new Callbacks(); } catch (Exception e) { string fatalError = "FATAL ERROR : Kerbalism core init has failed :" + "\n" + e.ToString(); Lib.Log(fatalError, Lib.LogLevel.Error); LoadFailedPopup(fatalError); } IsCoreGameInitDone = true; } // everything in there will be called every time a savegame (or a new game) is loaded from the main menu if (!IsSaveGameInitDone) { try { Cache.Init(); ResourceCache.Init(); // prepare storm data foreach (CelestialBody body in FlightGlobals.Bodies) { if (Storm.Skip_body(body)) { continue; } Storm_data sd = new Storm_data { body = body }; storm_bodies.Add(sd); } BackgroundResources.DisableBackgroundResources(); } catch (Exception e) { string fatalError = "FATAL ERROR : Kerbalism save game init has failed :" + "\n" + e.ToString(); Lib.Log(fatalError, Lib.LogLevel.Error); LoadFailedPopup(fatalError); } IsSaveGameInitDone = true; Message.Clear(); } // eveything else will be called on every OnLoad() call : // - save/load // - every scene change // - in various semi-random situations (thanks KSP) // Fix for background IMGUI textures being dropped on scene changes since KSP 1.8 Styles.ReloadBackgroundStyles(); // always clear the caches Cache.Clear(); ResourceCache.Clear(); // deserialize our database try { UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.DB.Load"); DB.Load(node); UnityEngine.Profiling.Profiler.EndSample(); } catch (Exception e) { string fatalError = "FATAL ERROR : Kerbalism save game load has failed :" + "\n" + e.ToString(); Lib.Log(fatalError, Lib.LogLevel.Error); LoadFailedPopup(fatalError); } // I'm smelling the hacky mess in here. Communications.NetworkInitialized = false; Communications.NetworkInitializing = false; // detect if this is a different savegame if (DB.uid != savegame_uid) { // clear caches Message.all_logs.Clear(); // sync main window pos from db UI.Sync(); // remember savegame id savegame_uid = DB.uid; } Kerbalism.gameLoadTime = Time.time; }
static void Render_file(Panel p, string filename, File file, Drive drive, bool short_strings, double rate) { // get experiment info ExperimentInfo exp = Science.Experiment(filename); // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(exp.situation, Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", exp.situation, "</color>" ); double exp_value = Science.Value(filename, file.size); if (exp_value > double.Epsilon) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); } if (rate > 0) { p.AddContent(exp_label, Lib.HumanReadableDataSize(file.size), "<i>" + Lib.HumanReadableDuration(file.size / rate) + "</i>"); } else { p.AddContent(exp_label, Lib.HumanReadableDataSize(file.size), exp_tooltip); } p.AddIcon(file.send ? Icons.send_cyan : Icons.send_black, "Flag the file for transmission to <b>DSN</b>", () => { file.send = !file.send; }); p.AddIcon(Icons.toggle_red, "Delete the file", () => Lib.Popup ( "Warning!", Lib.BuildString("Do you really want to delete ", exp.fullname, "?"), new DialogGUIButton("Delete it", () => drive.files.Remove(filename)), new DialogGUIButton("Keep it", () => { }) )); }
public void Render() { // headers foreach (Header h in headers) { GUILayout.BeginHorizontal(Styles.entry_container); if (h.leftIcon != null) { GUILayout.Label(new GUIContent(h.leftIcon.texture, h.leftIcon.tooltip), Styles.left_icon); if (h.leftIcon.click != null && Lib.IsClicked()) { callbacks.Add(h.leftIcon.click); } } GUILayout.Label(new GUIContent(h.label, h.tooltip), Styles.entry_label_nowrap); if (h.click != null && Lib.IsClicked()) { callbacks.Add(h.click); } foreach (Icon i in h.icons) { GUILayout.Label(new GUIContent(i.texture, i.tooltip), Styles.right_icon); if (i.click != null && Lib.IsClicked()) { callbacks.Add(i.click); } } GUILayout.EndHorizontal(); GUILayout.Space(Styles.ScaleFloat(10.0f)); } // sections foreach (Section p in sections) { // section title GUILayout.BeginHorizontal(Styles.section_container); if (p.left != null) { GUILayout.Label(Textures.left_arrow, Styles.left_icon); if (Lib.IsClicked()) { callbacks.Add(p.left); } } GUILayout.Label(p.title, Styles.section_text); if (p.right != null) { GUILayout.Label(Textures.right_arrow, Styles.right_icon); if (Lib.IsClicked()) { callbacks.Add(p.right); } } GUILayout.EndHorizontal(); // description if (p.desc.Length > 0) { GUILayout.BeginHorizontal(Styles.desc_container); GUILayout.Label(p.desc, Styles.desc); GUILayout.EndHorizontal(); } // entries if (p.needsSort) { p.needsSort = false; p.entries.Sort((a, b) => string.Compare(a.label, b.label, StringComparison.Ordinal)); } foreach (Entry e in p.entries) { GUILayout.BeginHorizontal(Styles.entry_container); if (e.leftIcon != null) { GUILayout.Label(new GUIContent(e.leftIcon.texture, e.leftIcon.tooltip), Styles.left_icon); if (e.leftIcon.click != null && Lib.IsClicked()) { callbacks.Add(e.leftIcon.click); } } GUILayout.Label(new GUIContent(e.label, e.tooltip), Styles.entry_label, GUILayout.Height(Styles.entry_label.fontSize)); if (e.hover != null && Lib.IsHover()) { callbacks.Add(e.hover); } GUILayout.Label(new GUIContent(e.value, e.tooltip), Styles.entry_value, GUILayout.Height(Styles.entry_value.fontSize)); if (e.click != null && Lib.IsClicked()) { callbacks.Add(e.click); } if (e.hover != null && Lib.IsHover()) { callbacks.Add(e.hover); } foreach (Icon i in e.icons) { GUILayout.Label(new GUIContent(i.texture, i.tooltip), Styles.right_icon); if (i.click != null && Lib.IsClicked()) { callbacks.Add(i.click); } } GUILayout.EndHorizontal(); } // spacing GUILayout.Space(Styles.ScaleFloat(10.0f)); } // call callbacks if (Event.current.type == EventType.Repaint) { foreach (Action func in callbacks) { func(); } callbacks.Clear(); } }
static void Render_sample(Panel p, uint partId, string filename, Sample sample, Drive drive, bool short_strings) { // get experiment info ExperimentInfo exp = Science.Experiment(filename); // render experiment name string exp_label = Lib.BuildString ( "<b>", Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)), "</b> <size=", Styles.ScaleInteger(10).ToString(), ">", Lib.Ellipsis(ExperimentInfo.Situation(filename), Styles.ScaleStringLength((short_strings ? 32 : 62) - Lib.Ellipsis(exp.name, Styles.ScaleStringLength(short_strings ? 24 : 38)).Length)), "</size>" ); string exp_tooltip = Lib.BuildString ( exp.name, "\n", "<color=#aaaaaa>", ExperimentInfo.Situation(filename), "</color>" ); double exp_value = Science.Value(filename, sample.size); if (exp_value >= 0.1) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableScience(exp_value), "</b>"); } if (sample.mass > Double.Epsilon) { exp_tooltip = Lib.BuildString(exp_tooltip, "\n<b>", Lib.HumanReadableMass(sample.mass), "</b>"); } p.AddContent(exp_label, Lib.HumanReadableSampleSize(sample.size), exp_tooltip, (Action)null, () => Highlighter.Set(partId, Color.cyan)); p.AddIcon(sample.analyze ? Icons.lab_cyan : Icons.lab_black, "Flag the file for analysis in a <b>laboratory</b>", () => { sample.analyze = !sample.analyze; }); p.AddIcon(Icons.toggle_red, "Dump the sample", () => { Lib.Popup("Warning!", Lib.BuildString("Do you really want to dump ", exp.FullName(filename), "?"), new DialogGUIButton("Dump it", () => drive.samples.Remove(filename)), new DialogGUIButton("Keep it", () => { })); } ); }
public static void Devman(this Panel p, Vessel v) { // avoid corner-case when this is called in a lambda after scene changes v = FlightGlobals.FindVessel(v.id); // if vessel doesn't exist anymore, leave the panel empty if (v == null) { return; } // get info from the cache Vessel_info vi = Cache.VesselInfo(v); // if not a valid vessel, leave the panel empty if (!vi.is_valid) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " <color=#cccccc>" + Localizer.Format("#KERBALISM_UI_devman") + "</color>")); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.scripts; // time-out simulation if (p.Timeout(vi)) { return; } // get devices Dictionary <uint, Device> devices = Computer.Boot(v); // direct control if (script_index == 0) { // draw section title and desc p.AddSection ( Localizer.Format("#KERBALISM_UI_devices"), Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last) ); // for each device foreach (var pair in devices) { // render device entry Device dev = pair.Value; p.AddContent(dev.Name(), dev.Info(), string.Empty, dev.Toggle, () => Highlighter.Set(dev.Part(), Color.cyan)); } } // script editor else { // get script ScriptType script_type = (ScriptType)script_index; string script_name = script_type.ToString().Replace('_', ' ').ToUpper(); Script script = DB.Vessel(v).computer.Get(script_type); // draw section title and desc p.AddSection ( script_name, Description(), () => p.Prev(ref script_index, (int)ScriptType.last), () => p.Next(ref script_index, (int)ScriptType.last) ); // for each device foreach (var pair in devices) { // determine tribool state int state = !script.states.ContainsKey(pair.Key) ? -1 : !script.states[pair.Key] ? 0 : 1; // render device entry Device dev = pair.Value; p.AddContent ( dev.Name(), state == -1 ? "<color=#999999>" + Localizer.Format("#KERBALISM_UI_dontcare") + " </color>" : state == 0 ? "<color=red>" + Localizer.Format("#KERBALISM_Generic_OFF") + "</color>" : "<color=cyan>" + Localizer.Format("#KERBALISM_Generic_ON") + "</color>", string.Empty, () => { switch (state) { case -1: script.Set(dev, true); break; case 0: script.Set(dev, null); break; case 1: script.Set(dev, false); break; } }, () => Highlighter.Set(dev.Part(), Color.cyan) ); } } // no devices case if (devices.Count == 0) { p.AddContent("<i>no devices</i>"); } }
public static void Config(this Panel p, Vessel v) { // avoid corner-case when this is called in a lambda after scene changes v = FlightGlobals.FindVessel(v.id); // if vessel doesn't exist anymore, leave the panel empty if (v == null) { return; } // get vessel data VesselData vd = v.KerbalismData(); // if not a valid vessel, leave the panel empty if (!vd.IsSimulated) { return; } // set metadata p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " ", Lib.Color("VESSEL CONFIG", Lib.Kolor.LightGrey))); p.Width(Styles.ScaleWidthFloat(355.0f)); p.paneltype = Panel.PanelType.config; // toggle rendering string tooltip; if (Features.Reliability) { p.AddSection("RENDERING"); } if (Features.Reliability) { tooltip = "Highlight failed components"; p.AddContent("highlight malfunctions", string.Empty, tooltip); p.AddRightIcon(vd.cfg_highlights ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_highlights)); } // toggle messages p.AddSection("MESSAGES"); tooltip = "Receive a message when\nElectricCharge level is low"; p.AddContent("battery", string.Empty, tooltip); p.AddRightIcon(vd.cfg_ec ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_ec)); if (Features.Supplies) { tooltip = "Receive a message when\nsupply resources level is low"; p.AddContent("supply", string.Empty, tooltip); p.AddRightIcon(vd.cfg_supply ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_supply)); } if (API.Comm.handlers.Count > 0 || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) { tooltip = "Receive a message when signal is lost or obtained"; p.AddContent("signal", string.Empty, tooltip); p.AddRightIcon(vd.cfg_signal ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_signal)); } if (Features.Reliability) { tooltip = "Receive a message\nwhen a component fail"; p.AddContent("reliability", string.Empty, tooltip); p.AddRightIcon(vd.cfg_malfunction ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_malfunction)); } if (Features.SpaceWeather) { tooltip = "Receive a message\nduring CME events"; p.AddContent("storm", string.Empty, tooltip); p.AddRightIcon(vd.cfg_storm ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_storm)); } if (Features.Automation) { tooltip = "Receive a message when\nscripts are executed"; p.AddContent("script", string.Empty, tooltip); p.AddRightIcon(vd.cfg_script ? Textures.toggle_green : Textures.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_script)); } }
///<summary> Initializes the icons </summary> internal static void Initialize() { TexturePath = KSPUtil.ApplicationRootPath + "GameData/Kerbalism/Textures/"; empty = Styles.GetUIScaledTexture("empty"); // an empty icon to maintain alignment close = Styles.GetUIScaledTexture("close"); // black close icon left_arrow = Styles.GetUIScaledTexture("left-arrow"); // white left arrow right_arrow = Styles.GetUIScaledTexture("right-arrow"); // white right arrow toggle_green = Styles.GetUIScaledTexture("toggle-green"); // green check mark toggle_red = Styles.GetUIScaledTexture("toggle-red"); // red check mark send_black = Styles.GetUIScaledTexture("send-black"); // used by file man send_cyan = Styles.GetUIScaledTexture("send-cyan"); lab_black = Styles.GetUIScaledTexture("lab-black"); lab_cyan = Styles.GetUIScaledTexture("lab-cyan"); applauncher = Styles.GetUIScaledTexture("applauncher", 38, 38); small_info = Styles.GetUIScaledTexture("small-info"); small_folder = Styles.GetUIScaledTexture("small-folder"); small_console = Styles.GetUIScaledTexture("small-console"); small_config = Styles.GetUIScaledTexture("small-config"); small_search = Styles.GetUIScaledTexture("small-search"); small_notes = Styles.GetUIScaledTexture("small-notes"); category_normal = Styles.GetUIScaledTexture("category-normal"); category_selected = Styles.GetUIScaledTexture("category-selected"); sun_black = Styles.GetUIScaledTexture("sun-black"); sun_white = Styles.GetUIScaledTexture("sun-white"); battery_white = Styles.GetUIScaledTexture("battery-white"); battery_yellow = Styles.GetUIScaledTexture("battery-yellow"); battery_red = Styles.GetUIScaledTexture("battery-red"); box_white = Styles.GetUIScaledTexture("box-white"); box_yellow = Styles.GetUIScaledTexture("box-yellow"); box_red = Styles.GetUIScaledTexture("box-red"); wrench_white = Styles.GetUIScaledTexture("wrench-white"); wrench_yellow = Styles.GetUIScaledTexture("wrench-yellow"); wrench_red = Styles.GetUIScaledTexture("wrench-red"); signal_white = Styles.GetUIScaledTexture("signal-white"); signal_yellow = Styles.GetUIScaledTexture("signal-yellow"); signal_red = Styles.GetUIScaledTexture("signal-red"); recycle_yellow = Styles.GetUIScaledTexture("recycle-yellow"); recycle_red = Styles.GetUIScaledTexture("recycle-red"); radiation_yellow = Styles.GetUIScaledTexture("radiation-yellow"); radiation_red = Styles.GetUIScaledTexture("radiation-red"); health_white = Styles.GetUIScaledTexture("health-white"); health_yellow = Styles.GetUIScaledTexture("health-yellow"); health_red = Styles.GetUIScaledTexture("health-red"); brain_white = Styles.GetUIScaledTexture("brain-white"); brain_yellow = Styles.GetUIScaledTexture("brain-yellow"); brain_red = Styles.GetUIScaledTexture("brain-red"); storm_yellow = Styles.GetUIScaledTexture("storm-yellow"); storm_red = Styles.GetUIScaledTexture("storm-red"); plant_white = Styles.GetUIScaledTexture("plant-white"); plant_yellow = Styles.GetUIScaledTexture("plant-yellow"); station_black = Styles.GetUIScaledTexture("vessels/station-black", 80, 80, 4); station_white = Styles.GetUIScaledTexture("vessels/station-white", 80, 80, 4); base_black = Styles.GetUIScaledTexture("vessels/base-black", 80, 80, 4); base_white = Styles.GetUIScaledTexture("vessels/base-white", 80, 80, 4); ship_black = Styles.GetUIScaledTexture("vessels/ship-black", 80, 80, 4); ship_white = Styles.GetUIScaledTexture("vessels/ship-white", 80, 80, 4); probe_black = Styles.GetUIScaledTexture("vessels/probe-black", 80, 80, 4); probe_white = Styles.GetUIScaledTexture("vessels/probe-white", 80, 80, 4); relay_black = Styles.GetUIScaledTexture("vessels/relay-black", 40, 40, 1.75f); relay_white = Styles.GetUIScaledTexture("vessels/relay-white", 40, 40, 1.75f); rover_black = Styles.GetUIScaledTexture("vessels/rover-black", 80, 80, 4); rover_white = Styles.GetUIScaledTexture("vessels/rover-white", 80, 80, 4); lander_black = Styles.GetUIScaledTexture("vessels/lander-black", 80, 80, 4); lander_white = Styles.GetUIScaledTexture("vessels/lander-white", 80, 80, 4); eva_black = Styles.GetUIScaledTexture("vessels/eva-black", 80, 80, 4); eva_white = Styles.GetUIScaledTexture("vessels/eva-white", 80, 80, 4); plane_black = Styles.GetUIScaledTexture("vessels/plane-black", 40, 40, 2.25f); plane_white = Styles.GetUIScaledTexture("vessels/plane-white", 40, 40, 2.25f); }