private void RenderTimecode(RenderGraphics g) { var frame = App.CurrentFrame; var famitrackerTempo = App.Project != null && App.Project.UsesFamiTrackerTempo; var zeroSizeX = g.MeasureString("0", ThemeBase.FontHuge); var colonSizeX = g.MeasureString(":", ThemeBase.FontHuge); g.FillAndDrawRectangle(timecodePosX, timecodePosY, timecodePosX + timecodeSizeX, Height - timecodePosY, theme.DarkGreyFillBrush1, theme.BlackBrush); if (Settings.TimeFormat == 0 || famitrackerTempo) // MM:SS:mmm cant be used with FamiTracker tempo. { int patternIdx = App.Song.FindPatternInstanceIndex(frame, out int noteIdx); var numPatternDigits = Utils.NumDecimalDigits(App.Song.Length - 1); var numNoteDigits = Utils.NumDecimalDigits(App.Song.GetPatternLength(patternIdx) - 1); var patternString = patternIdx.ToString("D" + numPatternDigits); var noteString = noteIdx.ToString("D" + numNoteDigits); var charPosX = timecodePosX + timecodeSizeX / 2 - ((numPatternDigits + numNoteDigits) * zeroSizeX + colonSizeX) / 2; for (int i = 0; i < numPatternDigits; i++, charPosX += zeroSizeX) { g.DrawText(patternString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < numNoteDigits; i++, charPosX += zeroSizeX) { g.DrawText(noteString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } } else { TimeSpan time = App.Project != null? TimeSpan.FromMilliseconds(frame * 1000.0 / (App.Project.PalMode ? NesApu.FpsPAL : NesApu.FpsNTSC)) : TimeSpan.Zero; var minutesString = time.Minutes.ToString("D2"); var secondsString = time.Seconds.ToString("D2"); var millisecondsString = time.Milliseconds.ToString("D3"); // 00:00:000 var charPosX = timecodePosX + timecodeSizeX / 2 - (7 * zeroSizeX + 2 * colonSizeX) / 2; for (int i = 0; i < 2; i++, charPosX += zeroSizeX) { g.DrawText(minutesString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < 2; i++, charPosX += zeroSizeX) { g.DrawText(secondsString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < 3; i++, charPosX += zeroSizeX) { g.DrawText(millisecondsString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } } }
protected override void OnRender(RenderGraphics g) { g.FillRectangle(0, 0, Width, Height, toolbarBrush); var scaling = RenderTheme.MainWindowScaling; var pt = this.PointToClient(Cursor.Position); // Buttons foreach (var btn in buttons) { bool hover = btn.IsPointIn(pt.X, pt.Y, Width); var bmp = btn.GetBitmap != null?btn.GetBitmap() : btn.Bmp; if (bmp == null) { bmp = btn.Bmp; } bool enabled = btn.Enabled != null?btn.Enabled() : true; int x = btn.RightAligned ? Width - btn.X : btn.X; g.DrawBitmap(bmp, x, btn.Y, enabled ? (hover ? 0.75f : 1.0f) : 0.25f); } // Timecode int frame = App.CurrentFrame; int patternIdx = App.Song.FindPatternInstanceIndex(frame, out int noteIdx); g.FillAndDrawRectangle(timecodePosX, timecodePosY, timecodePosX + timecodeSizeX, Height - timecodePosY, theme.DarkGreyFillBrush1, theme.BlackBrush); var numPatternDigits = Utils.NumDecimalDigits(App.Song.Length - 1); var numNoteDigits = Utils.NumDecimalDigits(App.Song.GetPatternLength(patternIdx) - 1); var zeroSizeX = g.MeasureString("0", ThemeBase.FontHuge); var colonSizeX = g.MeasureString(":", ThemeBase.FontHuge); var patternString = patternIdx.ToString("D" + numPatternDigits); var noteString = noteIdx.ToString("D" + numNoteDigits); var charPosX = timecodePosX + timecodeSizeX / 2 - ((numPatternDigits + numNoteDigits) * zeroSizeX + colonSizeX) / 2; for (int i = 0; i < numPatternDigits; i++, charPosX += zeroSizeX) { g.DrawText(patternString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < numNoteDigits; i++, charPosX += zeroSizeX) { g.DrawText(noteString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, theme.LightGreyFillBrush1, zeroSizeX); } var message = tooltip; var messageBrush = theme.BlackBrush; var messageFont = ThemeBase.FontMedium; var messageFontCenter = ThemeBase.FontMediumCenter; if (!string.IsNullOrEmpty(warning)) { var span = DateTime.Now - warningTime; if (span.TotalMilliseconds >= 2000) { warning = ""; } else { message = (((((long)span.TotalMilliseconds) / 250) & 1) != 0) ? warning : ""; messageBrush = warningBrush; messageFont = ThemeBase.FontMediumBold; messageFontCenter = ThemeBase.FontMediumBoldCenter; } } // Tooltip if (!string.IsNullOrEmpty(message)) { var lines = message.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); var posY = lines.Length == 1 ? tooltipSingleLinePosY : tooltipMultiLinePosY; for (int j = 0; j < lines.Length; j++) { var splits = lines[j].Split(new char[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries); var posX = Width - 40 * RenderTheme.MainWindowScaling; for (int i = splits.Length - 1; i >= 0; i--) { var str = splits[i]; if (specialCharacters.TryGetValue(str, out var specialCharacter)) { posX -= specialCharacter.Width; if (specialCharacter.Bmp != null) { g.DrawBitmap(specialCharacter.Bmp, posX, posY + specialCharacter.OffsetY); } else { #if FAMISTUDIO_MACOS if (str == "Ctrl") { str = "Cmd"; } #endif #if !FAMISTUDIO_WINDOWS // HACK: The way we handle fonts in OpenGL is so different, i cant be bothered to debug this. posX -= (int)scaling; #endif g.DrawRectangle(posX, posY + specialCharacter.OffsetY, posX + specialCharacter.Width, posY + specialCharacter.Height + specialCharacter.OffsetY, messageBrush); g.DrawText(str, messageFontCenter, posX, posY, messageBrush, specialCharacter.Width); #if !FAMISTUDIO_WINDOWS // HACK: The way we handle fonts in OpenGL is so different, i cant be bothered to debug this. posX -= (int)scaling; #endif } } else { posX -= g.MeasureString(splits[i], messageFont); g.DrawText(str, messageFont, posX, posY, messageBrush); } } posY += tooltipLineSizeY; } } }
private void RenderTimecode(RenderGraphics g) { var frame = App.CurrentFrame; var famitrackerTempo = App.Project != null && App.Project.UsesFamiTrackerTempo; var zeroSizeX = g.MeasureString("0", ThemeBase.FontHuge); var colonSizeX = g.MeasureString(":", ThemeBase.FontHuge); var timeCodeSizeY = Height - timecodePosY * 2; var textColor = App.IsRecording ? theme.DarkRedFillBrush : theme.LightGreyFillBrush2; g.FillAndDrawRectangle(timecodePosX, timecodePosY, timecodePosX + timecodeSizeX, Height - timecodePosY, theme.BlackBrush, theme.LightGreyFillBrush2); if (Settings.TimeFormat == 0 || famitrackerTempo) // MM:SS:mmm cant be used with FamiTracker tempo. { var location = NoteLocation.FromAbsoluteNoteIndex(App.Song, frame); var numPatternDigits = Utils.NumDecimalDigits(App.Song.Length - 1); var numNoteDigits = Utils.NumDecimalDigits(App.Song.GetPatternLength(location.PatternIndex) - 1); var patternString = location.PatternIndex.ToString("D" + numPatternDigits); var noteString = location.NoteIndex.ToString("D" + numNoteDigits); var charPosX = timecodePosX + timecodeSizeX / 2 - ((numPatternDigits + numNoteDigits) * zeroSizeX + colonSizeX) / 2; for (int i = 0; i < numPatternDigits; i++, charPosX += zeroSizeX) { g.DrawText(patternString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, textColor, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, textColor, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < numNoteDigits; i++, charPosX += zeroSizeX) { g.DrawText(noteString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, textColor, zeroSizeX); } } else { TimeSpan time = App.CurrentTime; var minutesString = time.Minutes.ToString("D2"); var secondsString = time.Seconds.ToString("D2"); var millisecondsString = time.Milliseconds.ToString("D3"); // 00:00:000 var charPosX = timecodePosX + timecodeSizeX / 2 - (7 * zeroSizeX + 2 * colonSizeX) / 2; for (int i = 0; i < 2; i++, charPosX += zeroSizeX) { g.DrawText(minutesString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, textColor, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, textColor, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < 2; i++, charPosX += zeroSizeX) { g.DrawText(secondsString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, textColor, zeroSizeX); } g.DrawText(":", ThemeBase.FontHuge, charPosX, 2, textColor, colonSizeX); charPosX += colonSizeX; for (int i = 0; i < 3; i++, charPosX += zeroSizeX) { g.DrawText(millisecondsString[i].ToString(), ThemeBase.FontHuge, charPosX, 2, textColor, zeroSizeX); } } }