private string InfoLine(ISystem sys, StarScan.ScanNode sn, JournalScan sd) { var information = new StringBuilder(); if (sd.Mapped) { information.Append("\u2713"); // let the cmdr see that this body is already mapped - this is a check } string bodyname = sd.BodyName.ReplaceIfStartsWith(sys.Name); // Name information.Append(bodyname); // Additional information information.Append((sd.AmmoniaWorld) ? @" is an ammonia world.".T(EDTx.UserControlSurveyor_isanammoniaworld) : null); information.Append((sd.Earthlike) ? @" is an earth like world.".T(EDTx.UserControlSurveyor_isanearthlikeworld) : null); information.Append((sd.WaterWorld && !sd.Terraformable) ? @" is a water world.".T(EDTx.UserControlSurveyor_isawaterworld) : null); information.Append((sd.WaterWorld && sd.Terraformable) ? @" is a terraformable water world.".T(EDTx.UserControlSurveyor_isaterraformablewaterworld) : null); information.Append((sd.Terraformable && !sd.WaterWorld) ? @" is a terraformable planet.".T(EDTx.UserControlSurveyor_isaterraformableplanet) : null); information.Append((sd.HasRings) ? @" Has ring.".T(EDTx.UserControlSurveyor_Hasring) : null); information.Append((sd.HasMeaningfulVolcanism) ? @" Has ".T(EDTx.UserControlSurveyor_Has) + sd.Volcanism + "." : null); information.Append((sd.nRadius < lowRadiusLimit) ? @" Low Radius.".T(EDTx.UserControlSurveyor_LowRadius) : null); information.Append((sn.Signals != null) ? " Has Signals.".T(EDTx.UserControlSurveyor_Signals) : null); information.Append(@" " + sd.DistanceFromArrivalText); if (sd.WasMapped == true && sd.WasDiscovered == true) { information.Append(" (Mapped & Discovered)".T(EDTx.UserControlSurveyor_MandD)); if (showValuesToolStripMenuItem.Checked) { information.Append(" " + sd.EstimatedValueBase.ToString("N0") + " cr"); } } else if (sd.WasMapped == true && sd.WasDiscovered == false) { information.Append(" (Mapped)".T(EDTx.UserControlSurveyor_MP)); if (showValuesToolStripMenuItem.Checked) { information.Append(" " + sd.EstimatedValueBase.ToString("N0") + " cr"); } } else if (sd.WasDiscovered == true && sd.WasMapped == false) { information.Append(" (Discovered)".T(EDTx.UserControlSurveyor_DIS)); if (showValuesToolStripMenuItem.Checked) { information.Append(" " + sd.EstimatedValueFirstMappedEfficiently.ToString("N0") + " cr"); } } else { // cope with old versions if (showValuesToolStripMenuItem.Checked) { information.Append(" " + (sd.EstimatedValueFirstDiscoveredFirstMappedEfficiently > 0 ? sd.EstimatedValueFirstDiscoveredFirstMappedEfficiently : sd.EstimatedValueBase).ToString("N0") + " cr"); } } return(information.ToString()); }
// return right bottom of area used from curpos Point CreatePlanetTree(List <PictureBoxHotspot.ImageElement> pc, StarScan.ScanNode planetnode, Point curpos) { // PLANETWIDTH|PLANETWIDTH (if drawing a full planet with rings/landing) // or // MOONWIDTH|MOONWIDTH (if drawing a single width planet) // this offset, ONLY used if a single width planet, allows for two moons int offset = moonsize.Width - planetsize.Width / 2; // centre is moon width, back off by planetwidth/2 to place the left edge of the planet Point maxtreepos = DrawNode(pc, planetnode, JournalScan.GetPlanetImageNotScanned(), curpos, planetsize, ref offset, true); // offset passes in the suggested offset, returns the centre offset if (planetnode.children != null && checkBoxMoons.Checked) { offset -= moonsize.Width; // offset is centre of planet image, back off by a moon width to allow for 2 moon widths centred Point moonpos = new Point(curpos.X + offset, maxtreepos.Y + itemsepar.Height); // moon pos foreach (StarScan.ScanNode moonnode in planetnode.children.Values) { int offsetm = moonsize.Width / 2; // pass in normal offset if not double width item (half moon from moonpos.x) Point mmax = DrawNode(pc, moonnode, JournalScan.GetMoonImageNotScanned(), moonpos, moonsize, ref offsetm, false); maxtreepos = new Point(Math.Max(maxtreepos.X, mmax.X), Math.Max(maxtreepos.Y, mmax.Y)); if (moonnode.children != null) { Point submoonpos; if (mmax.X <= moonpos.X + moonsize.Width * 2) // if we have nothing wider than the 2 moon widths, we can go with it right aligned { submoonpos = new Point(moonpos.X + moonsize.Width * 2 + itemsepar.Width, moonpos.Y); // moon pos } else { submoonpos = new Point(moonpos.X + moonsize.Width * 2 + itemsepar.Width, mmax.Y + itemsepar.Height); // moon pos below and right } foreach (StarScan.ScanNode submoonnode in moonnode.children.Values) { int offsetsm = moonsize.Width / 2; // pass in normal offset if not double width item (half moon from moonpos.x) Point sbmax = DrawNode(pc, submoonnode, JournalScan.GetMoonImageNotScanned(), submoonpos, moonsize, ref offsetsm, false); maxtreepos = new Point(Math.Max(maxtreepos.X, sbmax.X), Math.Max(maxtreepos.Y, sbmax.Y)); submoonpos = new Point(submoonpos.X, maxtreepos.Y + itemsepar.Height); } } moonpos = new Point(moonpos.X, maxtreepos.Y + itemsepar.Height); } } return(maxtreepos); }
private List <StarScan.ScanNode> Flatten(StarScan.ScanNode sn, List <StarScan.ScanNode> flattened) { flattened.Add(sn); if (sn.children != null) { foreach (StarScan.ScanNode node in sn.children.Values) { Flatten(node, flattened); } } return(flattened); }
// draw scannode (may be null), // curmats may be null public void DrawSystem(StarScan.SystemNode scannode, MaterialCommoditiesList curmats, HistoryList hl, string opttext = null, string[] filter = null) { HideInfo(); imagebox.ClearImageList(); // does not clear the image, render will do that if (scannode != null) { Point leftmiddle = new Point(leftmargin, topmargin + StarSize.Height * nodeheightratio / 2 / noderatiodivider); // half down (h/2 * ratio) if (opttext != null) { ExtPictureBox.ImageElement lab = new ExtPictureBox.ImageElement(); lab.TextAutosize(new Point(leftmargin, 0), new Size(500, 30), opttext, largerfont, EDDTheme.Instance.LabelColor, this.BackColor); imagebox.Add(lab); leftmiddle.Y += lab.Image.Height + 8; } DisplayAreaUsed = leftmiddle; List <ExtPictureBox.ImageElement> starcontrols = new List <ExtPictureBox.ImageElement>(); bool displaybelts = filter == null || (filter.Contains("belt") || filter.Contains("All")); Point maxitemspos = new Point(0, 0); foreach (StarScan.ScanNode starnode in scannode.starnodes.Values) // always has scan nodes { if (filter != null && starnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { // System.Diagnostics.Debug.WriteLine("SDUC Rejected " + starnode.fullname); continue; } // Draw star Point maxstarpos = DrawNode(starcontrols, starnode, curmats, hl, (starnode.type == StarScan.ScanNodeType.barycentre) ? Icons.Controls.Scan_Bodies_Barycentre : JournalScan.GetStarImageNotScanned(), leftmiddle, false, out int unusedstarcentre, StarSize, DrawLevel.TopLevelStar); // the last part nerfs the label down to the right position maxitemspos = new Point(Math.Max(maxitemspos.X, maxstarpos.X), Math.Max(maxitemspos.Y, maxstarpos.Y)); if (starnode.children != null) { leftmiddle = new Point(maxitemspos.X + starfirstplanetspacerx, leftmiddle.Y); Point firstcolumn = leftmiddle; Queue <StarScan.ScanNode> belts; if (starnode.ScanData != null && (!starnode.ScanData.IsEDSMBody || CheckEDSM)) // have scandata on star, and its not edsm or allowed edsm { belts = new Queue <StarScan.ScanNode>(starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.belt)); // find belts in children of star } else { belts = new Queue <StarScan.ScanNode>(); // empty array } StarScan.ScanNode lastbelt = belts.Count != 0 ? belts.Dequeue() : null; double habzonestartls = starnode.ScanData?.HabitableZoneInner ?? 0; double habzoneendls = starnode.ScanData?.HabitableZoneOuter ?? 0; // process body and stars only List <StarScan.ScanNode> planetsinorder = starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.body || s.type == StarScan.ScanNodeType.star).ToList(); var planetcentres = new Dictionary <StarScan.ScanNode, Point>(); for (int pn = 0; pn < planetsinorder.Count; pn++) { StarScan.ScanNode planetnode = planetsinorder[pn]; if (filter != null && planetnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { //System.Diagnostics.Debug.WriteLine("SDUC Rejected " + planetnode.fullname); continue; } //System.Diagnostics.Debug.WriteLine("Draw " + planetnode.ownname + ":" + planetnode.type); // if belt is before this, display belts here while (displaybelts && lastbelt != null && planetnode.ScanData != null && (lastbelt.BeltData == null || planetnode.ScanData.IsOrbitingBaryCentre || lastbelt.BeltData.OuterRad < planetnode.ScanData.nSemiMajorAxis)) { // if too far across, go back to star if (leftmiddle.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) // if too far across.. { leftmiddle = new Point(firstcolumn.X, maxitemspos.Y + planetspacery + planetsize.Height / 2); // move to left at maxy+space+h/2 } string appendlabel = ""; if (lastbelt.BeltData != null) { appendlabel = appendlabel.AppendPrePad($"{lastbelt.BeltData.OuterRad / JournalScan.oneLS_m:N1}ls", Environment.NewLine); } appendlabel = appendlabel.AppendPrePad("" + lastbelt.ScanData?.BodyID, Environment.NewLine); Point maxbeltpos = DrawNode(starcontrols, lastbelt, curmats, hl, Icons.Controls.Scan_Bodies_Belt, leftmiddle, false, out int unusedbeltcentre, beltsize, DrawLevel.PlanetLevel, appendlabeltext: appendlabel); leftmiddle = new Point(maxbeltpos.X + planetspacerx, leftmiddle.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; maxitemspos = new Point(Math.Max(maxitemspos.X, maxbeltpos.X), Math.Max(maxitemspos.Y, maxbeltpos.Y)); } //System.Diagnostics.Debug.WriteLine("Planet Node " + planetnode.ownname + " has scans " + nonedsmscans); if (planetnode.DoesNodeHaveNonEDSMScansBelow() || CheckEDSM) { List <ExtPictureBox.ImageElement> pc = new List <ExtPictureBox.ImageElement>(); bool habzone = false; if (ShowHabZone && planetnode.ScanData != null && !planetnode.ScanData.IsOrbitingBaryCentre && planetnode.ScanData.nSemiMajorAxis.HasValue) { double dist = planetnode.ScanData.nSemiMajorAxis.Value / JournalScan.oneLS_m; // m , converted to LS habzone = dist >= habzonestartls && dist <= habzoneendls; } Point maxplanetpos = CreatePlanetTree(pc, planetnode, curmats, hl, leftmiddle, filter, habzone, out int centreplanet); Point pcnt = new Point(centreplanet, leftmiddle.Y); if (maxplanetpos.X > panelStars.Width - panelStars.ScrollBarWidth) // uh oh too wide.. { int xoff = firstcolumn.X - leftmiddle.X; // shift to firstcolumn.x, maxitemspos.Y+planetspacer int yoff = (maxitemspos.Y + planetspacery) - (leftmiddle.Y - planetsize.Height / 2); RepositionTree(pc, xoff, yoff); // shift co-ords of all you've drawn - this will include any bary points drawn in moons pcnt.X += xoff; pcnt.Y += yoff; // need to account for planet centre maxplanetpos = new Point(maxplanetpos.X + xoff, maxplanetpos.Y + yoff); // remove the shift from maxpos leftmiddle = new Point(maxplanetpos.X + planetspacerx, leftmiddle.Y + yoff); // and set the curpos to maxpos.x + spacer, remove the shift from curpos.y } else { leftmiddle = new Point(maxplanetpos.X + planetspacerx, leftmiddle.Y); // shift current pos right, plus a spacer } maxitemspos = new Point(Math.Max(maxitemspos.X, maxplanetpos.X), Math.Max(maxitemspos.Y, maxplanetpos.Y)); starcontrols.AddRange(pc.ToArray()); planetcentres[planetnode] = pcnt; } } // do any futher belts after all planets while (displaybelts && lastbelt != null) { if (leftmiddle.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) // if too far across.. { leftmiddle = new Point(firstcolumn.X, maxitemspos.Y + planetspacery + planetsize.Height / 2); // move to left at maxy+space+h/2 } string appendlabel = ""; if (lastbelt.BeltData != null) { appendlabel = appendlabel.AppendPrePad($"{lastbelt.BeltData.OuterRad / JournalScan.oneLS_m:N1}ls", Environment.NewLine); } appendlabel = appendlabel.AppendPrePad("" + lastbelt.ScanData?.BodyID, Environment.NewLine); Point maxbeltpos = DrawNode(starcontrols, lastbelt, curmats, hl, Icons.Controls.Scan_Bodies_Belt, leftmiddle, false, out int unusedbelt2centre, beltsize, DrawLevel.PlanetLevel, appendlabeltext: appendlabel); leftmiddle = new Point(maxbeltpos.X + planetspacerx, leftmiddle.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; maxitemspos = new Point(Math.Max(maxitemspos.X, maxbeltpos.X), Math.Max(maxitemspos.Y, maxbeltpos.Y)); } maxitemspos = leftmiddle = new Point(leftmargin, maxitemspos.Y + starplanetgroupspacery + StarSize.Height / 2); // move back to left margin and move down to next position of star, allowing gap // make a tree of the planets with their barycentres from the Parents information var barynodes = StarScan.ScanNode.PopulateBarycentres(planetsinorder); // children always made, barynode tree StarScan.ScanNode.DumpTree(barynodes, "TOP", 0); List <ExtPictureBox.ImageElement> pcb = new List <ExtPictureBox.ImageElement>(); foreach (var k in barynodes.children) // for all barynodes.. display { DisplayBarynode(k.Value, 0, planetcentres, planetsinorder, pcb, planetsize.Height / 2); // done after the reposition so true positions set up. } starcontrols.InsertRange(0, pcb); // insert at start so drawn under } else { // no planets, so just move across and plot another one leftmiddle = new Point(maxitemspos.X + starfirstplanetspacerx, leftmiddle.Y); if (leftmiddle.X + StarSize.Width > panelStars.Width - panelStars.ScrollBarWidth) // if too far across.. { maxitemspos = leftmiddle = new Point(leftmargin, maxitemspos.Y + starplanetgroupspacery + StarSize.Height / 2); // move to left at maxy+space+h/2 } } DisplayAreaUsed = new Point(Math.Max(DisplayAreaUsed.X, maxitemspos.X), Math.Max(DisplayAreaUsed.Y, maxitemspos.Y)); } imagebox.AddRange(starcontrols); } imagebox.Render(); // replaces image.. }
const int baryspacingmargin = baryspacing * 4; // up to 4 bary lines.. Tuple <Point, int, int> DisplayBarynode(StarScan.ScanNode sn, int level, Dictionary <StarScan.ScanNode, Point> nodecentres, List <StarScan.ScanNode> nodes, List <ExtPictureBox.ImageElement> pc, int imagesize, bool horz = false) { if (sn.children == null) { return(new Tuple <Point, int, int>(Point.Empty, level, 0)); } var tojoin = new List <BaryPointInfo>(); int orderpos = 0; // this records the last planet order pos for use to pass back up the tree - helps in ordering foreach (var c in sn.children) { if (c.Value.type == StarScan.ScanNodeType.barycentre) // if a barycentre, draw it { var x = DisplayBarynode(c.Value, level + 1, nodecentres, nodes, pc, imagesize, horz); //System.Diagnostics.Debug.WriteLine(" ".Substring(0, level * 3) + level + " Draw bary " + c.Value.fullname + " " + x.Item1 + " " + level); if (horz) { tojoin.Add(new BaryPointInfo() { point = x.Item1, toppos = x.Item1, orderpos = x.Item3 }); // make a join point for a barynode } else { tojoin.Add(new BaryPointInfo() { point = x.Item1, toppos = x.Item1, orderpos = x.Item3 }); // make a join point for a barynode. Leave the toppos for later } } else { // Note if EDSM draw is turned off, but it was in the data from another source, we would not have drawn it so we need to check that by // seeing if the node has a nodecentre. No nodecentre, did not draw if (nodecentres.ContainsKey(c.Value)) { orderpos = nodes.IndexOf(c.Value); //System.Diagnostics.Debug.WriteLine(" ".Substring(0, level * 3) + level + " Draw Body " + c.Value.fullname + " " + orderpos + " " + nodecentres[c.Value]); if (horz) { tojoin.Add(new BaryPointInfo() { point = nodecentres[c.Value], toppos = new Point(nodecentres[c.Value].X - imagesize / 2, nodecentres[c.Value].Y), orderpos = orderpos }); } else { tojoin.Add(new BaryPointInfo() { point = nodecentres[c.Value], toppos = new Point(nodecentres[c.Value].X, nodecentres[c.Value].Y - 10 * imagesize / 8), orderpos = orderpos }); } } } } if (tojoin.Count > 1) // we need two or more to make a barynode line { tojoin.Sort(delegate(BaryPointInfo l, BaryPointInfo r) { return(l.orderpos.CompareTo(r.orderpos)); }); // make sure in order if (horz) { foreach (var c in tojoin) // find min y of cohort (same line) and set estimate pos to it { int minx = tojoin.Where(x => Math.Abs(x.toppos.X - c.toppos.X) < baryspacingmargin).Select(x => x.toppos.X).Min(); // find minx in cohort c.est = minx - baryspacing; // don't change toppos, we need it for other estimations. hold in another var } foreach (var c in tojoin) { c.toppos = new Point(c.est, c.toppos.Y); // apply calculated pos to toppos to align all barycentres to it } } else { foreach (var c in tojoin) // find min y of cohort (same line) and set estimate pos to it { int miny = tojoin.Where(y => Math.Abs(y.toppos.Y - c.toppos.Y) < baryspacingmargin).Select(x => x.toppos.Y).Min(); // find miny in cohort c.est = miny - baryspacing; // don't change toppos, we need it for other estimations. hold in another var } foreach (var c in tojoin) { c.toppos = new Point(c.toppos.X, c.est); // apply calculated pos to toppos to align all barycentres to it } } ExtPictureBox.ImageElement ie = new ExtPictureBox.ImageElement(); ie.OwnerDraw(DrawBaryTree, new Rectangle(0, 0, horz ? 1 : 0, 0), tojoin); // use Width, which does not get affected by repositiontree, to record if horz pc.Insert(0, ie); // insert first so drawn under //System.Diagnostics.Debug.Write(" ".Substring(0, level * 3) + level + " Join co-ords"); //for (int i = 0; i < tojoin.Count; i++) System.Diagnostics.Debug.Write(" " + tojoin[i].point + ":" + tojoin[i].toppos); Point pi; // calculate and return the barycentre position if (horz) { if (tojoin.Average(x => x.toppos.X) == tojoin[0].toppos.X) // if all on same line { pi = new Point(tojoin[0].toppos.X, (int)tojoin.Select(y => y.point.Y).Average()); //System.Diagnostics.Debug.Write(" same xline"); } else { pi = new Point(tojoin[0].toppos.X, tojoin[0].toppos.Y + imagesize); //System.Diagnostics.Debug.Write(" not same xline"); } } else { if (tojoin.Average(x => x.toppos.Y) == tojoin[0].toppos.Y) // if all on same line { pi = new Point((int)tojoin.Select(x => x.point.X).Average(), tojoin[0].toppos.Y); //System.Diagnostics.Debug.Write(" same yline"); } else { pi = new Point(tojoin[0].point.X + imagesize, tojoin[0].toppos.Y); // objects are not on same line, so we set the barypoint off to side a bit of the first //System.Diagnostics.Debug.Write(" not same yline"); } } //System.Diagnostics.Debug.WriteLine(" Pass back " + pi); //System.Diagnostics.Debug.WriteLine(""); return(new Tuple <Point, int, int>(pi, level, orderpos)); } else { return(new Tuple <Point, int, int>(Point.Empty, level, 0)); } }
// Width: Nodes are allowed 2 widths // Height: Nodes are allowed 1.5 Heights. 0 = top, 1/2/3/4 = image, 5 = bottom. // offset: pass in horizonal offset, return back middle of image // aligndown : if true, compensate for drawing normal size images and ones 1.5 by shifting down the image and the label by the right amounts // labelvoff : any additional compensation for label pos // return right bottom of area used from curpos Point DrawNode(List <PictureBoxHotspot.ImageElement> pc, StarScan.ScanNode sn, Image notscanned, Point curpos, Size size, ref int offset, bool aligndown = false, int labelvoff = 0) { string tip; Point endpoint = curpos; int quarterheight = size.Height / 4; int alignv = aligndown ? quarterheight : 0; JournalScan sc = sn.ScanData; //System.Diagnostics.Debug.WriteLine("Node " + sn.ownname + " " + curpos + " " + size + " hoff " + offset + " EDSM " + ((sc!= null) ? sc.IsEDSMBody.ToString() : "")); if (sc != null && (!sc.IsEDSMBody || checkBoxEDSM.Checked)) // if got one, and its our scan, or we are showing EDSM { tip = sc.DisplayString(); if (sc.IsStar) { endpoint = CreateImageLabel(pc, sc.GetStarTypeImage().Item1, new Point(curpos.X + offset, curpos.Y + alignv), // WE are basing it on a 1/4 + 1 + 1/4 grid, this is not being made bigger, move off size, sn.customname ?? sn.ownname, tip, alignv + labelvoff, sc.IsEDSMBody, false); // and the label needs to be a quarter height below it.. if (sc.HasRings) { curpos = new Point(endpoint.X + itemsepar.Width, curpos.Y); Point endbelt = curpos; for (int i = 0; i < sc.Rings.Length; i++) { string name = sc.Rings[i].Name; if (name.Length > sn.fullname.Length && name.Substring(0, sn.fullname.Length).Equals(sn.fullname)) { name = name.Substring(sn.fullname.Length).Trim(); } curpos.X += 4; // a little spacing, image is tight endbelt = CreateImageLabel(pc, EDDiscovery.Properties.Resources.Belt, new Point(curpos.X, curpos.Y + alignv), new Size(size.Width / 2, size.Height), name, sc.RingInformationMoons(i), alignv + labelvoff, sc.IsEDSMBody, false); curpos = new Point(endbelt.X + itemsepar.Width, curpos.Y); } endpoint = new Point(curpos.X, endpoint.Y); } offset += size.Width / 2; // return the middle used was this.. } else { bool indicatematerials = sc.HasMaterials && !checkBoxMaterials.Checked; Image nodeimage = sc.GetPlanetClassImage(); if ((sc.IsLandable || sc.HasRings || indicatematerials)) { Bitmap bmp = new Bitmap(size.Width * 2, quarterheight * 6); using (Graphics g = Graphics.FromImage(bmp)) { g.DrawImage(nodeimage, size.Width / 2, quarterheight, size.Width, size.Height); if (sc.IsLandable) { g.DrawImage(EDDiscovery.Properties.Resources.planet_landing, new Rectangle(quarterheight, 0, quarterheight * 6, quarterheight * 6)); } if (sc.HasRings) { g.DrawImage(sc.Rings.Count() > 1 ? EDDiscovery.Properties.Resources.RingGap512 : EDDiscovery.Properties.Resources.Ring_Only_512, new Rectangle(-2, quarterheight, size.Width * 2, size.Height)); } if (indicatematerials) { Image mm = EDDiscovery.Properties.Resources.materiamoreindicator; g.DrawImage(mm, new Rectangle(bmp.Width - mm.Width, bmp.Height - mm.Height, mm.Width, mm.Height)); } } endpoint = CreateImageLabel(pc, bmp, curpos, new Size(bmp.Width, bmp.Height), sn.customname ?? sn.ownname, tip, labelvoff, sc.IsEDSMBody); offset = size.Width; // return that the middle is now this } else { endpoint = CreateImageLabel(pc, nodeimage, new Point(curpos.X + offset, curpos.Y + alignv), size, sn.customname ?? sn.ownname, tip, alignv + labelvoff, sc.IsEDSMBody); offset += size.Width / 2; } if (sc.HasMaterials && checkBoxMaterials.Checked) { Point matpos = new Point(endpoint.X + 4, curpos.Y); Point endmat = CreateMaterialNodes(pc, sc, matpos, materialsize); endpoint = new Point(Math.Max(endpoint.X, endmat.X), Math.Max(endpoint.Y, endmat.Y)); // record new right point.. } } } else { if (sn.type == StarScan.ScanNodeType.barycentre) { tip = "Barycentre of " + sn.ownname; } else { tip = sn.ownname + "\n\nNo scan data available"; } endpoint = CreateImageLabel(pc, notscanned, new Point(curpos.X + offset, curpos.Y + alignv), size, sn.customname ?? sn.ownname, tip, alignv + labelvoff, false); offset += size.Width / 2; // return the middle used was this.. } return(endpoint); }
// return right bottom of area used from curpos Point DrawNode(List <PictureBoxHotspot.ImageElement> pc, StarScan.ScanNode sn, Image notscanned, Point curpos, Size size, ref int offset, bool alignhorz) { string tip; Point endpoint = curpos; int hoff = size.Height / 4; int alignhoff = (alignhorz) ? hoff : 0; JournalScan sc = sn.scandata; if (sc != null) { tip = sc.DisplayString(true); if (sc.IsStar) { endpoint = CreateImageLabel(pc, sc.GetStarTypeImage().Item1, new Point(curpos.X + offset, curpos.Y + alignhoff), size, sn.ownname, tip, alignhoff); if (sc.HasRings) { curpos = new Point(endpoint.X + itemsepar.Width, curpos.Y); Point endbelt = curpos; for (int i = 0; i < sc.Rings.Length; i++) { string name = sc.Rings[i].Name; if (name.Length > sn.fullname.Length && name.Substring(0, sn.fullname.Length).Equals(sn.fullname)) { name = name.Substring(sn.fullname.Length).Trim(); } curpos.X += 4; // a little spacing, image is tight endbelt = CreateImageLabel(pc, EDDiscovery.Properties.Resources.Belt, new Point(curpos.X, curpos.Y + alignhoff), new Size(size.Width / 2, size.Height), name, sc.RingInformationMoons(i), alignhoff); curpos = new Point(endbelt.X + itemsepar.Width, curpos.Y); } endpoint = new Point(curpos.X, endpoint.Y); } offset += size.Width / 2; // return the middle used was this.. } else { bool indicatematerials = sc.HasMaterials && !checkBoxMaterials.Checked; Image nodeimage = sc.GetPlanetClassImage(); if (sc.IsLandable || sc.HasRings || indicatematerials) { Bitmap bmp = new Bitmap(size.Width * 2, hoff * 6); using (Graphics g = Graphics.FromImage(bmp)) { g.DrawImage(nodeimage, size.Width / 2, hoff, size.Width, size.Height); if (sc.IsLandable) { g.DrawImage(EDDiscovery.Properties.Resources.planet_landing, new Rectangle(hoff, 0, hoff * 6, hoff * 6)); } if (sc.HasRings) { g.DrawImage(sc.Rings.Count() > 1 ? EDDiscovery.Properties.Resources.RingGap512 : EDDiscovery.Properties.Resources.Ring_Only_512, new Rectangle(-2, hoff, size.Width * 2, size.Height)); } if (indicatematerials) { Image mm = EDDiscovery.Properties.Resources.materiamoreindicator; g.DrawImage(mm, new Rectangle(bmp.Width - mm.Width, bmp.Height - mm.Height, mm.Width, mm.Height)); } } endpoint = CreateImageLabel(pc, bmp, curpos, new Size(bmp.Width, bmp.Height), sn.ownname, tip, 0); offset = size.Width; // return that the middle is now this } else { endpoint = CreateImageLabel(pc, nodeimage, new Point(curpos.X + offset, curpos.Y + alignhoff), size, sn.ownname, tip, alignhoff); offset += size.Width / 2; } if (sc.HasMaterials && checkBoxMaterials.Checked) { Point matpos = new Point(endpoint.X + 4, curpos.Y); Point endmat = CreateMaterialNodes(pc, sc, matpos, materialsize); endpoint = new Point(Math.Max(endpoint.X, endmat.X), Math.Max(endpoint.Y, endmat.Y)); // record new right point.. } } } else { if (sn.type == StarScan.ScanNodeType.barycentre) { tip = "Barycentre of " + sn.ownname; } else { tip = sn.ownname + "\n\nNo scan data available"; } endpoint = CreateImageLabel(pc, notscanned, new Point(curpos.X + offset, curpos.Y + alignhoff), size, sn.ownname, tip, alignhoff); offset += size.Width / 2; // return the middle used was this.. } return(endpoint); }
private string InfoLine(ISystem sys, StarScan.ScanNode sn, JournalScan js) { var information = new StringBuilder(); if (js.Mapped) { information.Append("\u2713"); // let the cmdr see that this body is already mapped - this is a check } string bodyname = js.BodyDesignationOrName.ReplaceIfStartsWith(sys.Name); // Name information.Append(bodyname); // Additional information information.Append((js.AmmoniaWorld) ? @" is an ammonia world.".T(EDTx.UserControlSurveyor_isanammoniaworld) : null); information.Append((js.Earthlike) ? @" is an earth like world.".T(EDTx.UserControlSurveyor_isanearthlikeworld) : null); information.Append((js.WaterWorld && !js.Terraformable) ? @" is a water world.".T(EDTx.UserControlSurveyor_isawaterworld) : null); information.Append((js.WaterWorld && js.Terraformable) ? @" is a terraformable water world.".T(EDTx.UserControlSurveyor_isaterraformablewaterworld) : null); information.Append((js.Terraformable && !js.WaterWorld) ? @" is a terraformable planet.".T(EDTx.UserControlSurveyor_isaterraformableplanet) : null); information.Append((js.HasRings) ? @" Has ring.".T(EDTx.UserControlSurveyor_Hasring) : null); information.Append((js.HasMeaningfulVolcanism) ? @" Has ".T(EDTx.UserControlSurveyor_Has) + js.Volcanism + "." : null); information.Append((js.nRadius < lowRadiusLimit) ? @" Low Radius.".T(EDTx.UserControlSurveyor_LowRadius) : null); information.Append((sn.Signals != null) ? " Has Signals.".T(EDTx.UserControlSurveyor_Signals) : null); information.Append((js.IsLandable) ? @" is landable.".T(EDTx.UserControlSurveyor_islandable) : null); var ev = js.GetEstimatedValues(); if (js.WasMapped == true && js.WasDiscovered == true) { information.Append(" (Mapped & Discovered)".T(EDTx.UserControlSurveyor_MandD)); if (showValuesToolStripMenuItem.Checked) { information.Append(' ').Append(ev.EstimatedValueBase.ToString("N0")).Append(" cr"); } } else if (js.WasMapped == true && js.WasDiscovered == false) { information.Append(" (Mapped)".T(EDTx.UserControlSurveyor_MP)); if (showValuesToolStripMenuItem.Checked) { information.Append(' ').Append(ev.EstimatedValueBase.ToString("N0")).Append(" cr"); } } else if (js.WasDiscovered == true && js.WasMapped == false) { information.Append(" (Discovered)".T(EDTx.UserControlSurveyor_DIS)); if (showValuesToolStripMenuItem.Checked) { information.Append(' ').Append(ev.EstimatedValueFirstMappedEfficiently.ToString("N0")).Append(" cr"); } } else { if (showValuesToolStripMenuItem.Checked) { information.Append(' ').Append((ev.EstimatedValueFirstDiscoveredFirstMappedEfficiently > 0 ? ev.EstimatedValueFirstDiscoveredFirstMappedEfficiently : ev.EstimatedValueBase).ToString("N0")).Append(" cr"); } } if (showMoreInformationToolStripMenuItem.Checked) { information.Append(' ').Append(js.ShortInformation()); } else { information.Append(' ').Append(js.DistanceFromArrivalText); } return(information.ToString()); }
// Width: Nodes are allowed 2 widths // Height: Nodes are allowed 1.5 Heights. 0 = top, 1/2/3/4 = image, 5 = bottom. // offset: pass in horizonal offset, return back middle of image // aligndown : if true, compensate for drawing normal size images and ones 1.5 by shifting down the image and the label by the right amounts // labelvoff : any additional compensation for label pos // return right bottom of area used from curpos // curmats may be null Point DrawNode(List <ExtPictureBox.ImageElement> pc, StarScan.ScanNode sn, MaterialCommoditiesList curmats, HistoryList hl, Image notscanned, Point curpos, Size size, ref int offset, bool aligndown = false, int labelvoff = 0, bool toplevel = false) { string tip; Point endpoint = curpos; int quarterheight = size.Height / 4; int alignv = aligndown ? quarterheight : 0; JournalScan sc = sn.ScanData; //System.Diagnostics.Debug.WriteLine("Node " + sn.ownname + " " + curpos + " " + size + " hoff " + offset + " EDSM " + ((sc!= null) ? sc.IsEDSMBody.ToString() : "")); if (sc != null && (!sc.IsEDSMBody || CheckEDSM)) // if got one, and its our scan, or we are showing EDSM { tip = sc.DisplayString(historicmatlist: curmats, currentmatlist: hl.GetLast?.MaterialCommodity); if (sn.type == StarScan.ScanNodeType.ring) { } else if (sc.IsStar && toplevel) { var starLabel = sn.customname ?? sn.ownname; var habZone = sc.GetHabZoneStringLs(); if (!string.IsNullOrEmpty(habZone)) { starLabel += $" ({habZone})"; } endpoint = CreateImageLabel(pc, sc.GetStarTypeImage(), new Point(curpos.X + offset, curpos.Y + alignv), // WE are basing it on a 1/4 + 1 + 1/4 grid, this is not being made bigger, move off size, starLabel, tip, alignv + labelvoff, sc.IsEDSMBody, false); // and the label needs to be a quarter height below it.. offset += size.Width / 2; // return the middle used was this.. } else //else not a top-level star { bool indicatematerials = sc.HasMaterials && !ShowMaterials; bool valuable = sc.EstimatedValue >= ValueLimit; Image nodeimage = sc.IsStar ? sc.GetStarTypeImage() : sc.GetPlanetClassImage(); if (ImageRequiresAnOverlay(sc, indicatematerials, valuable)) { Bitmap bmp = new Bitmap(size.Width * 2, quarterheight * 6); using (Graphics g = Graphics.FromImage(bmp)) { g.DrawImage(nodeimage, size.Width / 2, quarterheight, size.Width, size.Height); if (sc.IsLandable) { g.DrawImage(Icons.Controls.Scan_Bodies_Landable, new Rectangle(quarterheight, 0, quarterheight * 6, quarterheight * 6)); } if (sc.HasRings) { g.DrawImage(sc.Rings.Count() > 1 ? Icons.Controls.Scan_Bodies_RingGap : Icons.Controls.Scan_Bodies_RingOnly, new Rectangle(-2, quarterheight, size.Width * 2, size.Height)); } if (ShowOverlays) { int overlaystotal = (sc.Terraformable ? 1 : 0) + (sc.HasMeaningfulVolcanism ? 1 : 0) + (valuable ? 1 : 0) + (sc.Mapped ? 1 : 0); int ovsize = (overlaystotal > 1) ? quarterheight : (quarterheight * 3 / 2); int pos = 0; if (sc.Terraformable) { g.DrawImage(Icons.Controls.Scan_Bodies_Terraformable, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (sc.HasMeaningfulVolcanism) //this renders below the terraformable icon if present { g.DrawImage(Icons.Controls.Scan_Bodies_Volcanism, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (valuable) { g.DrawImage(Icons.Controls.Scan_Bodies_HighValue, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (sc.Mapped) { g.DrawImage(Icons.Controls.Scan_Bodies_Mapped, new Rectangle(0, pos, ovsize, ovsize)); } } if (indicatematerials) { Image mm = Icons.Controls.Scan_Bodies_MaterialMore; g.DrawImage(mm, new Rectangle(bmp.Width - mm.Width, bmp.Height - mm.Height, mm.Width, mm.Height)); } } var nodeLabel = sn.customname ?? sn.ownname; if (sn.ScanData.IsLandable && sn.ScanData.nSurfaceGravity != null) { nodeLabel += $" ({(sn.ScanData.nSurfaceGravity / JournalScan.oneGee_m_s2):N2}g)"; } endpoint = CreateImageLabel(pc, bmp, curpos, new Size(bmp.Width, bmp.Height), nodeLabel, tip, labelvoff, sc.IsEDSMBody); offset = size.Width; // return that the middle is now this } else { endpoint = CreateImageLabel(pc, nodeimage, new Point(curpos.X + offset, curpos.Y + alignv), size, sn.customname ?? sn.ownname, tip, alignv + labelvoff, sc.IsEDSMBody, false); offset += size.Width / 2; } if (sc.HasMaterials && ShowMaterials) { Point matpos = new Point(endpoint.X + 4, curpos.Y); Point endmat = CreateMaterialNodes(pc, sc, curmats, hl, matpos, materialsize); endpoint = new Point(Math.Max(endpoint.X, endmat.X), Math.Max(endpoint.Y, endmat.Y)); // record new right point.. } } } else if (sn.type == StarScan.ScanNodeType.belt) { if (sn.BeltData != null) { tip = sn.BeltData.RingInformationMoons(true); } else { tip = sn.ownname + Environment.NewLine + Environment.NewLine + "No scan data available".T(EDTx.ScanDisplayUserControl_NSD); } if (sn.children != null && sn.children.Count != 0) { foreach (StarScan.ScanNode snc in sn.children.Values) { if (snc.ScanData != null) { tip += "\n\n" + snc.ScanData.DisplayString(); } } } endpoint = CreateImageLabel(pc, Icons.Controls.Scan_Bodies_Belt, new Point(curpos.X, curpos.Y + alignv), new Size(size.Width, size.Height), sn.ownname, tip, alignv + labelvoff, false, false); offset += size.Width; } else { if (sn.type == StarScan.ScanNodeType.barycentre) { tip = string.Format("Barycentre of {0}".T(EDTx.ScanDisplayUserControl_BC), sn.ownname); } else { tip = sn.ownname + Environment.NewLine + Environment.NewLine + "No scan data available".T(EDTx.ScanDisplayUserControl_NSD); } endpoint = CreateImageLabel(pc, notscanned, new Point(curpos.X + offset, curpos.Y + alignv), size, sn.customname ?? sn.ownname, tip, alignv + labelvoff, false, false); offset += size.Width / 2; // return the middle used was this.. } return(endpoint); }
// return right bottom of area used from curpos Point CreatePlanetTree(List <ExtPictureBox.ImageElement> pc, StarScan.ScanNode planetnode, MaterialCommoditiesList curmats, HistoryList hl, Point curpos, string[] filter) { // PLANETWIDTH|PLANETWIDTH (if drawing a full planet with rings/landing) // or // MOONWIDTH|MOONWIDTH (if drawing a single width planet) // this offset, ONLY used if a single width planet, allows for two moons int offset = moonsize.Width - planetsize.Width / 2; // centre is moon width, back off by planetwidth/2 to place the left edge of the planet Point maxtreepos = DrawNode(pc, planetnode, curmats, hl, JournalScan.GetPlanetImageNotScanned(), curpos, planetsize, ref offset, true); // offset passes in the suggested offset, returns the centre offset if (planetnode.children != null && ShowMoons) { offset -= moonsize.Width; // offset is centre of planet image, back off by a moon width to allow for 2 moon widths centred Point moonpos = new Point(curpos.X + offset, maxtreepos.Y + moonspacery); // moon pos foreach (StarScan.ScanNode moonnode in planetnode.children.Values.Where(n => n.type != StarScan.ScanNodeType.barycentre)) { if (filter != null && moonnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { continue; } bool nonedsmscans = moonnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? if (nonedsmscans || CheckEDSM) { int offsetm = moonsize.Width / 2; // pass in normal offset if not double width item (half moon from moonpos.x) Point mmax = DrawNode(pc, moonnode, curmats, hl, JournalScan.GetMoonImageNotScanned(), moonpos, moonsize, ref offsetm); maxtreepos = new Point(Math.Max(maxtreepos.X, mmax.X), Math.Max(maxtreepos.Y, mmax.Y)); if (moonnode.children != null) { Point submoonpos; if (mmax.X <= moonpos.X + moonsize.Width * 2) // if we have nothing wider than the 2 moon widths, we can go with it right aligned { submoonpos = new Point(moonpos.X + moonsize.Width * 2 + moonspacerx, moonpos.Y); // moon pos } else { submoonpos = new Point(moonpos.X + moonsize.Width * 2 + moonspacerx, mmax.Y + moonspacery); // moon pos below and right } foreach (StarScan.ScanNode submoonnode in moonnode.children.Values) { if (filter != null && submoonnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { continue; } bool nonedsmsubmoonscans = submoonnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? if (nonedsmsubmoonscans || CheckEDSM) { int offsetsm = moonsize.Width / 2; // pass in normal offset if not double width item (half moon from moonpos.x) Point sbmax = DrawNode(pc, submoonnode, curmats, hl, JournalScan.GetMoonImageNotScanned(), submoonpos, moonsize, ref offsetsm); maxtreepos = new Point(Math.Max(maxtreepos.X, sbmax.X), Math.Max(maxtreepos.Y, sbmax.Y)); submoonpos = new Point(submoonpos.X, maxtreepos.Y + moonspacery); } } } moonpos = new Point(moonpos.X, maxtreepos.Y + moonspacery); } } } return(maxtreepos); }
// draw scannode (may be null), // curmats may be null public void DrawSystem(StarScan.SystemNode scannode, MaterialCommoditiesList curmats, HistoryList hl, string opttext = null, string[] filter = null) { HideInfo(); imagebox.ClearImageList(); // does not clear the image, render will do that if (scannode != null) { Point curpos = new Point(leftmargin, topmargin); if (opttext != null) { ExtPictureBox.ImageElement lab = new ExtPictureBox.ImageElement(); lab.TextAutosize(curpos, new Size(500, 30), opttext, largerfont, EDDTheme.Instance.LabelColor, this.BackColor); imagebox.Add(lab); curpos.Y += lab.img.Height + 8; } DisplayAreaUsed = curpos; List <ExtPictureBox.ImageElement> starcontrols = new List <ExtPictureBox.ImageElement>(); bool displaybelts = filter == null || (filter.Contains("belt") || filter.Contains("All")); //for( int i = 0; i < 1000; i +=100) CreateStarPlanet(starcontrols, EDDiscovery.Properties.Resources.ImageStarDiscWhite, new Point(i, 0), new Size(24, 24), i.ToString(), ""); //foreach( var sn in scannode.Bodies ) //{ // System.Diagnostics.Debug.Write("Node " + sn.type + " " + sn.fullname); // if ( sn.ScanData != null ) // { // System.Diagnostics.Debug.Write(" " + sn.ScanData.IsStar + " P:" + sn.ScanData.PlanetTypeID + " S:" + sn.ScanData.StarTypeID + " EDSM:" + sn.ScanData.IsEDSMBody); // } // System.Diagnostics.Debug.WriteLine(""); //} foreach (StarScan.ScanNode starnode in scannode.starnodes.Values) // always has scan nodes { if (filter != null && starnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { System.Diagnostics.Debug.WriteLine("SDUC Rejected " + starnode.fullname); continue; } // Draw star int offset = 0; Point maxstarpos = DrawNode(starcontrols, starnode, curmats, hl, (starnode.type == StarScan.ScanNodeType.barycentre) ? Icons.Controls.Scan_Bodies_Barycentre : JournalScan.GetStarImageNotScanned(), curpos, StarSize, ref offset, false, (planetsize.Height * 6 / 4 - StarSize.Height) / 2, true); // the last part nerfs the label down to the right position Point maxitemspos = maxstarpos; curpos = new Point(maxitemspos.X + starfirstplanetspacerx, curpos.Y); // move to the right curpos.Y += StarSize.Height / 2 - planetsize.Height * 3 / 4; // slide down for planet vs star difference in size Point firstcolumn = curpos; if (starnode.children != null) { Queue <StarScan.ScanNode> belts = null; if (starnode.ScanData != null && (!starnode.ScanData.IsEDSMBody || CheckEDSM)) { belts = new Queue <StarScan.ScanNode>(starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.belt)); } else { belts = new Queue <StarScan.ScanNode>(); } StarScan.ScanNode lastbelt = belts.Count != 0 ? belts.Dequeue() : null; // process body and stars only foreach (StarScan.ScanNode planetnode in starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.body || s.type == StarScan.ScanNodeType.star)) { if (filter != null && planetnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { System.Diagnostics.Debug.WriteLine("SDUC Rejected " + planetnode.fullname); continue; } //System.Diagnostics.Debug.WriteLine("Draw " + planetnode.ownname + ":" + planetnode.type); // if belt is before this, display belts here while (displaybelts && lastbelt != null && planetnode.ScanData != null && (lastbelt.BeltData == null || lastbelt.BeltData.OuterRad < planetnode.ScanData.nSemiMajorAxis)) { //System.Diagnostics.Debug.WriteLine("Draw a belt " + lastbelt.ownname); // if too far across, go back to star if (curpos.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) { curpos = new Point(firstcolumn.X, maxitemspos.Y + planetsize.Height + planetspacery); } Point used = DrawNode(starcontrols, lastbelt, curmats, hl, Icons.Controls.Scan_Bodies_Belt, new Point(curpos.X + (planetsize.Width - beltsize.Width) / 2, curpos.Y), beltsize, ref offset, false); curpos = new Point(used.X, curpos.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; } bool nonedsmscans = planetnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? //System.Diagnostics.Debug.WriteLine("Planet Node " + planetnode.ownname + " has scans " + nonedsmscans); if (nonedsmscans || CheckEDSM) { List <ExtPictureBox.ImageElement> pc = new List <ExtPictureBox.ImageElement>(); Point maxpos = CreatePlanetTree(pc, planetnode, curmats, hl, curpos, filter); //System.Diagnostics.Debug.WriteLine("Planet " + planetnode.ownname + " " + curpos + " " + maxpos + " max " + (panelStars.Width - panelStars.ScrollBarWidth)); if (maxpos.X > panelStars.Width - panelStars.ScrollBarWidth) // uh oh too wide.. { int xoffset = firstcolumn.X - curpos.X; // shift to firstcolumn.x, maxitemspos.Y+planetspacer int yoffset = (maxitemspos.Y + planetspacery) - curpos.Y; RepositionTree(pc, xoffset, yoffset); // shift co-ords of all you've drawn maxpos = new Point(maxpos.X + xoffset, maxpos.Y + yoffset); // remove the shift from maxpos curpos = new Point(maxpos.X + planetspacerx, curpos.Y + yoffset); // and set the curpos to maxpos.x + spacer, remove the shift from curpos.y } else { curpos = new Point(maxpos.X + planetspacerx, curpos.Y); // shift current pos right, plus a spacer } maxitemspos = new Point(Math.Max(maxitemspos.X, maxpos.X), Math.Max(maxitemspos.Y, maxpos.Y)); starcontrols.AddRange(pc.ToArray()); } } // do any futher belts after all planets while (displaybelts && lastbelt != null) { if (curpos.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) { curpos = new Point(firstcolumn.X, maxitemspos.Y + planetsize.Height); } Point used = DrawNode(starcontrols, lastbelt, curmats, hl, Icons.Controls.Scan_Bodies_Belt, new Point(curpos.X + (planetsize.Width - beltsize.Width) / 2, curpos.Y), beltsize, ref offset, false); curpos = new Point(used.X, curpos.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; } } DisplayAreaUsed = new Point(Math.Max(DisplayAreaUsed.X, maxitemspos.X), Math.Max(DisplayAreaUsed.Y, maxitemspos.Y)); curpos = new Point(leftmargin, maxitemspos.Y + starplanetgroupspacery); // move back to left margin and move down to next position of star, allowing gap } imagebox.AddRange(starcontrols); } imagebox.Render(); // replaces image.. }
void DrawSystem() // draw last_sn, last_he { HideInfo(); imagebox.ClearImageList(); // does not clear the image, render will do that if (last_he == null) { SetControlText("No System"); imagebox.Render(); return; } StarScan.SystemNode last_sn = discoveryform.history.starscan.FindSystem(last_he.System, checkBoxEDSM.Checked); SetControlText((last_sn == null) ? "No Scan" : last_sn.system.name); if (last_sn != null) // { Point curpos = new Point(leftmargin, topmargin); last_maxdisplayarea = curpos; List <PictureBoxHotspot.ImageElement> starcontrols = new List <PictureBoxHotspot.ImageElement>(); //for( int i = 0; i < 1000; i +=100) CreateStarPlanet(starcontrols, EDDiscovery.Properties.Resources.ImageStarDiscWhite, new Point(i, 0), new Size(24, 24), i.ToString(), ""); foreach (StarScan.ScanNode starnode in last_sn.starnodes.Values) // always has scan nodes { int offset = 0; Point maxstarpos = DrawNode(starcontrols, starnode, (starnode.type == StarScan.ScanNodeType.barycentre) ? EDDiscovery.Properties.Resources.Barycentre : JournalScan.GetStarImageNotScanned(), curpos, starsize, ref offset, false, (planetsize.Height * 6 / 4 - starsize.Height) / 2, true); // the last part nerfs the label down to the right position Point maxitemspos = maxstarpos; curpos = new Point(maxitemspos.X + itemsepar.Width, curpos.Y); // move to the right curpos.Y += starsize.Height / 2 - planetsize.Height * 3 / 4; // slide down for planet vs star difference in size Point firstcolumn = curpos; if (starnode.children != null) { Queue <StarScan.ScanNode> belts = null; if (starnode.ScanData != null && (!starnode.ScanData.IsEDSMBody || checkBoxEDSM.Checked)) { belts = new Queue <StarScan.ScanNode>(starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.belt)); } else { belts = new Queue <StarScan.ScanNode>(); } StarScan.ScanNode lastbelt = belts.Count != 0 ? belts.Dequeue() : null; foreach (StarScan.ScanNode planetnode in starnode.children.Values.Where(s => s.type != StarScan.ScanNodeType.belt)) { while (lastbelt != null && planetnode.ScanData != null && (lastbelt.BeltData == null || lastbelt.BeltData.OuterRad < planetnode.ScanData.nSemiMajorAxis)) { if (curpos.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) { curpos = new Point(firstcolumn.X, maxitemspos.Y + planetsize.Height); } DrawNode(starcontrols, lastbelt, EDDiscovery.Properties.Resources.Belt, new Point(curpos.X + (planetsize.Width - beltsize.Width) / 2, curpos.Y), beltsize, ref offset, false); curpos = new Point(curpos.X + planetsize.Width, curpos.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; } bool nonedsmscans = planetnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? //System.Diagnostics.Debug.WriteLine("Planet Node " + planetnode.ownname + " has scans " + nonedsmscans); if (nonedsmscans || checkBoxEDSM.Checked) { List <PictureBoxHotspot.ImageElement> pc = new List <PictureBoxHotspot.ImageElement>(); Point maxpos = CreatePlanetTree(pc, planetnode, curpos); //System.Diagnostics.Debug.WriteLine("Planet " + planetnode.ownname + " " + curpos + " " + maxpos + " max " + (panelStars.Width - panelStars.ScrollBarWidth)); if (maxpos.X > panelStars.Width - panelStars.ScrollBarWidth) // uh oh too wide.. { int xoffset = firstcolumn.X - curpos.X; int yoffset = maxitemspos.Y - curpos.Y; RepositionTree(pc, xoffset, yoffset); // shift co-ords of all you've drawn maxpos = new Point(maxpos.X + xoffset, maxpos.Y + yoffset); curpos = new Point(maxpos.X, curpos.Y + yoffset); } else { curpos = new Point(maxpos.X, curpos.Y); } maxitemspos = new Point(Math.Max(maxitemspos.X, maxpos.X), Math.Max(maxitemspos.Y, maxpos.Y)); starcontrols.AddRange(pc.ToArray()); } } while (lastbelt != null) { if (curpos.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) { curpos = new Point(firstcolumn.X, maxitemspos.Y + planetsize.Height); } DrawNode(starcontrols, lastbelt, EDDiscovery.Properties.Resources.Belt, new Point(curpos.X + (planetsize.Width - beltsize.Width) / 2, curpos.Y), beltsize, ref offset, false); curpos = new Point(curpos.X + planetsize.Width, curpos.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; } } last_maxdisplayarea = new Point(Math.Max(last_maxdisplayarea.X, maxitemspos.X), Math.Max(last_maxdisplayarea.Y, maxitemspos.Y)); curpos = new Point(leftmargin, maxitemspos.Y + itemsepar.Height); } imagebox.AddRange(starcontrols); } imagebox.Render(); // replaces image.. }
public void DrawSystem(StarScan.SystemNode last_sn, MaterialCommoditiesList curmats, HistoryList hl, string opttext = null) // draw showing_system (may be null), showing_matcomds (may be null) { HideInfo(); imagebox.ClearImageList(); // does not clear the image, render will do that if (last_sn != null) { Point curpos = new Point(leftmargin, topmargin); if (opttext != null) { ExtPictureBox.ImageElement lab = new ExtPictureBox.ImageElement(); lab.TextAutosize(curpos, new Size(500, 30), opttext, largerfont, EDDTheme.Instance.LabelColor, this.BackColor); imagebox.Add(lab); curpos.Y += lab.img.Height + 8; } DisplayAreaUsed = curpos; List <ExtPictureBox.ImageElement> starcontrols = new List <ExtPictureBox.ImageElement>(); //for( int i = 0; i < 1000; i +=100) CreateStarPlanet(starcontrols, EDDiscovery.Properties.Resources.ImageStarDiscWhite, new Point(i, 0), new Size(24, 24), i.ToString(), ""); foreach (StarScan.ScanNode starnode in last_sn.starnodes.Values) // always has scan nodes { //System.Diagnostics.Debug.WriteLine("Draw " + starnode.type); int offset = 0; Point maxstarpos = DrawNode(starcontrols, starnode, curmats, hl, (starnode.type == StarScan.ScanNodeType.barycentre) ? Icons.Controls.Scan_Bodies_Barycentre : JournalScan.GetStarImageNotScanned(), curpos, StarSize, ref offset, false, (planetsize.Height * 6 / 4 - StarSize.Height) / 2, true); // the last part nerfs the label down to the right position Point maxitemspos = maxstarpos; curpos = new Point(maxitemspos.X + itemsepar.Width, curpos.Y); // move to the right curpos.Y += StarSize.Height / 2 - planetsize.Height * 3 / 4; // slide down for planet vs star difference in size Point firstcolumn = curpos; if (starnode.children != null) { Queue <StarScan.ScanNode> belts = null; if (starnode.ScanData != null && (!starnode.ScanData.IsEDSMBody || CheckEDSM)) { belts = new Queue <StarScan.ScanNode>(starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.belt)); } else { belts = new Queue <StarScan.ScanNode>(); } StarScan.ScanNode lastbelt = belts.Count != 0 ? belts.Dequeue() : null; foreach (StarScan.ScanNode planetnode in starnode.children.Values.Where(s => s.type == StarScan.ScanNodeType.body || s.type == StarScan.ScanNodeType.star)) { // System.Diagnostics.Debug.WriteLine("Draw " + planetnode.type); while (lastbelt != null && planetnode.ScanData != null && (lastbelt.BeltData == null || lastbelt.BeltData.OuterRad < planetnode.ScanData.nSemiMajorAxis)) { if (curpos.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) { curpos = new Point(firstcolumn.X, maxitemspos.Y + planetsize.Height); } DrawNode(starcontrols, lastbelt, curmats, hl, Icons.Controls.Scan_Bodies_Belt, new Point(curpos.X + (planetsize.Width - beltsize.Width) / 2, curpos.Y), beltsize, ref offset, false); curpos = new Point(curpos.X + planetsize.Width, curpos.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; } bool nonedsmscans = planetnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? //System.Diagnostics.Debug.WriteLine("Planet Node " + planetnode.ownname + " has scans " + nonedsmscans); if (nonedsmscans || CheckEDSM) { List <ExtPictureBox.ImageElement> pc = new List <ExtPictureBox.ImageElement>(); Point maxpos = CreatePlanetTree(pc, planetnode, curmats, hl, curpos); //System.Diagnostics.Debug.WriteLine("Planet " + planetnode.ownname + " " + curpos + " " + maxpos + " max " + (panelStars.Width - panelStars.ScrollBarWidth)); if (maxpos.X > panelStars.Width - panelStars.ScrollBarWidth) // uh oh too wide.. { int xoffset = firstcolumn.X - curpos.X; int yoffset = maxitemspos.Y - curpos.Y; RepositionTree(pc, xoffset, yoffset); // shift co-ords of all you've drawn maxpos = new Point(maxpos.X + xoffset, maxpos.Y + yoffset); curpos = new Point(maxpos.X, curpos.Y + yoffset); } else { curpos = new Point(maxpos.X, curpos.Y); } maxitemspos = new Point(Math.Max(maxitemspos.X, maxpos.X), Math.Max(maxitemspos.Y, maxpos.Y)); starcontrols.AddRange(pc.ToArray()); } } while (lastbelt != null) { if (curpos.X + planetsize.Width > panelStars.Width - panelStars.ScrollBarWidth) { curpos = new Point(firstcolumn.X, maxitemspos.Y + planetsize.Height); } DrawNode(starcontrols, lastbelt, curmats, hl, Icons.Controls.Scan_Bodies_Belt, new Point(curpos.X + (planetsize.Width - beltsize.Width) / 2, curpos.Y), beltsize, ref offset, false); curpos = new Point(curpos.X + planetsize.Width, curpos.Y); lastbelt = belts.Count != 0 ? belts.Dequeue() : null; } } DisplayAreaUsed = new Point(Math.Max(DisplayAreaUsed.X, maxitemspos.X), Math.Max(DisplayAreaUsed.Y, maxitemspos.Y)); curpos = new Point(leftmargin, maxitemspos.Y + itemsepar.Height); } imagebox.AddRange(starcontrols); } imagebox.Render(); // replaces image.. }
// return right bottom of area used from curpos Point CreatePlanetTree(List <ExtPictureBox.ImageElement> pc, StarScan.ScanNode planetnode, MaterialCommoditiesList curmats, HistoryList hl, Point leftmiddle, string[] filter, bool habzone, out int planetcentre) { Color?backwash = null; if (habzone) { backwash = Color.FromArgb(64, 0, 128, 0); // transparent in case we have a non black background } Point maxtreepos = DrawNode(pc, planetnode, curmats, hl, (planetnode.type == StarScan.ScanNodeType.barycentre) ? Icons.Controls.Scan_Bodies_Barycentre : JournalScan.GetPlanetImageNotScanned(), leftmiddle, false, out planetcentre, planetsize, DrawLevel.PlanetLevel, backwash: backwash); // offset passes in the suggested offset, returns the centre offset if (planetnode.children != null && ShowMoons) { Point moonposcentremid = new Point(planetcentre, maxtreepos.Y + moonspacery + moonsize.Height / 2); // moon pos, below planet, centre x coord var moonnodes = planetnode.children.Values.Where(n => n.type != StarScan.ScanNodeType.barycentre).ToList(); var mooncentres = new Dictionary <StarScan.ScanNode, Point>(); for (int mn = 0; mn < moonnodes.Count; mn++) { StarScan.ScanNode moonnode = moonnodes[mn]; if (filter != null && moonnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { continue; } bool nonedsmscans = moonnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? if (nonedsmscans || CheckEDSM) { Point mmax = DrawNode(pc, moonnode, curmats, hl, (moonnode.type == StarScan.ScanNodeType.barycentre) ? Icons.Controls.Scan_Bodies_Barycentre : JournalScan.GetMoonImageNotScanned(), moonposcentremid, true, out int mooncentre, moonsize, DrawLevel.MoonLevel); maxtreepos = new Point(Math.Max(maxtreepos.X, mmax.X), Math.Max(maxtreepos.Y, mmax.Y)); if (moonnode.children != null) { Point submoonpos = new Point(mmax.X + moonspacerx, moonposcentremid.Y); // first its left mid bool xiscentre = false; foreach (StarScan.ScanNode submoonnode in moonnode.children.Values) { if (filter != null && submoonnode.IsBodyInFilter(filter, true) == false) // if filter active, but no body or children in filter { continue; } bool nonedsmsubmoonscans = submoonnode.DoesNodeHaveNonEDSMScansBelow(); // is there any scans here, either at this node or below? if (nonedsmsubmoonscans || CheckEDSM) { Point sbmax = DrawNode(pc, submoonnode, curmats, hl, (moonnode.type == StarScan.ScanNodeType.barycentre) ? Icons.Controls.Scan_Bodies_Barycentre : JournalScan.GetMoonImageNotScanned(), submoonpos, xiscentre, out int xsubmooncentre, moonsize, DrawLevel.MoonLevel); if (xiscentre) { submoonpos = new Point(submoonpos.X, sbmax.Y + moonspacery + moonsize.Height / 2); } else { submoonpos = new Point(xsubmooncentre, sbmax.Y + moonspacery + moonsize.Height / 2); xiscentre = true; // now go to centre placing } maxtreepos = new Point(Math.Max(maxtreepos.X, sbmax.X), Math.Max(maxtreepos.Y, sbmax.Y)); } } } mooncentres[moonnode] = new Point(mooncentre, moonposcentremid.Y); moonposcentremid = new Point(moonposcentremid.X, maxtreepos.Y + moonspacery + moonsize.Height / 2); //System.Diagnostics.Debug.WriteLine("Next moon centre at " + moonposcentremid ); } } //// now, taking the moon modes, create a barycentre tree with those inserted in var barynodes = StarScan.ScanNode.PopulateBarycentres(moonnodes); // children always made, barynode tree foreach (var k in barynodes.children) // for all barynodes.. display { DisplayBarynode(k.Value, 0, mooncentres, moonnodes, pc, moonsize.Width * 5 / 4, true); } } return(maxtreepos); }
static private string InfoLine(ISystem sys, StarScan.ScanNode sn, JournalScan js, bool volcanism, bool showvalues, bool shortinfo, bool showGravity) { var information = new StringBuilder(); if (js.Mapped) { information.Append("\u2713"); // let the cmdr see that this body is already mapped - this is a check } string bodyname = js.BodyDesignationOrName.ReplaceIfStartsWith(sys.Name); // Name information.Append((bodyname) + @" is a ".T(EDTx.UserControlSurveyor_isa)); // Additional information information.Append((js.IsStar) ? Bodies.StarName(js.StarTypeID) + "." : null); information.Append((js.CanBeTerraformable) ? @"terraformable ".T(EDTx.UserControlSurveyor_terraformable) : null); information.Append((js.IsPlanet) ? Bodies.PlanetTypeName(js.PlanetTypeID) + "." : null); information.Append((js.nRadius < lowRadiusLimit && js.IsPlanet) ? @" Is tiny.".T(EDTx.UserControlSurveyor_LowRadius) : null); information.Append((js.nRadius > largeRadiusLimit && js.IsPlanet && js.IsLandable) ? @" Is large.".T(EDTx.UserControlSurveyor_LargeRadius) : null); information.Append((js.IsLandable) ? @" Is landable.".T(EDTx.UserControlSurveyor_islandable) : null); information.Append((js.IsLandable && showGravity && js.nSurfaceGravityG.HasValue) ? @" (" + Math.Round(js.nSurfaceGravityG.Value, 2, MidpointRounding.AwayFromZero) + "g)" : null); information.Append((js.HasAtmosphericComposition && js.IsLandable) ? @" Atmosphere: ".T(EDTx.UserControlSurveyor_Atmosphere) + (js.Atmosphere ?? "unknown atmosphere".T(EDTx.UserControlSurveyor_unknownAtmosphere)) + "." : null); information.Append((js.HasMeaningfulVolcanism && js.IsLandable | volcanism) ? @" Has ".T(EDTx.UserControlSurveyor_Has) + js.Volcanism + "." : null); information.Append((sn.Signals != null) ? " Has signals.".T(EDTx.UserControlSurveyor_Signals) : null); information.Append((js.HasRings) ? @" Is ringed.".T(EDTx.UserControlSurveyor_Hasring) : null); information.Append((js.nEccentricity >= eccentricityLimit) ? @" Has an high eccentricity of ".T(EDTx.UserControlSurveyor_eccentricity) + js.nEccentricity + "." : null); var ev = js.GetEstimatedValues(); if (js.WasMapped == true && js.WasDiscovered == true) { information.Append(" (Mapped & Discovered)".T(EDTx.UserControlSurveyor_MandD)); if (showvalues) { information.Append(' ').Append(ev.EstimatedValueMappedEfficiently.ToString("N0")).Append(" cr"); } } else if (js.WasMapped == true && js.WasDiscovered == false) { information.Append(" (Mapped)".T(EDTx.UserControlSurveyor_MP)); if (showvalues) { information.Append(' ').Append(ev.EstimatedValueFirstMappedEfficiently.ToString("N0")).Append(" cr"); } } else if (js.WasDiscovered == true && js.WasMapped == false) { information.Append(" (Discovered)".T(EDTx.UserControlSurveyor_DIS)); if (showvalues) { information.Append(' ').Append(ev.EstimatedValueFirstMappedEfficiently.ToString("N0")).Append(" cr"); } } else { if (showvalues) { information.Append(' ').Append((ev.EstimatedValueFirstDiscoveredFirstMappedEfficiently > 0 ? ev.EstimatedValueFirstDiscoveredFirstMappedEfficiently : ev.EstimatedValueBase).ToString("N0")).Append(" cr"); } } if (shortinfo) { information.Append(' ').Append(js.ShortInformation()); } else { information.Append(' ').Append(js.DistanceFromArrivalText); } return(information.ToString()); }
Dictionary <Bitmap, float> imageintensities = new Dictionary <Bitmap, float>(); // cached // return right bottom of area used from curpos Point DrawNode(List <ExtPictureBox.ImageElement> pc, StarScan.ScanNode sn, MaterialCommoditiesList curmats, // curmats may be null HistoryList hl, Image notscanned, // image if sn is not known Point position, // position is normally left/middle, unless xiscentre is set. bool xiscentre, out Rectangle imagepos, Size size, // nominal size DrawLevel drawtype, // drawing.. Color?backwash = null, // optional back wash on image string appendlabeltext = "" // any label text to append ) { string tip; Point endpoint = position; imagepos = Rectangle.Empty; JournalScan sc = sn.ScanData; if (sc != null && (!sc.IsEDSMBody || CheckEDSM)) // has a scan and its our scan, or we are showing EDSM { if (sn.NodeType != StarScan.ScanNodeType.ring) // not rings { tip = sc.DisplayString(historicmatlist: curmats, currentmatlist: hl.GetLast?.MaterialCommodity); if (sn.Signals != null) { tip += "\n" + "Signals".T(EDTx.ScanDisplayUserControl_Signals) + ":\n" + JournalSAASignalsFound.SignalList(sn.Signals, 4, "\n"); } Bitmap nodeimage = (Bitmap)(sc.IsStar ? sc.GetStarTypeImage() : sc.GetPlanetClassImage()); string overlaytext = ""; var nodelabels = new string[2] { "", "" }; nodelabels[0] = sn.CustomNameOrOwnname; if (sc.IsEDSMBody) { nodelabels[0] = "_" + nodelabels[0]; } if (sc.IsStar) { if (ShowStarClasses) { overlaytext = sc.StarClassificationAbv; } if (sc.nStellarMass.HasValue) { nodelabels[1] = nodelabels[1].AppendPrePad($"{sc.nStellarMass.Value:N2} SM", Environment.NewLine); } if (drawtype == DrawLevel.TopLevelStar) { if (sc.nAge.HasValue) { nodelabels[1] = nodelabels[1].AppendPrePad($"{sc.nAge.Value:N0} MY", Environment.NewLine); } if (ShowHabZone) { var habZone = sc.GetHabZoneStringLs(); if (habZone.HasChars()) { nodelabels[1] = nodelabels[1].AppendPrePad($"{habZone}", Environment.NewLine); } } } } else { if (ShowPlanetClasses) { overlaytext = Bodies.PlanetAbv(sc.PlanetTypeID); } if ((sn.ScanData.IsLandable || ShowAllG) && sn.ScanData.nSurfaceGravity != null) { nodelabels[1] = nodelabels[1].AppendPrePad($"{(sn.ScanData.nSurfaceGravity / JournalScan.oneGee_m_s2):N2}g", Environment.NewLine); } } if (ShowDist) { if (drawtype != DrawLevel.MoonLevel) // other than moons { if (sn.ScanData.IsOrbitingBaryCentre) // if in orbit of barycentre { string s = $"{(sn.ScanData.DistanceFromArrivalLS):N1}ls"; if (sn.ScanData.nSemiMajorAxis.HasValue) { s += "/" + sn.ScanData.SemiMajorAxisLSKM; } nodelabels[1] = nodelabels[1].AppendPrePad(s, Environment.NewLine); } else { //System.Diagnostics.Debug.WriteLine(sn.ScanData.BodyName + " SMA " + sn.ScanData.nSemiMajorAxis + " " + sn.ScanData.DistanceFromArrivalm); string s = sn.ScanData.nSemiMajorAxis.HasValue && Math.Abs(sn.ScanData.nSemiMajorAxis.Value - sn.ScanData.DistanceFromArrivalm) > JournalScan.oneAU_m ? (" / " + sn.ScanData.SemiMajorAxisLSKM) : ""; nodelabels[1] = nodelabels[1].AppendPrePad($"{sn.ScanData.DistanceFromArrivalLS:N1}ls" + s, Environment.NewLine); } } else { if (!sn.ScanData.IsOrbitingBaryCentre && sn.ScanData.nSemiMajorAxis.HasValue) // if not in orbit of barycentre { nodelabels[1] = nodelabels[1].AppendPrePad($"{(sn.ScanData.nSemiMajorAxis / JournalScan.oneLS_m):N1}ls", Environment.NewLine); } } } nodelabels[1] = nodelabels[1].AppendPrePad(appendlabeltext, Environment.NewLine); // nodelabels[1] = nodelabels[1].AppendPrePad("" + sn.ScanData?.BodyID, Environment.NewLine); bool valuable = sc.EstimatedValue >= ValueLimit; bool isdiscovered = sc.IsPreviouslyDiscovered && sc.IsPlanet; int iconoverlays = ShowOverlays ? ((sc.Terraformable ? 1 : 0) + (sc.HasMeaningfulVolcanism ? 1 : 0) + (valuable ? 1 : 0) + (sc.Mapped ? 1 : 0) + (isdiscovered ? 1 : 0) + (sc.IsPreviouslyMapped ? 1 : 0) + (sn.Signals != null ? 1 : 0)) : 0; // if (sc.BodyName.Contains("4 b")) iconoverlays = 0; bool materialsicon = sc.HasMaterials && !ShowMaterials; bool imageoverlays = sc.IsLandable || (sc.HasRings && drawtype != DrawLevel.TopLevelStar) || materialsicon; int bitmapheight = size.Height * nodeheightratio / noderatiodivider; int overlaywidth = bitmapheight / 6; int imagewidtharea = (imageoverlays ? 2 : 1) * size.Width; // area used by image+overlay if any int iconwidtharea = (iconoverlays > 0 ? overlaywidth : 0); // area used by icon width area on left int bitmapwidth = iconwidtharea + imagewidtharea; // total width int imageleft = iconwidtharea + imagewidtharea / 2 - size.Width / 2; // calculate where the left of the image is int imagetop = bitmapheight / 2 - size.Height / 2; // and the top Bitmap bmp = new Bitmap(bitmapwidth, bitmapheight); using (Graphics g = Graphics.FromImage(bmp)) { // backwash = Color.FromArgb(128, 40, 40, 40); // debug if (backwash.HasValue) { using (Brush b = new SolidBrush(backwash.Value)) { g.FillRectangle(b, new Rectangle(iconwidtharea, 0, imagewidtharea, bitmapheight)); } } g.DrawImage(nodeimage, imageleft, imagetop, size.Width, size.Height); if (sc.IsLandable) { int offset = size.Height * 4 / 16; int scale = 5; g.DrawImage(Icons.Controls.Scan_Bodies_Landable, new Rectangle(imageleft + size.Width / 2 - offset * scale / 2, imagetop + size.Height / 2 - offset * scale / 2, offset * scale, offset * scale)); } if (sc.HasRings && drawtype != DrawLevel.TopLevelStar) { g.DrawImage(sc.Rings.Count() > 1 ? Icons.Controls.Scan_Bodies_RingGap : Icons.Controls.Scan_Bodies_RingOnly, new Rectangle(imageleft - size.Width / 2, imagetop, size.Width * 2, size.Height)); } if (iconoverlays > 0) { int ovsize = bmp.Height / 6; int pos = 4; if (sc.Terraformable) { g.DrawImage(Icons.Controls.Scan_Bodies_Terraformable, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (sc.HasMeaningfulVolcanism) //this renders below the terraformable icon if present { g.DrawImage(Icons.Controls.Scan_Bodies_Volcanism, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (valuable) { g.DrawImage(Icons.Controls.Scan_Bodies_HighValue, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (sc.Mapped) { g.DrawImage(Icons.Controls.Scan_Bodies_Mapped, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (sc.IsPreviouslyMapped) { g.DrawImage(Icons.Controls.Scan_Bodies_MappedByOthers, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (isdiscovered) { g.DrawImage(Icons.Controls.Scan_Bodies_DiscoveredByOthers, new Rectangle(0, pos, ovsize, ovsize)); pos += ovsize + 1; } if (sn.Signals != null) { g.DrawImage(Icons.Controls.Scan_Bodies_Signals, new Rectangle(0, pos, ovsize, ovsize)); } } if (materialsicon) { Image mm = Icons.Controls.Scan_Bodies_MaterialMore; g.DrawImage(mm, new Rectangle(bmp.Width - mm.Width, bmp.Height - mm.Height, mm.Width, mm.Height)); } if (overlaytext.HasChars()) { float ii; if (imageintensities.ContainsKey(nodeimage)) // find cache { ii = imageintensities[nodeimage]; //System.Diagnostics.Debug.WriteLine("Cached Image intensity of " + sn.fullname + " " + ii); } else { var imageintensity = nodeimage.Function(BitMapHelpers.BitmapFunction.Brightness, nodeimage.Width * 3 / 8, nodeimage.Height * 3 / 8, nodeimage.Width * 2 / 8, nodeimage.Height * 2 / 8); ii = imageintensity.Item2; imageintensities[nodeimage] = ii; //System.Diagnostics.Debug.WriteLine("Calculated Image intensity of " + sn.fullname + " " + ii); } Color text = ii > 0.3f ? Color.Black : Color.FromArgb(255, 200, 200, 200); using (Font f = new Font(EDDTheme.Instance.FontName, size.Width / 5.0f)) { using (Brush b = new SolidBrush(text)) { g.DrawString(overlaytext, f, b, new Rectangle(iconwidtharea, 0, bitmapwidth - iconwidtharea, bitmapheight), new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); } } } } // need left middle, if xiscentre, translate to it Point postoplot = xiscentre ? new Point(position.X - bmp.Width / 2, position.Y) : position; //System.Diagnostics.Debug.WriteLine("Body " + sc.BodyName + " plot at " + postoplot + " " + bmp.Size + " " + (postoplot.X+imageleft) + "," + (postoplot.Y-bmp.Height/2+imagetop)); endpoint = CreateImageAndLabel(pc, bmp, postoplot, bmp.Size, out imagepos, nodelabels, tip); //System.Diagnostics.Debug.WriteLine("Draw {0} at {1} {2} out {3}", nodelabels[0], postoplot, bmp.Size, imagepos); if (sc.HasMaterials && ShowMaterials) { Point matpos = new Point(endpoint.X + 4, position.Y); Point endmat = CreateMaterialNodes(pc, sc, curmats, hl, matpos, materialsize); endpoint = new Point(Math.Max(endpoint.X, endmat.X), Math.Max(endpoint.Y, endmat.Y)); // record new right point.. } } } else if (sn.NodeType == StarScan.ScanNodeType.belt) { if (sn.BeltData != null) { tip = sn.BeltData.RingInformationMoons(true, ""); } else { tip = sn.OwnName + Environment.NewLine + Environment.NewLine + "No scan data available".T(EDTx.ScanDisplayUserControl_NSD); } if (sn.Children != null && sn.Children.Count != 0) { foreach (StarScan.ScanNode snc in sn.Children.Values) { if (snc.ScanData != null) { string sd = snc.ScanData.DisplayString() + "\n"; tip += "\n" + sd; } } } Size bmpsize = new Size(size.Width, planetsize.Height * nodeheightratio / noderatiodivider); endpoint = CreateImageAndLabel(pc, Icons.Controls.Scan_Bodies_Belt, position, bmpsize, out imagepos, new string[] { sn.OwnName.AppendPrePad(appendlabeltext, Environment.NewLine) }, tip, false); } else { if (sn.NodeType == StarScan.ScanNodeType.barycentre) { tip = string.Format("Barycentre of {0}".T(EDTx.ScanDisplayUserControl_BC), sn.OwnName); } else { tip = sn.OwnName + Environment.NewLine + Environment.NewLine + "No scan data available".T(EDTx.ScanDisplayUserControl_NSD); } string nodelabel = sn.CustomName ?? sn.OwnName; nodelabel = nodelabel.AppendPrePad(appendlabeltext, Environment.NewLine); endpoint = CreateImageAndLabel(pc, notscanned, position, size, out imagepos, new string[] { nodelabel }, tip, false); } // System.Diagnostics.Debug.WriteLine("Node " + sn.ownname + " " + position + " " + size + " -> "+ endpoint); return(endpoint); }
private static bool ImageRequiresAnOverlay(JournalScan sc, bool indicatematerials, bool valuable, StarScan.ScanNode sn) { return(sc.IsLandable || sc.HasRings || indicatematerials || sc.Mapped || sc.Terraformable || sc.HasMeaningfulVolcanism || valuable || sn.Signals != null); }