コード例 #1
0
        public TrainColorEditForm(Train train, ISettings settings) : this(settings)
        {
            Train = train;
            style = new TrainStyle(train);
            var attrs = new TimetableStyle(train._parent);

            colorComboBox.SelectedValue = ColorFormatter.ToString(style.TrainColor ?? attrs.TrainColor);
            widthComboBox.SelectedValue = style.TrainWidth ?? attrs.TrainWidth;
            dashComboBox.SelectedValue  = style.LineStyle;
            drawCheckBox.Checked        = style.Show;
        }
コード例 #2
0
ファイル: TrainTipViewModel.cs プロジェクト: N-Magi/TrainTime
        /// <summary>
        /// Initialization
        /// </summary>
        /// <param name="isRapid">Rapid / Local</param>
        /// <param name="dest">Destination</param>
        /// <param name="time">ArrivalTime</param>
        public TrainTipViewModel(TrainStyle trainStyle, string style, string dest, DateTime time)
        {
            Style = style;
            switch (trainStyle)
            {
            case TrainStyle.local: StyleColor = new SolidColorBrush(Color.FromArgb(255, 0, 104, 183)); break;

            case TrainStyle.rapid: StyleColor = new SolidColorBrush(Color.FromArgb(255, 233, 84, 100)); break;

            case TrainStyle.commuterRapid: StyleColor = new SolidColorBrush(Colors.OrangeRed); break;
            }
            Dest  = dest;
            DTime = time;
            Time  = time.ToString("HH:mm");
        }
