Fix toolstrip textbox scaling, browse button alignment, and WebBrowser optical zoom
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using Markdig;
|
using Markdig;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -23,6 +23,10 @@ namespace hMarkdown
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
this.DragEnter += Form1_DragEnter;
|
this.DragEnter += Form1_DragEnter;
|
||||||
this.Resize += Form1_Resize;
|
this.Resize += Form1_Resize;
|
||||||
|
this.Load += (s, e) => AdjustDosyaTextBoxWidth();
|
||||||
|
|
||||||
|
InitializeCustomControls();
|
||||||
|
SetMode(false);
|
||||||
|
|
||||||
if (fn.Length>0) {
|
if (fn.Length>0) {
|
||||||
tbDosya.Text = fn;
|
tbDosya.Text = fn;
|
||||||
@@ -32,8 +36,7 @@ namespace hMarkdown
|
|||||||
|
|
||||||
private void Form1_Resize(object sender, EventArgs e)
|
private void Form1_Resize(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (this.Width > 200)
|
AdjustDosyaTextBoxWidth();
|
||||||
tbDosya.Width = this.Width - 250;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Form1_DragEnter(object sender, DragEventArgs e)
|
private void Form1_DragEnter(object sender, DragEventArgs e)
|
||||||
@@ -50,6 +53,7 @@ namespace hMarkdown
|
|||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
RenderHtml();
|
RenderHtml();
|
||||||
|
UpdateStatusBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderHtml()
|
private void RenderHtml()
|
||||||
@@ -67,6 +71,11 @@ namespace hMarkdown
|
|||||||
<script src=""https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.5/highlight.min.js""></script>
|
<script src=""https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.5/highlight.min.js""></script>
|
||||||
<script>hljs.initHighlightingOnLoad();</script>
|
<script>hljs.initHighlightingOnLoad();</script>
|
||||||
<style>
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
.markdown-body {
|
.markdown-body {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
@@ -83,9 +92,11 @@ namespace hMarkdown
|
|||||||
img { max-width: 100%; }
|
img { max-width: 100%; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class=""markdown-body"">";
|
<body>
|
||||||
|
<div class=""markdown-body"">";
|
||||||
|
|
||||||
result = bas + result + @"
|
result = bas + result + @"
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>";
|
</html>";
|
||||||
webBrowser.DocumentText = result;
|
webBrowser.DocumentText = result;
|
||||||
@@ -123,16 +134,11 @@ namespace hMarkdown
|
|||||||
{
|
{
|
||||||
if (rtbEditor.Visible)
|
if (rtbEditor.Visible)
|
||||||
{
|
{
|
||||||
rtbEditor.Visible = false;
|
SetMode(false);
|
||||||
webBrowser.Visible = true;
|
|
||||||
tbEdit.Text = "Düzenle";
|
|
||||||
RenderHtml();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rtbEditor.Visible = true;
|
SetMode(true);
|
||||||
webBrowser.Visible = false;
|
|
||||||
tbEdit.Text = "Görüntüle";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +150,7 @@ namespace hMarkdown
|
|||||||
{
|
{
|
||||||
File.WriteAllText(tbDosya.Text, rtbEditor.Text);
|
File.WriteAllText(tbDosya.Text, rtbEditor.Text);
|
||||||
MessageBox.Show("Dosya kaydedildi.");
|
MessageBox.Show("Dosya kaydedildi.");
|
||||||
|
SetMode(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -187,5 +194,691 @@ namespace hMarkdown
|
|||||||
DosyaAc();
|
DosyaAc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- CUSTOM IMPLEMENTATION ---
|
||||||
|
private ToolStripStatusLabel lblCharCount;
|
||||||
|
private ToolStripStatusLabel lblFormat;
|
||||||
|
private ToolStripStatusLabel lblEncoding;
|
||||||
|
private TrackBar zoomTrackBar;
|
||||||
|
private ToolStripButton btnStatusZoomOut;
|
||||||
|
private ToolStripButton btnStatusZoomIn;
|
||||||
|
private ToolStripStatusLabel lblStatusZoomText;
|
||||||
|
private float currentZoom = 1.0f;
|
||||||
|
private bool isAdjustingWidth = false;
|
||||||
|
|
||||||
|
private void InitializeCustomControls()
|
||||||
|
{
|
||||||
|
// 1. StatusStrip
|
||||||
|
statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||||
|
|
||||||
|
lblCharCount = new ToolStripStatusLabel();
|
||||||
|
lblCharCount.Text = "Karakter: 0";
|
||||||
|
|
||||||
|
ToolStripStatusLabel spacer = new ToolStripStatusLabel();
|
||||||
|
spacer.Spring = true;
|
||||||
|
spacer.Text = "";
|
||||||
|
|
||||||
|
lblFormat = new ToolStripStatusLabel();
|
||||||
|
lblFormat.Text = "Biçim: Markdown";
|
||||||
|
lblFormat.Margin = new Padding(10, 3, 10, 2);
|
||||||
|
|
||||||
|
lblEncoding = new ToolStripStatusLabel();
|
||||||
|
lblEncoding.Text = "Kodlama: UTF-8";
|
||||||
|
lblEncoding.Margin = new Padding(10, 3, 10, 2);
|
||||||
|
|
||||||
|
// TrackBar control for Zooming
|
||||||
|
zoomTrackBar = new TrackBar();
|
||||||
|
zoomTrackBar.Minimum = 50;
|
||||||
|
zoomTrackBar.Maximum = 300;
|
||||||
|
zoomTrackBar.Value = 100;
|
||||||
|
zoomTrackBar.TickStyle = TickStyle.None;
|
||||||
|
zoomTrackBar.AutoSize = false;
|
||||||
|
zoomTrackBar.Height = 16;
|
||||||
|
zoomTrackBar.Width = 100;
|
||||||
|
zoomTrackBar.BackColor = SystemColors.Control;
|
||||||
|
zoomTrackBar.Scroll += (s, e) => SetZoom(zoomTrackBar.Value / 100f);
|
||||||
|
|
||||||
|
var trackBarHost = new ToolStripControlHost(zoomTrackBar);
|
||||||
|
trackBarHost.Margin = new Padding(5, 2, 5, 2);
|
||||||
|
|
||||||
|
btnStatusZoomOut = new ToolStripButton("➖");
|
||||||
|
btnStatusZoomOut.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||||
|
btnStatusZoomOut.Click += (s, e) => SetZoom(currentZoom - 0.1f);
|
||||||
|
|
||||||
|
btnStatusZoomIn = new ToolStripButton("➕");
|
||||||
|
btnStatusZoomIn.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||||
|
btnStatusZoomIn.Click += (s, e) => SetZoom(currentZoom + 0.1f);
|
||||||
|
|
||||||
|
lblStatusZoomText = new ToolStripStatusLabel("%100");
|
||||||
|
lblStatusZoomText.Margin = new Padding(5, 3, 5, 2);
|
||||||
|
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] {
|
||||||
|
lblCharCount,
|
||||||
|
spacer,
|
||||||
|
lblFormat,
|
||||||
|
lblEncoding,
|
||||||
|
btnStatusZoomOut,
|
||||||
|
trackBarHost,
|
||||||
|
btnStatusZoomIn,
|
||||||
|
lblStatusZoomText
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. toolStripEditor
|
||||||
|
toolStripEditor.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||||
|
toolStripEditor.RenderMode = ToolStripRenderMode.Professional;
|
||||||
|
toolStripEditor.Visible = false;
|
||||||
|
|
||||||
|
// Menus
|
||||||
|
var menuDosya = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(menuDosya, "document", "Dosya");
|
||||||
|
var mDosyaAc = new ToolStripMenuItem("📂 Aç", null, (s, e) => tbGozat_Click(s, e));
|
||||||
|
var mDosyaKaydet = new ToolStripMenuItem("💾 Kaydet", null, (s, e) => tbSave_Click(s, e));
|
||||||
|
var mDosyaFarkliKaydet = new ToolStripMenuItem("💾 Farklı Kaydet...", null, (s, e) => DosyaFarkliKaydet());
|
||||||
|
var mDosyaKapat = new ToolStripMenuItem("❌ Kapat", null, (s, e) => DosyaKapat());
|
||||||
|
menuDosya.DropDownItems.AddRange(new ToolStripItem[] { mDosyaAc, mDosyaKaydet, mDosyaFarkliKaydet, new ToolStripSeparator(), mDosyaKapat });
|
||||||
|
|
||||||
|
var menuDuzen = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(menuDuzen, "edit", "Düzen");
|
||||||
|
var mDuzenUndo = new ToolStripMenuItem("↩️ Geri Al", null, (s, e) => { if (rtbEditor.CanUndo) rtbEditor.Undo(); });
|
||||||
|
var mDuzenRedo = new ToolStripMenuItem("↪️ İleri Al", null, (s, e) => { if (rtbEditor.CanRedo) rtbEditor.Redo(); });
|
||||||
|
var mDuzenCut = new ToolStripMenuItem("✂️ Kes", null, (s, e) => rtbEditor.Cut());
|
||||||
|
var mDuzenCopy = new ToolStripMenuItem("📋 Kopyala", null, (s, e) => rtbEditor.Copy());
|
||||||
|
var mDuzenPaste = new ToolStripMenuItem("📥 Yapıştır", null, (s, e) => rtbEditor.Paste());
|
||||||
|
var mDuzenSelectAll = new ToolStripMenuItem("🧹 Tümünü Seç", null, (s, e) => rtbEditor.SelectAll());
|
||||||
|
menuDuzen.DropDownItems.AddRange(new ToolStripItem[] { mDuzenUndo, mDuzenRedo, new ToolStripSeparator(), mDuzenCut, mDuzenCopy, mDuzenPaste, new ToolStripSeparator(), mDuzenSelectAll });
|
||||||
|
|
||||||
|
var menuGorunum = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(menuGorunum, "visible", "Görünüm");
|
||||||
|
var mGorunumZoomIn = new ToolStripMenuItem("➕ Yakınlaştır (%+)", null, (s, e) => ZoomIn());
|
||||||
|
var mGorunumZoomOut = new ToolStripMenuItem("➖ Uzaklaştır (%-)", null, (s, e) => ZoomOut());
|
||||||
|
var mGorunumZoomReset = new ToolStripMenuItem("🔄 Varsayılan Zoom (%100)", null, (s, e) => ZoomReset());
|
||||||
|
menuGorunum.DropDownItems.AddRange(new ToolStripItem[] { mGorunumZoomIn, mGorunumZoomOut, mGorunumZoomReset });
|
||||||
|
|
||||||
|
// Header Dropdown
|
||||||
|
var btnHeading = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(btnHeading, "heading", "Başlık");
|
||||||
|
for (int i = 1; i <= 6; i++)
|
||||||
|
{
|
||||||
|
int level = i;
|
||||||
|
btnHeading.DropDownItems.Add(new ToolStripMenuItem($"Başlık {level} (H{level})", null, (s, e) => InsertHeader(level)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lists Dropdown
|
||||||
|
var btnLists = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(btnLists, "list", "Liste & No");
|
||||||
|
btnLists.DropDownItems.Add(new ToolStripMenuItem("• Madde İşaretli Liste", null, (s, e) => InsertMarkdownPrefix("* ")));
|
||||||
|
btnLists.DropDownItems.Add(new ToolStripMenuItem("1. Numaralı Liste", null, (s, e) => InsertMarkdownPrefix("1. ")));
|
||||||
|
|
||||||
|
// Indent Dropdown
|
||||||
|
var btnIndent = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(btnIndent, "indent", "Girinti");
|
||||||
|
btnIndent.DropDownItems.Add(new ToolStripMenuItem("➡️ Girintiyi Arttır", null, (s, e) => InsertMarkdownPrefix(" ")));
|
||||||
|
btnIndent.DropDownItems.Add(new ToolStripMenuItem("⬅️ Girintiyi Azalt", null, (s, e) => DecreaseIndent()));
|
||||||
|
|
||||||
|
// Formatting Buttons
|
||||||
|
var btnBold = new ToolStripButton();
|
||||||
|
ConfigureEditorButton(btnBold, "bold", "Koyu");
|
||||||
|
btnBold.Click += (s, e) => WrapSelection("**", "**");
|
||||||
|
btnBold.Font = new Font(btnBold.Font, FontStyle.Bold);
|
||||||
|
|
||||||
|
var btnItalic = new ToolStripButton();
|
||||||
|
ConfigureEditorButton(btnItalic, "italic", "İtelik");
|
||||||
|
btnItalic.Click += (s, e) => WrapSelection("*", "*");
|
||||||
|
btnItalic.Font = new Font(btnItalic.Font, FontStyle.Italic);
|
||||||
|
|
||||||
|
var btnStrikethrough = new ToolStripButton();
|
||||||
|
ConfigureEditorButton(btnStrikethrough, "strikethrough", "Üstü Çizgili");
|
||||||
|
btnStrikethrough.Click += (s, e) => WrapSelection("~~", "~~");
|
||||||
|
|
||||||
|
var btnLink = new ToolStripButton();
|
||||||
|
ConfigureEditorButton(btnLink, "link", "Link");
|
||||||
|
btnLink.Click += (s, e) => InsertLink();
|
||||||
|
|
||||||
|
var btnClearFormatting = new ToolStripButton();
|
||||||
|
ConfigureEditorButton(btnClearFormatting, "eraser", "Temizle");
|
||||||
|
btnClearFormatting.Click += (s, e) => ClearFormatting();
|
||||||
|
|
||||||
|
// Table Dropdown
|
||||||
|
var btnTable = new ToolStripDropDownButton();
|
||||||
|
ConfigureEditorButton(btnTable, "table", "Tablo");
|
||||||
|
btnTable.DropDownItems.Add(new ToolStripMenuItem("2x2 Tablo", null, (s, e) => InsertTable(2, 2)));
|
||||||
|
btnTable.DropDownItems.Add(new ToolStripMenuItem("3x3 Tablo", null, (s, e) => InsertTable(3, 3)));
|
||||||
|
btnTable.DropDownItems.Add(new ToolStripMenuItem("4x3 Tablo", null, (s, e) => InsertTable(4, 3)));
|
||||||
|
btnTable.DropDownItems.Add(new ToolStripSeparator());
|
||||||
|
btnTable.DropDownItems.Add(new ToolStripMenuItem("Özel Tablo...", null, (s, e) => InsertCustomTable()));
|
||||||
|
|
||||||
|
// Add items to toolStripEditor
|
||||||
|
toolStripEditor.Items.AddRange(new ToolStripItem[] {
|
||||||
|
menuDosya,
|
||||||
|
menuDuzen,
|
||||||
|
menuGorunum,
|
||||||
|
new ToolStripSeparator(),
|
||||||
|
btnHeading,
|
||||||
|
btnLists,
|
||||||
|
btnIndent,
|
||||||
|
new ToolStripSeparator(),
|
||||||
|
btnBold,
|
||||||
|
btnItalic,
|
||||||
|
btnStrikethrough,
|
||||||
|
btnLink,
|
||||||
|
btnClearFormatting,
|
||||||
|
new ToolStripSeparator(),
|
||||||
|
btnTable
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reorganize toolStrip1 items for correct alignment
|
||||||
|
tbDosya.AutoSize = false;
|
||||||
|
tbDosya.Height = 22;
|
||||||
|
tbHelp.Alignment = ToolStripItemAlignment.Right;
|
||||||
|
tbSave.Alignment = ToolStripItemAlignment.Right;
|
||||||
|
tbEdit.Alignment = ToolStripItemAlignment.Right;
|
||||||
|
tbGozat.Alignment = ToolStripItemAlignment.Right;
|
||||||
|
|
||||||
|
toolStrip1.Items.Clear();
|
||||||
|
toolStrip1.Items.Add(toolStripLabel1);
|
||||||
|
toolStrip1.Items.Add(tbDosya);
|
||||||
|
toolStrip1.Items.Add(tbHelp);
|
||||||
|
toolStrip1.Items.Add(tbSave);
|
||||||
|
toolStrip1.Items.Add(tbEdit);
|
||||||
|
toolStrip1.Items.Add(tbGozat);
|
||||||
|
|
||||||
|
// Configure main toolstrip buttons with PNG icons
|
||||||
|
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
|
||||||
|
ConfigureMainButton(tbGozat, "opened-folder", "...");
|
||||||
|
ConfigureMainButton(tbSave, "save", "Kaydet");
|
||||||
|
ConfigureMainButton(tbHelp, "help", "Yardım");
|
||||||
|
ConfigureMainButton(tbEdit, "edit", "Düzenle");
|
||||||
|
|
||||||
|
rtbEditor.TextChanged += (s, e) => UpdateStatusBar();
|
||||||
|
rtbEditor.SelectionChanged += (s, e) => UpdateStatusBar();
|
||||||
|
|
||||||
|
webBrowser.DocumentCompleted += (s, e) => ApplyWebBrowserZoom();
|
||||||
|
|
||||||
|
UpdateZoomUI();
|
||||||
|
RefreshControlLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMode(bool editMode)
|
||||||
|
{
|
||||||
|
if (editMode)
|
||||||
|
{
|
||||||
|
rtbEditor.Visible = true;
|
||||||
|
webBrowser.Visible = false;
|
||||||
|
|
||||||
|
toolStripEditor.Visible = true;
|
||||||
|
tbSave.Visible = true;
|
||||||
|
tbHelp.Visible = true;
|
||||||
|
|
||||||
|
ConfigureMainButton(tbEdit, "visible", "Görüntüle");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rtbEditor.Visible = false;
|
||||||
|
webBrowser.Visible = true;
|
||||||
|
|
||||||
|
toolStripEditor.Visible = false;
|
||||||
|
tbSave.Visible = false;
|
||||||
|
tbHelp.Visible = false;
|
||||||
|
|
||||||
|
ConfigureMainButton(tbEdit, "edit", "Düzenle");
|
||||||
|
RenderHtml();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshControlLayout();
|
||||||
|
AdjustDosyaTextBoxWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshControlLayout()
|
||||||
|
{
|
||||||
|
this.SuspendLayout();
|
||||||
|
|
||||||
|
// 1-pixel separator line border styling
|
||||||
|
rtbEditor.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
|
||||||
|
// Absolute winforms docking z-order setup (from back to front):
|
||||||
|
// 1. Workspace content fill
|
||||||
|
rtbEditor.SendToBack();
|
||||||
|
webBrowser.SendToBack();
|
||||||
|
// 2. StatusStrip bottom
|
||||||
|
statusStrip1.SendToBack();
|
||||||
|
// 3. toolStripEditor below toolStrip1
|
||||||
|
if (toolStripEditor != null)
|
||||||
|
{
|
||||||
|
toolStripEditor.SendToBack();
|
||||||
|
}
|
||||||
|
// 4. toolStrip1 at very top edge
|
||||||
|
toolStrip1.SendToBack();
|
||||||
|
|
||||||
|
this.ResumeLayout(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void AdjustDosyaTextBoxWidth()
|
||||||
|
{
|
||||||
|
if (isAdjustingWidth) return;
|
||||||
|
if (toolStrip1 == null || tbDosya == null) return;
|
||||||
|
|
||||||
|
int totalWidth = toolStrip1.DisplayRectangle.Width;
|
||||||
|
if (totalWidth <= 0) return;
|
||||||
|
|
||||||
|
isAdjustingWidth = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int originalWidth = tbDosya.Width;
|
||||||
|
|
||||||
|
// Temporarily set tbDosya to a small width to allow other items to layout fully
|
||||||
|
tbDosya.Width = 50;
|
||||||
|
toolStrip1.PerformLayout();
|
||||||
|
|
||||||
|
int occupiedWidth = 0;
|
||||||
|
foreach (ToolStripItem item in toolStrip1.Items)
|
||||||
|
{
|
||||||
|
if (item != tbDosya && item.Visible)
|
||||||
|
{
|
||||||
|
occupiedWidth += item.Width + item.Margin.Horizontal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int newWidth = totalWidth - occupiedWidth - tbDosya.Margin.Horizontal - 25;
|
||||||
|
if (newWidth < 100) newWidth = 100;
|
||||||
|
|
||||||
|
if (tbDosya.Width != newWidth)
|
||||||
|
{
|
||||||
|
tbDosya.Width = newWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tbDosya.Width = originalWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
isAdjustingWidth = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStatusBar()
|
||||||
|
{
|
||||||
|
if (rtbEditor == null || lblCharCount == null) return;
|
||||||
|
int charCount = rtbEditor.Text.Length;
|
||||||
|
lblCharCount.Text = $"Karakter: {charCount}";
|
||||||
|
|
||||||
|
if (Math.Abs(rtbEditor.ZoomFactor - currentZoom) > 0.01f)
|
||||||
|
{
|
||||||
|
currentZoom = rtbEditor.ZoomFactor;
|
||||||
|
UpdateZoomUI();
|
||||||
|
ApplyWebBrowserZoom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetZoom(float zoomFactor)
|
||||||
|
{
|
||||||
|
currentZoom = Math.Max(0.5f, Math.Min(3.0f, zoomFactor));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rtbEditor.ZoomFactor = currentZoom;
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
|
||||||
|
ApplyWebBrowserZoom();
|
||||||
|
UpdateZoomUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateZoomUI()
|
||||||
|
{
|
||||||
|
if (zoomTrackBar != null)
|
||||||
|
{
|
||||||
|
int val = (int)(currentZoom * 100);
|
||||||
|
zoomTrackBar.Value = Math.Max(zoomTrackBar.Minimum, Math.Min(zoomTrackBar.Maximum, val));
|
||||||
|
}
|
||||||
|
if (lblStatusZoomText != null)
|
||||||
|
{
|
||||||
|
lblStatusZoomText.Text = $"%{(int)(currentZoom * 100)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DosyaFarkliKaydet()
|
||||||
|
{
|
||||||
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
sfd.Filter = "(*.md)|*.md|Tüm Dosyalar (*.*)|*.*";
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
tbDosya.Text = sfd.FileName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(tbDosya.Text, rtbEditor.Text);
|
||||||
|
MessageBox.Show("Dosya farklı kaydedildi.");
|
||||||
|
SetMode(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Hata: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DosyaKapat()
|
||||||
|
{
|
||||||
|
rtbEditor.Clear();
|
||||||
|
tbDosya.Text = "";
|
||||||
|
webBrowser.DocumentText = "";
|
||||||
|
UpdateStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ZoomIn()
|
||||||
|
{
|
||||||
|
SetZoom(currentZoom + 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ZoomOut()
|
||||||
|
{
|
||||||
|
SetZoom(currentZoom - 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ZoomReset()
|
||||||
|
{
|
||||||
|
SetZoom(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertMarkdownPrefix(string prefix)
|
||||||
|
{
|
||||||
|
int selectionStart = rtbEditor.SelectionStart;
|
||||||
|
int lineIndex = rtbEditor.GetLineFromCharIndex(selectionStart);
|
||||||
|
int lineStartCharIndex = rtbEditor.GetFirstCharIndexFromLine(lineIndex);
|
||||||
|
|
||||||
|
rtbEditor.Select(lineStartCharIndex, 0);
|
||||||
|
rtbEditor.SelectedText = prefix;
|
||||||
|
rtbEditor.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertHeader(int level)
|
||||||
|
{
|
||||||
|
string prefix = new string('#', level) + " ";
|
||||||
|
InsertMarkdownPrefix(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DecreaseIndent()
|
||||||
|
{
|
||||||
|
if (rtbEditor.Lines.Length == 0) return;
|
||||||
|
|
||||||
|
int selectionStart = rtbEditor.SelectionStart;
|
||||||
|
int lineIndex = rtbEditor.GetLineFromCharIndex(selectionStart);
|
||||||
|
if (lineIndex < 0 || lineIndex >= rtbEditor.Lines.Length) return;
|
||||||
|
|
||||||
|
int lineStartCharIndex = rtbEditor.GetFirstCharIndexFromLine(lineIndex);
|
||||||
|
string lineText = rtbEditor.Lines[lineIndex];
|
||||||
|
|
||||||
|
if (lineText.StartsWith(" "))
|
||||||
|
{
|
||||||
|
rtbEditor.Select(lineStartCharIndex, 4);
|
||||||
|
rtbEditor.SelectedText = "";
|
||||||
|
}
|
||||||
|
else if (lineText.StartsWith("\t"))
|
||||||
|
{
|
||||||
|
rtbEditor.Select(lineStartCharIndex, 1);
|
||||||
|
rtbEditor.SelectedText = "";
|
||||||
|
}
|
||||||
|
rtbEditor.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WrapSelection(string prefix, string suffix)
|
||||||
|
{
|
||||||
|
string selectedText = rtbEditor.SelectedText;
|
||||||
|
int selectionStart = rtbEditor.SelectionStart;
|
||||||
|
|
||||||
|
rtbEditor.SelectedText = prefix + selectedText + suffix;
|
||||||
|
rtbEditor.SelectionStart = selectionStart + prefix.Length;
|
||||||
|
rtbEditor.SelectionLength = selectedText.Length;
|
||||||
|
rtbEditor.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertLink()
|
||||||
|
{
|
||||||
|
string selectedText = rtbEditor.SelectedText;
|
||||||
|
string title = string.IsNullOrEmpty(selectedText) ? "Link Başlığı" : selectedText;
|
||||||
|
string url = Prompt.ShowDialog("Link URL'sini girin:", "Link Ekle");
|
||||||
|
if (!string.IsNullOrEmpty(url))
|
||||||
|
{
|
||||||
|
rtbEditor.SelectedText = $"[{title}]({url})";
|
||||||
|
}
|
||||||
|
rtbEditor.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearFormatting()
|
||||||
|
{
|
||||||
|
string text = rtbEditor.SelectedText;
|
||||||
|
if (string.IsNullOrEmpty(text)) return;
|
||||||
|
|
||||||
|
text = System.Text.RegularExpressions.Regex.Replace(text, @"(\*\*|\*|~~|`|_)", "");
|
||||||
|
var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
|
||||||
|
for (int i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
lines[i] = System.Text.RegularExpressions.Regex.Replace(lines[i], @"^(#+\s+|\*\s+|-\s+|\d+\.\s+)", "");
|
||||||
|
}
|
||||||
|
rtbEditor.SelectedText = string.Join(Environment.NewLine, lines);
|
||||||
|
rtbEditor.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertTable(int rows, int cols)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine();
|
||||||
|
for (int c = 1; c <= cols; c++)
|
||||||
|
{
|
||||||
|
sb.Append($"| Başlık {c} ");
|
||||||
|
}
|
||||||
|
sb.AppendLine("|");
|
||||||
|
for (int c = 1; c <= cols; c++)
|
||||||
|
{
|
||||||
|
sb.Append("| --- ");
|
||||||
|
}
|
||||||
|
sb.AppendLine("|");
|
||||||
|
for (int r = 1; r <= rows; r++)
|
||||||
|
{
|
||||||
|
for (int c = 1; c <= cols; c++)
|
||||||
|
{
|
||||||
|
sb.Append($"| Hücre {r},{c} ");
|
||||||
|
}
|
||||||
|
sb.AppendLine("|");
|
||||||
|
}
|
||||||
|
sb.AppendLine();
|
||||||
|
|
||||||
|
rtbEditor.SelectedText = sb.ToString();
|
||||||
|
rtbEditor.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertCustomTable()
|
||||||
|
{
|
||||||
|
string input = Prompt.ShowDialog("Satır ve Sütun sayısını girin (Örn: 3x4):", "Özel Tablo Ekle");
|
||||||
|
if (!string.IsNullOrEmpty(input))
|
||||||
|
{
|
||||||
|
var parts = input.Split('x');
|
||||||
|
if (parts.Length == 2 && int.TryParse(parts[0], out int rows) && int.TryParse(parts[1], out int cols))
|
||||||
|
{
|
||||||
|
InsertTable(rows, cols);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Geçersiz format. Lütfen 'SatırxSütun' şeklinde girin (örn. 3x3).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureEditorButton(ToolStripItem item, string iconName, string label)
|
||||||
|
{
|
||||||
|
item.Text = label;
|
||||||
|
item.ToolTipText = label;
|
||||||
|
|
||||||
|
System.Drawing.Image img = LoadIcon(iconName);
|
||||||
|
if (img != null)
|
||||||
|
{
|
||||||
|
item.Image = img;
|
||||||
|
item.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.Image = CreateEmojiImage(GetFallbackEmoji(iconName), 24);
|
||||||
|
item.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item is ToolStripButton btn)
|
||||||
|
{
|
||||||
|
btn.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
|
btn.ImageAlign = ContentAlignment.TopCenter;
|
||||||
|
btn.TextAlign = ContentAlignment.BottomCenter;
|
||||||
|
}
|
||||||
|
else if (item is ToolStripDropDownButton dd)
|
||||||
|
{
|
||||||
|
dd.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
|
dd.ImageAlign = ContentAlignment.TopCenter;
|
||||||
|
dd.TextAlign = ContentAlignment.BottomCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureMainButton(ToolStripItem item, string iconName, string label)
|
||||||
|
{
|
||||||
|
item.Text = label;
|
||||||
|
item.ToolTipText = label;
|
||||||
|
|
||||||
|
System.Drawing.Image img = LoadIcon(iconName);
|
||||||
|
if (img != null)
|
||||||
|
{
|
||||||
|
item.Image = img;
|
||||||
|
item.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.Text = GetFallbackEmoji(iconName) + " " + label;
|
||||||
|
item.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private System.Drawing.Image LoadIcon(string iconName)
|
||||||
|
{
|
||||||
|
string cacheDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "icons");
|
||||||
|
if (!Directory.Exists(cacheDir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(cacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
string localPath = Path.Combine(cacheDir, iconName + ".png");
|
||||||
|
if (!File.Exists(localPath))
|
||||||
|
{
|
||||||
|
string url = $"https://img.icons8.com/material-outlined/24/000000/{iconName}.png";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var webClient = new System.Net.WebClient())
|
||||||
|
{
|
||||||
|
webClient.DownloadFile(url, localPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return System.Drawing.Image.FromFile(localPath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFallbackEmoji(string iconName)
|
||||||
|
{
|
||||||
|
switch (iconName)
|
||||||
|
{
|
||||||
|
case "document": return "📄";
|
||||||
|
case "edit": return "✏️";
|
||||||
|
case "visible": return "👁️";
|
||||||
|
case "heading": return "🏷️";
|
||||||
|
case "list": return "📋";
|
||||||
|
case "indent": return "➡️";
|
||||||
|
case "bold": return "𝐁";
|
||||||
|
case "italic": return "𝘐";
|
||||||
|
case "strikethrough": return "̶S̶";
|
||||||
|
case "link": return "🔗";
|
||||||
|
case "eraser": return "🧼";
|
||||||
|
case "table": return "📅";
|
||||||
|
case "opened-folder": return "📂";
|
||||||
|
case "save": return "💾";
|
||||||
|
case "help": return "❓";
|
||||||
|
default: return "⚙️";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private System.Drawing.Image CreateEmojiImage(string emoji, int size)
|
||||||
|
{
|
||||||
|
Bitmap bmp = new Bitmap(size, size);
|
||||||
|
using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.Clear(Color.Transparent);
|
||||||
|
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
||||||
|
|
||||||
|
using (Font font = new Font("Segoe UI Emoji", 12, FontStyle.Regular, GraphicsUnit.Point))
|
||||||
|
{
|
||||||
|
var format = new StringFormat
|
||||||
|
{
|
||||||
|
Alignment = StringAlignment.Center,
|
||||||
|
LineAlignment = StringAlignment.Center
|
||||||
|
};
|
||||||
|
g.DrawString(emoji, font, Brushes.Black, new RectangleF(0, 0, size, size), format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple nested modal input prompt helper
|
||||||
|
public static class Prompt
|
||||||
|
{
|
||||||
|
public static string ShowDialog(string text, string caption)
|
||||||
|
{
|
||||||
|
Form prompt = new Form()
|
||||||
|
{
|
||||||
|
Width = 400,
|
||||||
|
Height = 150,
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog,
|
||||||
|
Text = caption,
|
||||||
|
StartPosition = FormStartPosition.CenterParent,
|
||||||
|
MaximizeBox = false,
|
||||||
|
MinimizeBox = false
|
||||||
|
};
|
||||||
|
Label textLabel = new Label() { Left = 20, Top = 20, Text = text, Width = 350 };
|
||||||
|
TextBox textBox = new TextBox() { Left = 20, Top = 45, Width = 350 };
|
||||||
|
Button confirmation = new Button() { Text = "Tamam", Left = 270, Width = 100, Top = 80, DialogResult = DialogResult.OK };
|
||||||
|
confirmation.Click += (sender, e) => { prompt.Close(); };
|
||||||
|
prompt.Controls.Add(textBox);
|
||||||
|
prompt.Controls.Add(confirmation);
|
||||||
|
prompt.Controls.Add(textLabel);
|
||||||
|
prompt.AcceptButton = confirmation;
|
||||||
|
return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyWebBrowserZoom()
|
||||||
|
{
|
||||||
|
if (webBrowser == null || webBrowser.Document == null) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int zoomPercent = (int)(currentZoom * 100);
|
||||||
|
object ax = webBrowser.ActiveXInstance;
|
||||||
|
ax.GetType().InvokeMember(
|
||||||
|
"ExecWB",
|
||||||
|
System.Reflection.BindingFlags.InvokeMethod,
|
||||||
|
null,
|
||||||
|
ax,
|
||||||
|
new object[] { 63, 2, zoomPercent, null }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user