private void RenderOscilloscope(RenderGraphics g) { if (!oscilloscopeVisible) { return; } var oscilloscopeSizeX = timecodeSizeX; var oscilloscopeSizeY = Height - timecodePosY * 2; g.FillRectangle(oscilloscopePosX, timecodePosY, oscilloscopePosX + oscilloscopeSizeX, Height - timecodePosY, theme.BlackBrush); var oscilloscopeGeometry = App.GetOscilloscopeGeometry(out lastOscilloscopeHadNonZeroSample); if (oscilloscopeGeometry != null && lastOscilloscopeHadNonZeroSample) { float scaleX = oscilloscopeSizeX; float scaleY = oscilloscopeSizeY / 2; RenderGeometry geo = g.CreateGeometry(oscilloscopeGeometry, false); g.PushTransform(oscilloscopePosX, timecodePosY + oscilloscopeSizeY / 2, scaleX, scaleY); g.AntiAliasing = true; g.DrawGeometry(geo, theme.LightGreyFillBrush2); g.AntiAliasing = false; g.PopTransform(); geo.Dispose(); } else { g.PushTranslation(oscilloscopePosX, timecodePosY + oscilloscopeSizeY / 2); g.AntiAliasing = true; g.DrawLine(0, 0, oscilloscopeSizeX, 0, theme.LightGreyFillBrush2); g.AntiAliasing = false; g.PopTransform(); } g.DrawRectangle(oscilloscopePosX, timecodePosY, oscilloscopePosX + oscilloscopeSizeX, Height - timecodePosY, theme.LightGreyFillBrush2); }
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 RenderWarningAndTooltip(RenderGraphics g) { var scaling = RenderTheme.MainWindowScaling; 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 * scaling; 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; } } }
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); var bmp = btn.GetBitmap != null?btn.GetBitmap() : btn.Bmp; if (bmp == null) { bmp = btn.Bmp; } bool enabled = btn.Enabled != null?btn.Enabled() : true; g.DrawBitmap(bmp, btn.X, btn.Y, enabled ? (hover ? 0.75f : 1.0f) : 0.25f); } // Timecode int frame = App.CurrentFrame; int patternIdx = frame / App.Song.PatternLength; int noteIdx = frame % App.Song.PatternLength; g.FillAndDrawRectangle(timecodePosX, timecodePosY, timecodePosX + timecodeSizeX, Height - timecodePosY, theme.DarkGreyFillBrush1, theme.BlackBrush); g.DrawText($"{patternIdx:D3}:{noteIdx:D3}", ThemeBase.FontHuge, timecodePosX + timecodeTextPosX, 2, theme.LightGreyFillBrush1, timecodeSizeX); // Tooltip if (!string.IsNullOrEmpty(tooltip)) { var lines = tooltip.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 - 8 * 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--; #endif g.DrawRectangle(posX, posY + specialCharacter.OffsetY, posX + specialCharacter.Width, posY + specialCharacter.Height + specialCharacter.OffsetY, theme.BlackBrush, RenderTheme.MainWindowScaling * 2 - 1); g.DrawText(str, ThemeBase.FontMediumCenter, posX, posY, theme.BlackBrush, specialCharacter.Width); #if !FAMISTUDIO_WINDOWS // HACK: The way we handle fonts in OpenGL is so different, i cant be bothered to debug this. posX--; #endif } } else { posX -= g.MeasureString(splits[i], ThemeBase.FontMedium); g.DrawText(str, ThemeBase.FontMedium, posX, posY, theme.BlackBrush); } } posY += tooltipLineSizeY; } } }