コード例 #3
0
        public void Render(Graphics g, Train train)
        {
            var style = new TrainStyle(train, attrs);

            if (!style.CalcedShow)
            {
                return;
            }

            var ardps = train.GetArrDeps();
            var dir   = GetTrainDirection(train);

            using (var pen = new Pen((Color)style.CalcedColor, style.CalcedWidth)
            {
                DashStyle = ds.ParseDashstyle(style.CalcedLineStyle)
            })
                using (var brush = new SolidBrush((Color)style.CalcedColor))
                {
                    List <PointF> points = new List <PointF>();
                    bool          hadFirstArrival = false, hadLastDeparture = false, isFirst = true;
                    var           stas = dir ? Enumerable.Reverse(stations) : stations;

                    //TODO: Those helpers are ugly in this part of the code...
                    // Render helpers
                    float GetTimeY(TimeSpan time) => margin.Top + ((time - startTime).GetMinutes() * attrs.HeightPerHour / 60f);

                    PointF?GetGutterPoint(bool arrival, StationX sx, TimeSpan time)
                    {
                        if (time == default)
                        {
                            return(null);
                        }
                        var x = arrival ^ dir ? sx.Left : sx.Right;

                        return(new PointF(margin.Left + x, GetTimeY(time)));
                    }

                    PointF?GetInternalPoint(StationX sx, TimeSpan time, string track)
                    {
                        if (time == default || track == null || !sx.TrackOffsets.TryGetValue(track, out float x))
                        {
                            return(null);
                        }
                        return(new PointF(margin.Left + x, GetTimeY(time)));
                    }

                    void MaybeAddPoint(PointF?point)
                    {
                        if (point.HasValue)
                        {
                            points.Add(point.Value);
                        }
                    }

                    foreach (var sta in stas)
                    {
                        if (!ardps.ContainsKey(sta))
                        {
                            continue;
                        }
                        var ardp = ardps[sta];

                        if (!ardp.HasMinOneTimeSet)
                        {
                            continue;
                        }

                        MaybeAddPoint(GetGutterPoint(true, stationOffsets[sta], ardp.Arrival));
                        MaybeAddPoint(GetInternalPoint(stationOffsets[sta], ardp.Arrival, ardp.ArrivalTrack));

                        foreach (var shunt in ardp.ShuntMoves)
                        {
                            MaybeAddPoint(GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.SourceTrack));
                            MaybeAddPoint(GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.TargetTrack));
                        }

                        MaybeAddPoint(GetInternalPoint(stationOffsets[sta], ardp.Departure, ardp.DepartureTrack));
                        MaybeAddPoint(GetGutterPoint(false, stationOffsets[sta], ardp.Departure));

                        hadLastDeparture = ardp.Departure != default;
                        if (isFirst)
                        {
                            hadFirstArrival = ardp.Arrival != default;
                        }
                        isFirst = false;
                    }

                    // Halbe Linien bei Abfahrten / Ankünften ohne Gegenstelle
                    var hly = !dir ? 20 : -20;
                    if (hadLastDeparture)
                    {
                        points.Add(points.Last() + new Size(50, hly));
                    }
                    if (hadFirstArrival)
                    {
                        points.Insert(0, points.First() - new Size(50, hly));
                    }

                    // Verbindung zum Folgezug
                    var transition = tt.GetTransition(train);
                    if (transition != null && !hadLastDeparture && attrs.StationLines != StationLineStyle.None)
                    {
                        var lastStaOfFirst = GetSortedStations(train)?.LastOrDefault();
                        var firstStaOfNext = GetSortedStations(transition)?.FirstOrDefault();

                        if (lastStaOfFirst == firstStaOfNext)
                        {
                            var departure = transition.GetArrDep(firstStaOfNext).Departure;
                            points.Add(new PointF(points.Last().X, GetTimeY(departure)));
                        }
                    }

                    using (var p = new GraphicsPath())
                    {
                        for (int i = 0; i < points.Count; i += 1)
                        {
                            if (points.Count <= i + 1)
                            {
                                continue;
                            }

                            var isStationLine = (int)points[i].X == (int)points[i + 1].X;
                            if (isStationLine)
                            {
                                var preX         = i > 0 ? points[i - 1].X : 0;
                                var postX        = i < points.Count - 2 ? points[i + 2].X : 0;
                                var x            = points[i].X;
                                var isTransition = isStationLine && (points.Count == i + 2 || Math.Sign(preX - x) == Math.Sign(postX - x));

                                float bezierFactor = !isTransition ?
                                                     ((preX < postX) ? -1 : 1) : // preX < postX --> TrainDirection.ti
                                                     Math.Sign(preX - x);        // Bei Transitions
                                if (isTransition)
                                {
                                    bezierFactor *= 0.5f;
                                }
                                var bezierOffset  = new SizeF(bezierFactor * 14, (points[i + 1].Y - points[i].Y) / -4.0f);
                                var bezierOffsetT = new SizeF(bezierOffset.Width, -bezierOffset.Height);

                                switch (attrs.StationLines)
                                {
                                case StationLineStyle.None:
                                    p.MoveTo(points[i + 1]);
                                    break;

                                case StationLineStyle.Normal:
                                    p.AddLine(points[i], points[i + 1]);
                                    break;

                                case StationLineStyle.Cubic:
                                    var control2 = points[i + 1] + (!isTransition ? bezierOffset : -bezierOffsetT);
                                    p.AddBezier(points[i], points[i] - bezierOffset, control2, points[i + 1]);
                                    break;
                                }
                            }
                            else
                            {
                                p.AddLine(points[i], points[i + 1]); // Normale Zuglinie
                            }
                            if (points[i].X == points[i + 1].X || points[i].Y == points[i + 1].Y)
                            {
                                continue;
                            }
                            // Zugnummern zeichnen
                            var trainFont = (Font)attrs.TrainFont;

                            var     size = g.MeasureString(trainFont, train.TName);
                            float[] ys   = new[] { points[i].Y, points[i + 1].Y };
                            float[] xs   = new[] { points[i].X, points[i + 1].X };
                            float   ty   = ys.Min() + (ys.Max() - ys.Min()) / 2 - (size.Height / 2);
                            float   tx   = xs.Min() + (xs.Max() - xs.Min()) / 2;

                            float angle = CalcAngle(ys, xs, train);
                            g.SaveTransform();
                            g.TranslateTransform(tx, ty);
                            g.RotateTransform(-angle);
                            g.DrawText(trainFont, brush, -(size.Width / 2), -(size.Height / 2), train.TName);
                            g.RestoreTransform();
                        }
                        g.DrawPath(pen, p);
                    }
                }
        }
