private void RenderButtons(RenderGraphics g) { g.FillRectangle(0, 0, Width, Height, toolbarBrush); var pt = this.PointToClient(Cursor.Position); // Buttons foreach (var btn in buttons) { if (!btn.Visible) { continue; } bool hover = btn.IsPointIn(pt.X, pt.Y, Width); var bmp = btn.GetBitmap != null?btn.GetBitmap() : btn.Bmp; if (bmp == null) { bmp = btn.Bmp; } var status = btn.Enabled == null ? ButtonStatus.Enabled : btn.Enabled(); var opacity = status == ButtonStatus.Enabled ? 1.0f : 0.25f; if (status != ButtonStatus.Disabled && hover) { opacity *= 0.75f; } int x = btn.RightAligned ? Width - btn.X : btn.X; g.DrawBitmap(bmp, x, btn.Y, opacity); } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); bmpSong = g.CreateBitmapFromResource("Music"); bmpInstrument[Project.ExpansionNone] = g.CreateBitmapFromResource("Instrument"); bmpInstrument[Project.ExpansionVrc6] = g.CreateBitmapFromResource("InstrumentVRC6"); #if DEV bmpInstrument[Project.ExpansionVrc7] = g.CreateBitmapFromResource("InstrumentVRC6"); bmpInstrument[Project.ExpansionFds] = g.CreateBitmapFromResource("Instrument"); bmpInstrument[Project.ExpansionMmc5] = g.CreateBitmapFromResource("Instrument"); bmpInstrument[Project.ExpansionNamco] = g.CreateBitmapFromResource("Instrument"); bmpInstrument[Project.ExpansionSunsoft] = g.CreateBitmapFromResource("Instrument"); #endif bmpAdd = g.CreateBitmapFromResource("Add"); bmpDPCM = g.CreateBitmapFromResource("DPCM"); bmpDuty[0] = g.CreateBitmapFromResource("Duty0"); bmpDuty[1] = g.CreateBitmapFromResource("Duty1"); bmpDuty[2] = g.CreateBitmapFromResource("Duty2"); bmpDuty[3] = g.CreateBitmapFromResource("Duty3"); bmpDuty[4] = g.CreateBitmapFromResource("Duty4"); bmpDuty[5] = g.CreateBitmapFromResource("Duty5"); bmpDuty[6] = g.CreateBitmapFromResource("Duty6"); bmpDuty[7] = g.CreateBitmapFromResource("Duty7"); bmpArpeggio = g.CreateBitmapFromResource("Arpeggio"); bmpPitch = g.CreateBitmapFromResource("Pitch"); bmpVolume = g.CreateBitmapFromResource("Volume"); bmpLoadInstrument = g.CreateBitmapFromResource("InstrumentOpen"); }
protected override void OnRender(RenderGraphics g) { RenderButtons(g); RenderTimecode(g); RenderOscilloscope(g); RenderWarningAndTooltip(g); }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); bmpTracks[Channel.Square1] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Square2] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Triangle] = g.CreateBitmapFromResource("Triangle"); bmpTracks[Channel.Noise] = g.CreateBitmapFromResource("Noise"); bmpTracks[Channel.DPCM] = g.CreateBitmapFromResource("DPCM"); bmpGhostNote = g.CreateBitmapFromResource("GhostSmall"); seekBarBrush = g.CreateSolidBrush(ThemeBase.SeekBarColor); whiteKeyBrush = g.CreateHorizontalGradientBrush(0, trackNameSizeX, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); patternHeaderBrush = g.CreateVerticalGradientBrush(0, patternHeaderSizeY, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); selectedPatternVisibleBrush = g.CreateSolidBrush(Color.FromArgb(64, ThemeBase.LightGreyFillColor1)); selectedPatternInvisibleBrush = g.CreateSolidBrush(Color.FromArgb(32, ThemeBase.LightGreyFillColor1)); seekGeometry = g.CreateConvexPath(new[] { new Point(-headerSizeY / 2, 1), new Point(0, headerSizeY - 2), new Point(headerSizeY / 2, 1) }); }
public virtual void InitializeForGraphics(RenderGraphics g) { BlackBrush = g.CreateSolidBrush(BlackColor); LightGreyFillBrush1 = g.CreateSolidBrush(LightGreyFillColor1); LightGreyFillBrush2 = g.CreateSolidBrush(LightGreyFillColor2); DarkGreyLineBrush1 = g.CreateSolidBrush(DarkGreyLineColor1); DarkGreyLineBrush2 = g.CreateSolidBrush(DarkGreyLineColor2); DarkGreyFillBrush1 = g.CreateSolidBrush(DarkGreyFillColor1); DarkGreyFillBrush2 = g.CreateSolidBrush(DarkGreyFillColor2); }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); bmpTracks[Channel.Square1] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Square2] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Triangle] = g.CreateBitmapFromResource("Triangle"); bmpTracks[Channel.Noise] = g.CreateBitmapFromResource("Noise"); bmpTracks[Channel.DPCM] = g.CreateBitmapFromResource("DPCM"); bmpGhostNote = g.CreateBitmapFromResource("GhostSmall"); playPositionBrush = g.CreateSolidBrush(Color.FromArgb(192, ThemeBase.LightGreyFillColor1)); whiteKeyBrush = g.CreateHorizontalGradientBrush(0, trackNameSizeX, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); patternHeaderBrush = g.CreateVerticalGradientBrush(0, patternHeaderSizeY, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); selectedPatternBrush = g.CreateSolidBrush(Color.FromArgb(128, ThemeBase.LightGreyFillColor1)); }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); bmpButtonIcons[(int)ButtonType.Song] = g.CreateBitmapFromResource("Music"); bmpButtonIcons[(int)ButtonType.Instrument] = g.CreateBitmapFromResource("Pattern"); bmpSubButtonIcons[(int)SubButtonType.Add] = g.CreateBitmapFromResource("Add"); bmpSubButtonIcons[(int)SubButtonType.DPCM] = g.CreateBitmapFromResource("DPCM"); bmpSubButtonIcons[(int)SubButtonType.DutyCycle0] = g.CreateBitmapFromResource("Duty0"); bmpSubButtonIcons[(int)SubButtonType.DutyCycle1] = g.CreateBitmapFromResource("Duty1"); bmpSubButtonIcons[(int)SubButtonType.DutyCycle2] = g.CreateBitmapFromResource("Duty2"); bmpSubButtonIcons[(int)SubButtonType.DutyCycle3] = g.CreateBitmapFromResource("Duty3"); bmpSubButtonIcons[(int)SubButtonType.Arpeggio] = g.CreateBitmapFromResource("Arpeggio"); bmpSubButtonIcons[(int)SubButtonType.Pitch] = g.CreateBitmapFromResource("Pitch"); bmpSubButtonIcons[(int)SubButtonType.Volume] = g.CreateBitmapFromResource("Volume"); }
protected override void OnRender(RenderGraphics g) { g.Clear(ThemeBase.DarkGreyFillColor1); g.DrawLine(0, 0, 0, Height, theme.BlackBrush); int actualWidth = Width - scrollBarSizeX; int y = -scrollY; foreach (var button in buttons) { var icon = bmpButtonIcons[(int)button.type]; g.PushTranslation(0, y); g.FillAndDrawRectangle(0, 0, actualWidth, buttonSizeY, g.GetVerticalGradientBrush(button.GetColor(), buttonSizeY, 0.8f), theme.BlackBrush); g.DrawText(button.GetText(App.Project), button.GetFont(selectedSong, selectedInstrument), icon == null ? buttonTextNoIconPosX : buttonTextPosX, buttonTextPosY, theme.BlackBrush, actualWidth - buttonTextNoIconPosX * 2); if (icon != null) { g.DrawBitmap(icon, buttonIconPosX, buttonIconPosY); } var subButtons = button.GetSubButtons(out var active); if (subButtons != null) { for (int i = 0, x = actualWidth - subButtonSpacingX; i < subButtons.Length; i++, x -= subButtonSpacingX) { g.DrawBitmap(bmpSubButtonIcons[(int)subButtons[i]], x, subButtonPosY, active[i] ? 1.0f : 0.2f); } } g.PopTransform(); y += buttonSizeY; } if (needsScrollBar) { int virtualSizeY = this.virtualSizeY; int scrollBarSizeY = (int)Math.Round(Height * (Height / (float)virtualSizeY)); int scrollBarPosY = (int)Math.Round(Height * (scrollY / (float)virtualSizeY)); g.FillAndDrawRectangle(actualWidth, 0, Width - 1, Height, theme.DarkGreyFillBrush1, theme.BlackBrush); g.FillAndDrawRectangle(actualWidth, scrollBarPosY, Width - 1, scrollBarPosY + scrollBarSizeY, theme.LightGreyFillBrush1, theme.BlackBrush); } }
public virtual void InitializeForGraphics(RenderGraphics g) { BlackBrush = g.CreateSolidBrush(BlackColor); LightGreyFillBrush1 = g.CreateSolidBrush(LightGreyFillColor1); LightGreyFillBrush2 = g.CreateSolidBrush(LightGreyFillColor2); DarkGreyLineBrush1 = g.CreateSolidBrush(DarkGreyLineColor1); DarkGreyLineBrush2 = g.CreateSolidBrush(DarkGreyLineColor2); DarkGreyFillBrush1 = g.CreateSolidBrush(DarkGreyFillColor1); DarkGreyFillBrush2 = g.CreateSolidBrush(DarkGreyFillColor2); for (int j = 0; j < CustomColors.GetLength(1); j++) { for (int i = 0; i < CustomColors.GetLength(0); i++) { CustomColorBrushes[CustomColors[i, j]] = g.CreateSolidBrush(CustomColors[i, j]); } } }
private void RenderButtons(RenderGraphics g) { g.FillRectangle(0, 0, Width, Height, toolbarBrush); 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); } }
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); 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)) { g.DrawText(tooltip, ThemeBase.FontMediumRight, Width - 314, tooltipPosY, theme.BlackBrush, 300); } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); toolbarBrush = g.CreateHorizontalGradientBrush(0, 81, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); bmpLoopNone = g.CreateBitmapFromResource("LoopNone"); bmpLoopSong = g.CreateBitmapFromResource("Loop"); bmpLoopPattern = g.CreateBitmapFromResource("LoopPattern"); bmpPlay = g.CreateBitmapFromResource("Play"); bmpPause = g.CreateBitmapFromResource("Pause"); buttons[ButtonNew] = new Button { X = 4, Y = 4, Bmp = g.CreateBitmapFromResource("File"), Click = OnNew }; buttons[ButtonOpen] = new Button { X = 44, Y = 4, Bmp = g.CreateBitmapFromResource("Open"), Click = OnOpen }; buttons[ButtonSave] = new Button { X = 84, Y = 4, Bmp = g.CreateBitmapFromResource("Save"), Click = OnSave, RightClick = OnSaveAs }; buttons[ButtonExport] = new Button { X = 124, Y = 4, Bmp = g.CreateBitmapFromResource("Export"), Click = OnExport }; buttons[ButtonUndo] = new Button { X = 164, Y = 4, Bmp = g.CreateBitmapFromResource("Undo"), Click = OnUndo, Enabled = OnUndoEnabled }; buttons[ButtonRedo] = new Button { X = 204, Y = 4, Bmp = g.CreateBitmapFromResource("Redo"), Click = OnRedo, Enabled = OnRedoEnabled }; buttons[ButtonConfig] = new Button { X = 244, Y = 4, Bmp = g.CreateBitmapFromResource("Config"), Click = OnConfig }; buttons[ButtonPlay] = new Button { X = 476, Y = 4, Click = OnPlay, GetBitmap = OnPlayGetBitmap }; buttons[ButtonRewind] = new Button { X = 516, Y = 4, Bmp = g.CreateBitmapFromResource("Rewind"), Click = OnRewind }; buttons[ButtonLoop] = new Button { X = 556, Y = 4, Click = OnLoop, GetBitmap = OnLoopGetBitmap }; buttons[ButtonNew].ToolTip = "New Project (Ctrl-N)"; buttons[ButtonOpen].ToolTip = "Open Project (Ctrl-O)"; buttons[ButtonSave].ToolTip = "Save Project (Ctrl-S) [Right-Click: Save As...]"; buttons[ButtonExport].ToolTip = "Export to various formats (Ctrl+E)"; buttons[ButtonUndo].ToolTip = "Undo (Ctrl+Z)"; buttons[ButtonRedo].ToolTip = "Redo (Ctrl+Y)"; buttons[ButtonConfig].ToolTip = "Edit Application Settings"; buttons[ButtonPlay].ToolTip = "Play/Pause (Space) [Ctrl+Space: Play pattern loop, Shift-Space: Play song loop]"; buttons[ButtonRewind].ToolTip = "Rewind (Home) [Ctrl+Home: Rewind to beginning of current pattern]"; buttons[ButtonLoop].ToolTip = "Toggle Loop Mode"; var scaling = RenderTheme.MainWindowScaling; for (int i = 0; i < ButtonCount; i++) { var btn = buttons[i]; btn.X = (int)(btn.X * scaling); btn.Y = (int)(btn.Y * scaling); btn.Size = (int)(btn.Size * scaling); } timecodePosX = (int)(DefaultTimecodePosX * scaling); timecodePosY = (int)(DefaultTimecodePosY * scaling); timecodeSizeX = (int)(DefaultTimecodeSizeX * scaling); timecodeTextPosX = (int)(DefaultTimecodeTextPosX * scaling); tooltipPosY = (int)(DefaultTooltipPosY * scaling); }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); toolbarBrush = g.CreateHorizontalGradientBrush(0, 81, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); bmpLoopNone = g.CreateBitmapFromResource("LoopNone"); bmpLoopSong = g.CreateBitmapFromResource("Loop"); bmpLoopPattern = g.CreateBitmapFromResource("LoopPattern"); bmpPlay = g.CreateBitmapFromResource("Play"); bmpPause = g.CreateBitmapFromResource("Pause"); buttons[ButtonNew] = new Button { X = 4, Y = 4, Bmp = g.CreateBitmapFromResource("File"), Click = OnNew }; buttons[ButtonOpen] = new Button { X = 44, Y = 4, Bmp = g.CreateBitmapFromResource("Open"), Click = OnOpen }; buttons[ButtonSave] = new Button { X = 84, Y = 4, Bmp = g.CreateBitmapFromResource("Save"), Click = OnSave, RightClick = OnSaveAs }; buttons[ButtonExport] = new Button { X = 124, Y = 4, Bmp = g.CreateBitmapFromResource("Export"), Click = OnExport }; buttons[ButtonCopy] = new Button { X = 164, Y = 4, Bmp = g.CreateBitmapFromResource("Copy"), Click = OnCopy, Enabled = OnCopyEnabled }; buttons[ButtonCut] = new Button { X = 204, Y = 4, Bmp = g.CreateBitmapFromResource("Cut"), Click = OnCut, Enabled = OnCutEnabled }; buttons[ButtonPaste] = new Button { X = 244, Y = 4, Bmp = g.CreateBitmapFromResource("Paste"), Click = OnPaste, RightClick = OnPasteSpecial, Enabled = OnPasteEnabled }; buttons[ButtonUndo] = new Button { X = 284, Y = 4, Bmp = g.CreateBitmapFromResource("Undo"), Click = OnUndo, Enabled = OnUndoEnabled }; buttons[ButtonRedo] = new Button { X = 324, Y = 4, Bmp = g.CreateBitmapFromResource("Redo"), Click = OnRedo, Enabled = OnRedoEnabled }; buttons[ButtonConfig] = new Button { X = 364, Y = 4, Bmp = g.CreateBitmapFromResource("Config"), Click = OnConfig }; buttons[ButtonPlay] = new Button { X = 594, Y = 4, Click = OnPlay, GetBitmap = OnPlayGetBitmap }; buttons[ButtonRewind] = new Button { X = 634, Y = 4, Bmp = g.CreateBitmapFromResource("Rewind"), Click = OnRewind }; buttons[ButtonLoop] = new Button { X = 674, Y = 4, Click = OnLoop, GetBitmap = OnLoopGetBitmap }; buttons[ButtonNew].ToolTip = "{MouseLeft} New Project {Ctrl} {N}"; buttons[ButtonOpen].ToolTip = "{MouseLeft} Open Project {Ctrl} {O}"; buttons[ButtonSave].ToolTip = "{MouseLeft} Save Project {Ctrl} {S} - {MouseRight} Save As..."; buttons[ButtonExport].ToolTip = "{MouseLeft} Export to various formats {Ctrl} {E}"; buttons[ButtonCopy].ToolTip = "{MouseLeft} Copy selection {Ctrl} {C}"; buttons[ButtonCut].ToolTip = "{MouseLeft} Cut selection {Ctrl} {X}"; buttons[ButtonPaste].ToolTip = "{MouseLeft} Paste {Ctrl} {V}\n{MouseRight} Paste Special... {Ctrl} {Shift} {V}"; buttons[ButtonUndo].ToolTip = "{MouseLeft} Undo {Ctrl} {Z}"; buttons[ButtonRedo].ToolTip = "{MouseLeft} Redo {Ctrl} {Y}"; buttons[ButtonConfig].ToolTip = "{MouseLeft} Edit Application Settings"; buttons[ButtonPlay].ToolTip = "{MouseLeft} Play/Pause {Space}\nPlay pattern loop {Ctrl} {Space} - Play song loop {Shift} {Space}"; buttons[ButtonRewind].ToolTip = "{MouseLeft} Rewind {Home}\nRewind to beginning of current pattern {Ctrl} {Home}"; buttons[ButtonLoop].ToolTip = "{MouseLeft} Toggle Loop Mode"; var scaling = RenderTheme.MainWindowScaling; for (int i = 0; i < ButtonCount; i++) { var btn = buttons[i]; btn.X = (int)(btn.X * scaling); btn.Y = (int)(btn.Y * scaling); btn.Size = (int)(btn.Size * scaling); } timecodePosX = (int)(DefaultTimecodePosX * scaling); timecodePosY = (int)(DefaultTimecodePosY * scaling); timecodeSizeX = (int)(DefaultTimecodeSizeX * scaling); timecodeTextPosX = (int)(DefaultTimecodeTextPosX * scaling); tooltipSingleLinePosY = (int)(DefaultTooltipSingleLinePosY * scaling); tooltipMultiLinePosY = (int)(DefaultTooltipMultiLinePosY * scaling); tooltipLineSizeY = (int)(DefaultTooltipLineSizeY * scaling); tooltipSpecialCharSizeX = (int)(DefaultTooltipSpecialCharSizeX * scaling); tooltipSpecialCharSizeY = (int)(DefaultTooltipSpecialCharSizeY * scaling); specialCharacters["Shift"] = new TooltipSpecialCharacter { Width = (int)(32 * scaling) }; specialCharacters["Space"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Home"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Ctrl"] = new TooltipSpecialCharacter { Width = (int)(28 * scaling) }; specialCharacters["Alt"] = new TooltipSpecialCharacter { Width = (int)(24 * scaling) }; specialCharacters["Drag"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("Drag"), OffsetY = 2 * scaling }; specialCharacters["MouseLeft"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseLeft"), OffsetY = 2 * scaling }; specialCharacters["MouseRight"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseRight"), OffsetY = 2 * scaling }; specialCharacters["MouseWheel"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseWheel"), OffsetY = 2 * scaling }; for (char i = 'A'; i <= 'Z'; i++) { specialCharacters[i.ToString()] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX } } ; foreach (var specialChar in specialCharacters.Values) { if (specialChar.Bmp != null) { specialChar.Width = (int)g.GetBitmapWidth(specialChar.Bmp); } specialChar.Height = tooltipSpecialCharSizeY; } }
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); } } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); toolbarBrush = g.CreateHorizontalGradientBrush(0, 81, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); warningBrush = g.CreateSolidBrush(ThemeBase.Darken(ThemeBase.CustomColors[0, 0])); bmpLoopNone = g.CreateBitmapFromResource("LoopNone"); bmpLoopSong = g.CreateBitmapFromResource("Loop"); bmpLoopPattern = g.CreateBitmapFromResource("LoopPattern"); bmpPlay = g.CreateBitmapFromResource("Play"); bmpPause = g.CreateBitmapFromResource("Pause"); bmpNtsc = g.CreateBitmapFromResource("NTSC"); bmpPal = g.CreateBitmapFromResource("PAL"); buttons[ButtonNew] = new Button { X = 4, Y = 4, Bmp = g.CreateBitmapFromResource("File"), Click = OnNew }; buttons[ButtonOpen] = new Button { X = 40, Y = 4, Bmp = g.CreateBitmapFromResource("Open"), Click = OnOpen }; buttons[ButtonSave] = new Button { X = 76, Y = 4, Bmp = g.CreateBitmapFromResource("Save"), Click = OnSave, RightClick = OnSaveAs }; buttons[ButtonExport] = new Button { X = 112, Y = 4, Bmp = g.CreateBitmapFromResource("Export"), Click = OnExport }; buttons[ButtonCopy] = new Button { X = 148, Y = 4, Bmp = g.CreateBitmapFromResource("Copy"), Click = OnCopy, Enabled = OnCopyEnabled }; buttons[ButtonCut] = new Button { X = 184, Y = 4, Bmp = g.CreateBitmapFromResource("Cut"), Click = OnCut, Enabled = OnCutEnabled }; buttons[ButtonPaste] = new Button { X = 220, Y = 4, Bmp = g.CreateBitmapFromResource("Paste"), Click = OnPaste, RightClick = OnPasteSpecial, Enabled = OnPasteEnabled }; buttons[ButtonUndo] = new Button { X = 256, Y = 4, Bmp = g.CreateBitmapFromResource("Undo"), Click = OnUndo, Enabled = OnUndoEnabled }; buttons[ButtonRedo] = new Button { X = 292, Y = 4, Bmp = g.CreateBitmapFromResource("Redo"), Click = OnRedo, Enabled = OnRedoEnabled }; buttons[ButtonTransform] = new Button { X = 328, Y = 4, Bmp = g.CreateBitmapFromResource("Transform"), Click = OnTransform }; buttons[ButtonConfig] = new Button { X = 364, Y = 4, Bmp = g.CreateBitmapFromResource("Config"), Click = OnConfig }; buttons[ButtonPlay] = new Button { X = 572, Y = 4, Click = OnPlay, GetBitmap = OnPlayGetBitmap }; buttons[ButtonRewind] = new Button { X = 608, Y = 4, Bmp = g.CreateBitmapFromResource("Rewind"), Click = OnRewind }; buttons[ButtonLoop] = new Button { X = 644, Y = 4, Click = OnLoop, GetBitmap = OnLoopGetBitmap }; buttons[ButtonMachine] = new Button { X = 680, Y = 4, Click = OnMachine, GetBitmap = OnMachineGetBitmap, Enabled = OnMachineEnabled }; buttons[ButtonHelp] = new Button { X = 36, Y = 4, Bmp = g.CreateBitmapFromResource("Help"), RightAligned = true, Click = OnHelp }; buttons[ButtonNew].ToolTip = "{MouseLeft} New Project {Ctrl} {N}"; buttons[ButtonOpen].ToolTip = "{MouseLeft} Open Project {Ctrl} {O}"; buttons[ButtonSave].ToolTip = "{MouseLeft} Save Project {Ctrl} {S} - {MouseRight} Save As..."; buttons[ButtonExport].ToolTip = "{MouseLeft} Export to various formats {Ctrl} {E}"; buttons[ButtonCopy].ToolTip = "{MouseLeft} Copy selection {Ctrl} {C}"; buttons[ButtonCut].ToolTip = "{MouseLeft} Cut selection {Ctrl} {X}"; buttons[ButtonPaste].ToolTip = "{MouseLeft} Paste {Ctrl} {V}\n{MouseRight} Paste Special... {Ctrl} {Shift} {V}"; buttons[ButtonUndo].ToolTip = "{MouseLeft} Undo {Ctrl} {Z}"; buttons[ButtonRedo].ToolTip = "{MouseLeft} Redo {Ctrl} {Y}"; buttons[ButtonTransform].ToolTip = "{MouseLeft} Perform cleanup and various operations"; buttons[ButtonConfig].ToolTip = "{MouseLeft} Edit Application Settings"; buttons[ButtonPlay].ToolTip = "{MouseLeft} Play/Pause {Space} - Play from start of pattern {Ctrl} {Space}"; buttons[ButtonRewind].ToolTip = "{MouseLeft} Rewind {Home}\nRewind to beginning of current pattern {Ctrl} {Home}"; buttons[ButtonLoop].ToolTip = "{MouseLeft} Toggle Loop Mode"; buttons[ButtonMachine].ToolTip = "{MouseLeft} Toggle between NTSC/PAL playback mode"; buttons[ButtonHelp].ToolTip = "{MouseLeft} Online documentation"; var scaling = RenderTheme.MainWindowScaling; for (int i = 0; i < ButtonCount; i++) { var btn = buttons[i]; btn.X = (int)(btn.X * scaling); btn.Y = (int)(btn.Y * scaling); btn.Size = (int)(btn.Size * scaling); } timecodePosX = (int)(DefaultTimecodePosX * scaling); timecodePosY = (int)(DefaultTimecodePosY * scaling); timecodeSizeX = (int)(DefaultTimecodeSizeX * scaling); tooltipSingleLinePosY = (int)(DefaultTooltipSingleLinePosY * scaling); tooltipMultiLinePosY = (int)(DefaultTooltipMultiLinePosY * scaling); tooltipLineSizeY = (int)(DefaultTooltipLineSizeY * scaling); tooltipSpecialCharSizeX = (int)(DefaultTooltipSpecialCharSizeX * scaling); tooltipSpecialCharSizeY = (int)(DefaultTooltipSpecialCharSizeY * scaling); specialCharacters["Shift"] = new TooltipSpecialCharacter { Width = (int)(32 * scaling) }; specialCharacters["Space"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Home"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Ctrl"] = new TooltipSpecialCharacter { Width = (int)(28 * scaling) }; specialCharacters["Alt"] = new TooltipSpecialCharacter { Width = (int)(24 * scaling) }; specialCharacters["Drag"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("Drag"), OffsetY = 2 * scaling }; specialCharacters["MouseLeft"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseLeft"), OffsetY = 2 * scaling }; specialCharacters["MouseRight"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseRight"), OffsetY = 2 * scaling }; specialCharacters["MouseWheel"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseWheel"), OffsetY = 2 * scaling }; specialCharacters["Warning"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("Warning") }; for (char i = 'A'; i <= 'Z'; i++) { specialCharacters[i.ToString()] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX } } ; for (char i = '0'; i <= '9'; i++) { specialCharacters[i.ToString()] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX } } ; specialCharacters["~"] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX }; foreach (var specialChar in specialCharacters.Values) { if (specialChar.Bmp != null) { specialChar.Width = (int)g.GetBitmapWidth(specialChar.Bmp); } specialChar.Height = tooltipSpecialCharSizeY; } }
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); 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.Clear(ThemeBase.DarkGreyFillColor1); g.DrawLine(0, 0, 0, Height, theme.BlackBrush); int actualWidth = Width - scrollBarSizeX; int y = -scrollY; foreach (var button in buttons) { var icon = button.GetIcon(); g.PushTranslation(0, y); g.FillAndDrawRectangle(0, 0, actualWidth, buttonSizeY, g.GetVerticalGradientBrush(button.GetColor(), buttonSizeY, 0.8f), theme.BlackBrush); var leftPadding = 0; if (App.Project.NeedsExpansionInstruments && (button.type == ButtonType.Instrument || button.type == ButtonType.Song)) { var tabColor = button.instrument != null && button.instrument.IsExpansionInstrument ? ThemeBase.MediumGreyFillColor1 : ThemeBase.LightGreyFillColor1; g.FillRectangle(1, 1, 1 + expansionTypeSizeX, buttonSizeY, g.GetVerticalGradientBrush(tabColor, buttonSizeY, 0.8f)); g.PushTranslation(1 + expansionTypeSizeX, 0); g.DrawLine(0, 0, 0, buttonSizeY, theme.BlackBrush); leftPadding = expansionTypeSizeX; } g.DrawText(button.GetText(App.Project), button.GetFont(selectedSong, selectedInstrument), icon == null ? buttonTextNoIconPosX : buttonTextPosX, buttonTextPosY, theme.BlackBrush, actualWidth - buttonTextNoIconPosX * 2); if (icon != null) { g.DrawBitmap(icon, buttonIconPosX, buttonIconPosY); } var subButtons = button.GetSubButtons(out var active); if (subButtons != null) { for (int i = 0, x = actualWidth - subButtonSpacingX - leftPadding; i < subButtons.Length; i++, x -= subButtonSpacingX) { g.DrawBitmap(button.GetIcon(subButtons[i]), x, subButtonPosY, active[i] ? 1.0f : 0.2f); } } if (leftPadding != 0) { g.PopTransform(); } g.PopTransform(); y += buttonSizeY; } if (needsScrollBar) { int virtualSizeY = this.virtualSizeY; int scrollBarSizeY = (int)Math.Round(Height * (Height / (float)virtualSizeY)); int scrollBarPosY = (int)Math.Round(Height * (scrollY / (float)virtualSizeY)); g.FillAndDrawRectangle(actualWidth, 0, Width - 1, Height, theme.DarkGreyFillBrush1, theme.BlackBrush); g.FillAndDrawRectangle(actualWidth, scrollBarPosY, Width - 1, scrollBarPosY + scrollBarSizeY, theme.LightGreyFillBrush1, theme.BlackBrush); } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); toolbarBrush = g.CreateVerticalGradientBrush(0, Height, ThemeBase.DarkGreyFillColor2, ThemeBase.DarkGreyFillColor1); warningBrush = g.CreateSolidBrush(System.Drawing.Color.FromArgb(205, 77, 64)); bmpLoopNone = g.CreateBitmapFromResource("LoopNone"); bmpLoopSong = g.CreateBitmapFromResource("Loop"); bmpLoopPattern = g.CreateBitmapFromResource("LoopPattern"); bmpPlay = g.CreateBitmapFromResource("Play"); bmpPause = g.CreateBitmapFromResource("Pause"); bmpNtsc = g.CreateBitmapFromResource("NTSC"); bmpPal = g.CreateBitmapFromResource("PAL"); bmpNtscToPal = g.CreateBitmapFromResource("NTSCToPAL"); bmpPalToNtsc = g.CreateBitmapFromResource("PALToNTSC"); bmpRec = g.CreateBitmapFromResource("Rec"); bmpRecRed = g.CreateBitmapFromResource("RecRed"); buttons[ButtonNew] = new Button { Bmp = g.CreateBitmapFromResource("File"), Click = OnNew }; buttons[ButtonOpen] = new Button { Bmp = g.CreateBitmapFromResource("Open"), Click = OnOpen }; buttons[ButtonSave] = new Button { Bmp = g.CreateBitmapFromResource("Save"), Click = OnSave, RightClick = OnSaveAs }; buttons[ButtonExport] = new Button { Bmp = g.CreateBitmapFromResource("Export"), Click = OnExport, RightClick = OnRepeatLastExport }; buttons[ButtonCopy] = new Button { Bmp = g.CreateBitmapFromResource("Copy"), Click = OnCopy, Enabled = OnCopyEnabled }; buttons[ButtonCut] = new Button { Bmp = g.CreateBitmapFromResource("Cut"), Click = OnCut, Enabled = OnCutEnabled }; buttons[ButtonPaste] = new Button { Bmp = g.CreateBitmapFromResource("Paste"), Click = OnPaste, RightClick = OnPasteSpecial, Enabled = OnPasteEnabled }; buttons[ButtonUndo] = new Button { Bmp = g.CreateBitmapFromResource("Undo"), Click = OnUndo, Enabled = OnUndoEnabled }; buttons[ButtonRedo] = new Button { Bmp = g.CreateBitmapFromResource("Redo"), Click = OnRedo, Enabled = OnRedoEnabled }; buttons[ButtonTransform] = new Button { Bmp = g.CreateBitmapFromResource("Transform"), Click = OnTransform }; buttons[ButtonConfig] = new Button { Bmp = g.CreateBitmapFromResource("Config"), Click = OnConfig }; buttons[ButtonPlay] = new Button { Click = OnPlay, GetBitmap = OnPlayGetBitmap }; buttons[ButtonRec] = new Button { GetBitmap = OnRecordGetBitmap, Click = OnRecord }; buttons[ButtonRewind] = new Button { Bmp = g.CreateBitmapFromResource("Rewind"), Click = OnRewind }; buttons[ButtonLoop] = new Button { Click = OnLoop, GetBitmap = OnLoopGetBitmap }; buttons[ButtonQwerty] = new Button { Bmp = g.CreateBitmapFromResource("QwertyPiano"), Click = OnQwerty, Enabled = OnQwertyEnabled }; buttons[ButtonMachine] = new Button { Click = OnMachine, GetBitmap = OnMachineGetBitmap, Enabled = OnMachineEnabled }; buttons[ButtonFollow] = new Button { Bmp = g.CreateBitmapFromResource("Follow"), Click = OnFollow, Enabled = OnFollowEnabled }; buttons[ButtonHelp] = new Button { Bmp = g.CreateBitmapFromResource("Help"), RightAligned = true, Click = OnHelp }; buttons[ButtonNew].ToolTip = "{MouseLeft} New Project {Ctrl} {N}"; buttons[ButtonOpen].ToolTip = "{MouseLeft} Open Project {Ctrl} {O}"; buttons[ButtonSave].ToolTip = "{MouseLeft} Save Project {Ctrl} {S} - {MouseRight} Save As..."; buttons[ButtonExport].ToolTip = "{MouseLeft} Export to various formats {Ctrl} {E}\n{MouseRight} Repeat last export {Ctrl} {Shift} {E}"; buttons[ButtonCopy].ToolTip = "{MouseLeft} Copy selection {Ctrl} {C}"; buttons[ButtonCut].ToolTip = "{MouseLeft} Cut selection {Ctrl} {X}"; buttons[ButtonPaste].ToolTip = "{MouseLeft} Paste {Ctrl} {V}\n{MouseRight} Paste Special... {Ctrl} {Shift} {V}"; buttons[ButtonUndo].ToolTip = "{MouseLeft} Undo {Ctrl} {Z}"; buttons[ButtonRedo].ToolTip = "{MouseLeft} Redo {Ctrl} {Y}"; buttons[ButtonTransform].ToolTip = "{MouseLeft} Perform cleanup and various operations"; buttons[ButtonConfig].ToolTip = "{MouseLeft} Edit Application Settings"; buttons[ButtonPlay].ToolTip = "{MouseLeft} Play/Pause {Space} - Play from start of pattern {Ctrl} {Space}\nPlay from start of song {Shift} {Space} - Play from loop point {Ctrl} {Shift} {Space}"; buttons[ButtonRewind].ToolTip = "{MouseLeft} Rewind {Home}\nRewind to beginning of current pattern {Ctrl} {Home}"; buttons[ButtonRec].ToolTip = "{MouseLeft} Toggles recording mode {Enter}\nAbort recording {Esc}"; buttons[ButtonLoop].ToolTip = "{MouseLeft} Toggle Loop Mode"; buttons[ButtonQwerty].ToolTip = "{MouseLeft} Toggle QWERTY keyboard piano input"; buttons[ButtonMachine].ToolTip = "{MouseLeft} Toggle between NTSC/PAL playback mode"; buttons[ButtonFollow].ToolTip = "{MouseLeft} Toggle follow mode {Shift} {F}"; buttons[ButtonHelp].ToolTip = "{MouseLeft} Online documentation"; UpdateButtonLayout(); var scaling = RenderTheme.MainWindowScaling; timecodePosY = (int)(DefaultTimecodePosY * scaling); timecodeSizeX = (int)(DefaultTimecodeSizeX * scaling); tooltipSingleLinePosY = (int)(DefaultTooltipSingleLinePosY * scaling); tooltipMultiLinePosY = (int)(DefaultTooltipMultiLinePosY * scaling); tooltipLineSizeY = (int)(DefaultTooltipLineSizeY * scaling); tooltipSpecialCharSizeX = (int)(DefaultTooltipSpecialCharSizeX * scaling); tooltipSpecialCharSizeY = (int)(DefaultTooltipSpecialCharSizeY * scaling); specialCharacters["Shift"] = new TooltipSpecialCharacter { Width = (int)(32 * scaling) }; specialCharacters["Space"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Home"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Ctrl"] = new TooltipSpecialCharacter { Width = (int)(28 * scaling) }; specialCharacters["Alt"] = new TooltipSpecialCharacter { Width = (int)(24 * scaling) }; specialCharacters["Enter"] = new TooltipSpecialCharacter { Width = (int)(38 * scaling) }; specialCharacters["Esc"] = new TooltipSpecialCharacter { Width = (int)(24 * scaling) }; specialCharacters["Del"] = new TooltipSpecialCharacter { Width = (int)(24 * scaling) }; specialCharacters["Drag"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("Drag"), OffsetY = 2 * scaling }; specialCharacters["MouseLeft"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseLeft"), OffsetY = 2 * scaling }; specialCharacters["MouseRight"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseRight"), OffsetY = 2 * scaling }; specialCharacters["MouseWheel"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("MouseWheel"), OffsetY = 2 * scaling }; specialCharacters["Warning"] = new TooltipSpecialCharacter { Bmp = g.CreateBitmapFromResource("Warning") }; for (char i = 'A'; i <= 'Z'; i++) { specialCharacters[i.ToString()] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX } } ; for (char i = '0'; i <= '9'; i++) { specialCharacters[i.ToString()] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX } } ; specialCharacters["~"] = new TooltipSpecialCharacter { Width = tooltipSpecialCharSizeX }; foreach (var specialChar in specialCharacters.Values) { if (specialChar.Bmp != null) { specialChar.Width = (int)g.GetBitmapWidth(specialChar.Bmp); } specialChar.Height = tooltipSpecialCharSizeY; } }
private unsafe RenderBitmap GetPatternBitmapFromCache(RenderGraphics g, Pattern p) { int patternSizeX = Song.PatternLength - 1; int patternSizeY = trackSizeY - patternHeaderSizeY - 1; RenderBitmap bmp; if (patternBitmapCache.TryGetValue(p.Id, out bmp)) { if (bmp.Size.Width == patternSizeX) { return(bmp); } else { patternBitmapCache.Remove(p.Id); bmp.Dispose(); bmp = null; } } uint[] data = new uint[patternSizeX * patternSizeY]; Note minNote; Note maxNote; if (p.GetMinMaxNote(out minNote, out maxNote)) { if (maxNote.Value == minNote.Value) { minNote.Value = (byte)(minNote.Value - 5); maxNote.Value = (byte)(maxNote.Value + 5); } else { minNote.Value = (byte)(minNote.Value - 2); maxNote.Value = (byte)(maxNote.Value + 2); } Note lastValid = new Note { Value = Note.NoteInvalid }; for (int i = 0; i < Song.PatternLength - 1; i++) // TODO: We always skip the last note. { var n = p.Notes[i]; if (n.IsValid && !n.IsStop) { lastValid = p.Notes[i]; } if (lastValid.IsValid) { float scaleY = (patternSizeY - noteSizeY) / (float)patternSizeY; int x = i; int y = Math.Min((int)Math.Round((lastValid.Value - minNote.Value) / (float)(maxNote.Value - minNote.Value) * scaleY * patternSizeY), patternSizeY - noteSizeY); var instrument = lastValid.Instrument; var color = instrument == null ? ThemeBase.LightGreyFillColor1 : instrument.Color; for (int j = 0; j < noteSizeY; j++) { data[(patternSizeY - 1 - (y + j)) * patternSizeX + x] = (uint)color.ToArgb(); } } //if (n.HasEffect) //{ // for (int y = 0; y < patternSizeY; y++) // { // data[y * patternSizeX + i] = 0xff000000; // } //} } } bmp = g.CreateBitmap(patternSizeX, patternSizeY, data); patternBitmapCache[p.Id] = bmp; return(bmp); }
protected override void OnRender(RenderGraphics g) { g.Clear(ThemeBase.DarkGreyFillColor1); int patternSizeX = PatternSizeX; int minVisiblePattern = Math.Max((int)Math.Floor(scrollX / (float)patternSizeX), 0); int maxVisiblePattern = Math.Min((int)Math.Ceiling((scrollX + Width) / (float)patternSizeX), Song.Length); // Track name background g.FillRectangle(0, 0, trackNameSizeX, Height, whiteKeyBrush); // Header g.DrawLine(0, 0, Width, 0, theme.BlackBrush); g.DrawLine(trackNameSizeX - 1, 0, trackNameSizeX - 1, headerSizeY, theme.DarkGreyLineBrush1); g.PushTranslation(trackNameSizeX, 0); g.PushClip(0, 0, Width, Height); for (int i = minVisiblePattern, x = minVisiblePattern * patternSizeX - scrollX; i <= maxVisiblePattern; i++, x += patternSizeX) { if (i != 0) { g.DrawLine(x, 0, x, Height, theme.DarkGreyLineBrush1); } } for (int i = minVisiblePattern, x = minVisiblePattern * patternSizeX - scrollX; i < maxVisiblePattern; i++, x += patternSizeX) { g.PushTranslation(x, 0); g.DrawText(i.ToString(), ThemeBase.FontMediumCenter, 0, barTextPosY, theme.LightGreyFillBrush1, patternSizeX); g.PopTransform(); } g.PopClip(); g.PopTransform(); g.PushTranslation(0, headerSizeY); // Icons for (int i = 0, y = 0; i < Song.Channels.Length; i++, y += trackSizeY) { g.DrawBitmap(bmpTracks[(int)Song.Channels[i].Type], trackIconPosX, y + trackIconPosY, RenderTheme.MainWindowScaling, (App.ChannelMask & (1 << i)) != 0 ? 1.0f : 0.2f); } // Track names for (int i = 0, y = 0; i < Song.Channels.Length; i++, y += trackSizeY) { g.DrawText(Song.Channels[i].Name, i == selectedChannel ? ThemeBase.FontMediumBold : ThemeBase.FontMedium, trackNamePosX, y + trackNamePosY, theme.BlackBrush); } // Ghost note icons for (int i = 0, y = 0; i < Song.Channels.Length; i++, y += trackSizeY) { g.DrawBitmap(bmpGhostNote, trackNameSizeX - ghostNoteOffsetX, y + trackSizeY - ghostNoteOffsetY - 1, RenderTheme.MainWindowScaling, (App.GhostChannelMask & (1 << i)) != 0 ? 1.0f : 0.2f); } // Vertical line seperating the track labels. g.DrawLine(trackNameSizeX - 1, 0, trackNameSizeX - 1, Height, theme.DarkGreyLineBrush1); // Grey background rectangles ever other pattern + vertical lines g.PushClip(trackNameSizeX, 0, Width, Height); g.PushTranslation(trackNameSizeX, 0); for (int i = minVisiblePattern, x = minVisiblePattern * patternSizeX - scrollX; i < maxVisiblePattern; i++, x += patternSizeX) { if ((i & 1) == 0) { g.FillRectangle(x, 0, x + patternSizeX, Height, theme.DarkGreyFillBrush2); } } for (int i = minVisiblePattern, x = minVisiblePattern * patternSizeX - scrollX; i <= maxVisiblePattern; i++, x += patternSizeX) { if (i != 0) { g.DrawLine(x, 0, x, Height, theme.DarkGreyLineBrush1); } } g.PopTransform(); g.PopClip(); // Horizontal lines for (int i = 0, y = 0; i < Song.Channels.Length; i++, y += trackSizeY) { g.DrawLine(0, y, Width, y, theme.DarkGreyLineBrush1); } g.PushClip(trackNameSizeX, 0, Width, Height); // Seek int xxx = ScaleForZoom(App.CurrentFrame) + trackNameSizeX - scrollX; g.DrawLine(xxx, -headerSizeY, xxx, Height, playPositionBrush); // Patterns for (int t = 0, y = 0; t < Song.Channels.Length; t++, y += trackSizeY) { for (int i = minVisiblePattern, x = minVisiblePattern * patternSizeX + trackNameSizeX - scrollX; i < maxVisiblePattern; i++, x += patternSizeX) { var pattern = Song.Channels[t].PatternInstances[i]; if (pattern != null) { var bmp = GetPatternBitmapFromCache(g, pattern); g.PushTranslation(x, y); g.FillRectangle(1, 1, patternSizeX, patternHeaderSizeY, g.GetVerticalGradientBrush(pattern.Color, patternHeaderSizeY - 1, 0.9f)); g.DrawLine(0, patternHeaderSizeY, patternSizeX, patternHeaderSizeY, theme.DarkGreyLineBrush1); if (IsPatternSelected(t, i)) { g.FillRectangle(1, 1 + patternHeaderSizeY, PatternSizeX, patternHeaderSizeY + bmp.Size.Height + 1, selectedPatternBrush); } g.DrawBitmap(bmp, 1, 1 + patternHeaderSizeY, PatternSizeX - 1, bmp.Size.Height, 1.0f); g.PushClip(0, 0, PatternSizeX, trackSizeY); g.DrawText(pattern.Name, ThemeBase.FontSmall, patternNamePosX, patternNamePosY, theme.BlackBrush); g.PopClip(); g.PopTransform(); } } } // Dragging selection if (isDraggingSelection) { var pt = this.PointToClient(Cursor.Position); //pt.X -= TrackNameSizeX; pt.Y -= headerSizeY; var drawX = pt.X - selectionDragAnchorX; var drawY = minSelectedChannelIdx * trackSizeY; var sizeX = (maxSelectedPatternIdx - minSelectedPatternIdx + 1) * patternSizeX; var sizeY = (maxSelectedChannelIdx - minSelectedChannelIdx + 1) * trackSizeY; g.FillRectangle(drawX, drawY, drawX + sizeX, drawY + sizeY, selectedPatternBrush); } g.PopClip(); g.PopTransform(); g.DrawLine(0, Height - 1, Width, Height - 1, theme.DarkGreyLineBrush1); }
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; } } }
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; } } }