コード例 #4
0
ファイル: TrainRenderer.cs プロジェクト: FPLedit/FPLedit
        public void Render(Graphics g, ITrain train, bool exportColor)
        {
            var style = new TrainStyle(train, attrs);

            if (!style.CalcedShow)
            {
                return;
            }

            var ardps = train.GetArrDepsUnsorted();
            var dir   = GetTrainDirection(train);

            using var pen = new Pen(style.CalcedColor.ToSD(exportColor), style.CalcedWidth)
                  {
                      DashPattern = ds.ParseDashstyle(style.CalcedLineStyle)
                  };
            using var brush = new SolidBrush(style.CalcedColor.ToSD(exportColor));

            List <PointF> points = new List <PointF>();
            bool          hadFirstArrival = false, hadLastDeparture = false, isFirst = true;
            var           stas = dir ? Enumerable.Reverse(stations) : stations;

            int trainTravelsRouteCount = 0;

            foreach (var sta in stas)
            {
                if (!ardps.ContainsKey(sta))
                {
                    continue;
                }
                var ardp = ardps[sta];
                trainTravelsRouteCount++;

                if (!ardp.HasMinOneTimeSet)
                {
                    continue;
                }

                MaybeAddPoint(points, GetGutterPoint(true, dir, stationOffsets[sta], ardp.Arrival));
                MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], ardp.Arrival, ardp.ArrivalTrack));

                foreach (var shunt in ardp.ShuntMoves)
                {
                    MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.SourceTrack));
                    MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.TargetTrack));
                }

                MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], ardp.Departure, ardp.DepartureTrack));
                MaybeAddPoint(points, GetGutterPoint(false, dir, stationOffsets[sta], ardp.Departure));

                hadLastDeparture = ardp.Departure != default;
                if (isFirst)
                {
                    hadFirstArrival = ardp.Arrival != default;
                }
                isFirst = false;
            }

            // Halbe Linien bei Abfahrten / Ankünften ohne Gegenstelle
            if (attrs.DrawNetworkTrains)
            {
                var hly = !dir ? 20 : -20;
                if (hadLastDeparture)
                {
                    points.Add(points.Last() + new Size(50, hly));
                }
                if (hadFirstArrival)
                {
                    points.Insert(0, points.First() - new Size(50, hly));
                }
            }
            else if (trainTravelsRouteCount <= 1)
            {
                return; // This train has only one station on this route and we don't draw network trains.
            }
            if (points.Count == 0)
            {
                return; // This train is not travelling on this route
            }
            // Transition to the next train; filtered by days and station.
            var lastStaOfFirst = GetSortedStations(train)?.LastOrDefault();
            var transition     = tt.GetTransition(train, renderDays, lastStaOfFirst);

            if (transition != null && !hadLastDeparture && attrs.StationLines != StationLineStyle.None && transition.Days.IsIntersecting(renderDays))
            {
                var firstStaOfNext = GetSortedStations(transition)?.FirstOrDefault();

                if (lastStaOfFirst == firstStaOfNext)
                {
                    var departure = transition.GetArrDep(firstStaOfNext).Departure;
                    points.Add(new PointF(points.Last().X, GetTimeY(departure)));
                }
            }

            using var p = new GraphicsPath();

            for (int i = 0; i < points.Count; i += 1)
            {
                if (points.Count <= i + 1)
                {
                    continue;
                }

                var isStationLine = (int)points[i].X == (int)points[i + 1].X;
                if (isStationLine)
                {
                    var preX         = i > 0 ? points[i - 1].X : 0;
                    var postX        = i < points.Count - 2 ? points[i + 2].X : 0;
                    var x            = points[i].X;
                    var isTransition = isStationLine && (points.Count == i + 2 || Math.Sign(preX - x) == Math.Sign(postX - x));

                    float bezierFactor = !isTransition ?
                                         ((preX < postX) ? -1 : 1) : // preX < postX --> TrainDirection.ti
                                         Math.Sign(preX - x);        // Transition
                    if (isTransition)
                    {
                        bezierFactor *= 0.5f;
                    }
                    var bezierOffset  = new SizeF(bezierFactor * 14, (points[i + 1].Y - points[i].Y) / -4.0f);
                    var bezierOffsetT = new SizeF(bezierOffset.Width, -bezierOffset.Height);

                    switch (attrs.StationLines)
                    {
                    case StationLineStyle.None:
                        p.MoveTo(points[i + 1]);
                        break;

                    case StationLineStyle.Normal:
                        p.AddLine(points[i], points[i + 1]);
                        break;

                    case StationLineStyle.Cubic:
                        var control2 = points[i + 1] + (!isTransition ? bezierOffset : (SizeF.Empty - bezierOffsetT));
                        p.AddBezier(points[i], points[i] - bezierOffset, control2, points[i + 1]);
                        break;
                    }
                }
                else
                {
                    p.AddLine(points[i], points[i + 1]); // Normal line between stations
                }
                if (points[i].X == points[i + 1].X || points[i].Y == points[i + 1].Y)
                {
                    continue;
                }
                // Zugnummern zeichnen
                var trainFont = (Font)attrs.TrainFont;

                var     size = g.MeasureString(trainFont, train.TName);
                float[] ys   = { points[i].Y, points[i + 1].Y };
                float[] xs   = { points[i].X, points[i + 1].X };
                float   ty   = ys.Min() + (ys.Max() - ys.Min()) / 2 - (size.Height / 2);
                float   tx   = xs.Min() + (xs.Max() - xs.Min()) / 2;

                if (g.Clip.IsVisible(new PointF(tx, ty))) // translated drawing does not respect clip (Idk why)
                {
                    float angle = CalcAngle(ys, xs, train);

                    var matrix = g.Transform.Clone();

                    g.TranslateTransform(tx, ty);
                    g.RotateTransform(-angle);
                    g.DrawText(trainFont, brush, -(size.Width / 2), -(size.Height / 2), train.TName);

                    g.Transform = matrix;
                }
            }
            g.DrawPath(pen, p);
        }