Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Notepads/Controls/TextEditor/ITextEditor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2019-2024, Jiaqi (0x7c13) Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -74,6 +74,8 @@ void Init(TextFile textFile,

string GetText();

string GetSelectedText();

void StartCheckingFileStatusPeriodically();

void StopCheckingFileStatus();
Expand Down
9 changes: 8 additions & 1 deletion src/Notepads/Controls/TextEditor/TextEditor.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Notepads.Controls.TextEditor
namespace Notepads.Controls.TextEditor
{
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -312,6 +312,13 @@ public string GetText()
return TextEditorCore.GetText();
}

public string GetSelectedText()
{
return TextEditorCore.Document.Selection.StartPosition == TextEditorCore.Document.Selection.EndPosition
? string.Empty
: TextEditorCore.Document.Selection.Text;
}

// Make sure this method is thread safe
public TextEditorStateMetaData GetTextEditorStateMetaData()
{
Expand Down
3 changes: 2 additions & 1 deletion src/Notepads/Core/INotepadsCore.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2019-2024, Jiaqi (0x7c13) Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -31,6 +31,7 @@ public interface INotepadsCore
event EventHandler<ITextEditor> TextEditorFontZoomFactorChanged;
event EventHandler<ITextEditor> TextEditorEncodingChanged;
event EventHandler<ITextEditor> TextEditorLineEndingChanged;
event EventHandler<ITextEditor> TextEditorTextChanging;
event EventHandler<ITextEditor> TextEditorModeChanged;
event EventHandler<ITextEditor> TextEditorMovedToAnotherAppInstance;
event EventHandler<IReadOnlyList<IStorageItem>> StorageItemsDropped;
Expand Down
11 changes: 10 additions & 1 deletion src/Notepads/Core/NotepadsCore.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2019-2024, Jiaqi (0x7c13) Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -42,6 +42,7 @@ public class NotepadsCore : INotepadsCore
public event EventHandler<ITextEditor> TextEditorFontZoomFactorChanged;
public event EventHandler<ITextEditor> TextEditorEncodingChanged;
public event EventHandler<ITextEditor> TextEditorLineEndingChanged;
public event EventHandler<ITextEditor> TextEditorTextChanging;
public event EventHandler<ITextEditor> TextEditorModeChanged;
public event EventHandler<ITextEditor> TextEditorMovedToAnotherAppInstance;
public event EventHandler<IReadOnlyList<IStorageItem>> StorageItemsDropped;
Expand Down Expand Up @@ -199,6 +200,7 @@ public ITextEditor CreateTextEditor(
textEditor.Loaded += TextEditor_Loaded;
textEditor.Unloaded += TextEditor_Unloaded;
textEditor.SelectionChanged += TextEditor_OnSelectionChanged;
textEditor.TextChanging += TextEditor_OnTextChanging;
textEditor.FontZoomFactorChanged += TextEditor_OnFontZoomFactorChanged;
textEditor.KeyDown += TextEditorKeyDown;
textEditor.ModificationStateChanged += TextEditor_OnEditorModificationStateChanged;
Expand Down Expand Up @@ -238,6 +240,7 @@ public void DeleteTextEditor(ITextEditor textEditor)
textEditor.Unloaded -= TextEditor_Unloaded;
textEditor.KeyDown -= TextEditorKeyDown;
textEditor.SelectionChanged -= TextEditor_OnSelectionChanged;
textEditor.TextChanging -= TextEditor_OnTextChanging;
textEditor.FontZoomFactorChanged -= TextEditor_OnFontZoomFactorChanged;
textEditor.ModificationStateChanged -= TextEditor_OnEditorModificationStateChanged;
textEditor.ModeChanged -= TextEditor_OnModeChanged;
Expand Down Expand Up @@ -521,6 +524,12 @@ private void TextEditor_OnSelectionChanged(object sender, EventArgs e)
TextEditorSelectionChanged?.Invoke(this, textEditor);
}

private void TextEditor_OnTextChanging(object sender, EventArgs e)
{
if (!(sender is ITextEditor textEditor)) return;
TextEditorTextChanging?.Invoke(this, textEditor);
}

private void TextEditor_OnFontZoomFactorChanged(object sender, EventArgs e)
{
if (!(sender is ITextEditor textEditor)) return;
Expand Down
62 changes: 61 additions & 1 deletion src/Notepads/Views/MainPage/NotepadsMainPage.StatusBar.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2019-2024, Jiaqi (0x7c13) Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -40,6 +40,7 @@ private void SetupStatusBar(ITextEditor textEditor)
UpdatePathIndicator(textEditor);
UpdateEditorModificationIndicator(textEditor);
UpdateLineColumnIndicator(textEditor);
UpdateWordCountIndicator(textEditor);
UpdateFontZoomIndicator(textEditor);
UpdateLineEndingIndicator(textEditor.GetLineEnding());
UpdateEncodingIndicator(textEditor.GetEncoding());
Expand Down Expand Up @@ -161,6 +162,65 @@ private void UpdateLineColumnIndicator(ITextEditor textEditor)
selectedCount, wordSelected);
}

private void UpdateWordCountIndicator(ITextEditor textEditor)
{
if (StatusBar == null) return;

var fullText = textEditor.GetText();
var totalWordCount = CountWords(fullText);

var selectedText = textEditor.GetSelectedText();
if (!string.IsNullOrEmpty(selectedText))
{
var selectedWordCount = CountWords(selectedText);
WordCountIndicator.Text = string.Format(
"Words: {0} | Selected: {1}",
totalWordCount.ToString("N0", CultureInfo.CurrentCulture),
selectedWordCount.ToString("N0", CultureInfo.CurrentCulture));
}
else
{
WordCountIndicator.Text = string.Format(
"Words: {0}",
totalWordCount.ToString("N0", CultureInfo.CurrentCulture));
}
}

/// <summary>
/// Counts words in the given text using character iteration for efficiency.
/// A word is defined as a contiguous sequence of non-whitespace characters.
/// </summary>
private static int CountWords(string text)
{
if (string.IsNullOrEmpty(text)) return 0;

int wordCount = 0;
bool inWord = false;

for (int i = 0; i < text.Length; i++)
{
if (char.IsWhiteSpace(text[i]))
{
if (inWord)
{
wordCount++;
inWord = false;
}
}
else
{
inWord = true;
}
}

if (inWord)
{
wordCount++;
}

return wordCount;
}

private void UpdateFontZoomIndicator(ITextEditor textEditor)
{
if (StatusBar == null) return;
Expand Down
16 changes: 11 additions & 5 deletions src/Notepads/Views/MainPage/NotepadsMainPage.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Page
<Page
x:Class="Notepads.Views.MainPage.NotepadsMainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down Expand Up @@ -289,6 +289,7 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid Column="0">
<Grid x:Name="FileModificationStateIndicator"
Expand Down Expand Up @@ -488,7 +489,12 @@
Tapped="StatusBarComponent_OnTapped">
</TextBlock>
</Grid>
<Grid Column="4"
<Grid Column="4">
<TextBlock x:Name="WordCountIndicator" Style="{StaticResource StatusBarTextBlockStyle}"
IsHitTestVisible="False">
</TextBlock>
</Grid>
<Grid Column="5"
ui:FrameworkElementExtensions.Cursor="Hand">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered">
Expand Down Expand Up @@ -580,7 +586,7 @@
</TextBlock.ContextFlyout>
</TextBlock>
</Grid>
<Grid Column="5"
<Grid Column="6"
ui:FrameworkElementExtensions.Cursor="Hand">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered">
Expand Down Expand Up @@ -617,7 +623,7 @@
</TextBlock.ContextFlyout>
</TextBlock>
</Grid>
<Grid Column="6"
<Grid Column="7"
ui:FrameworkElementExtensions.Cursor="Hand">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered">
Expand Down Expand Up @@ -651,7 +657,7 @@
</TextBlock.ContextFlyout>
</TextBlock>
</Grid>
<Grid Column="7"
<Grid Column="8"
ui:FrameworkElementExtensions.Cursor="Hand">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered">
Expand Down
5 changes: 3 additions & 2 deletions src/Notepads/Views/MainPage/NotepadsMainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2019-2024, Jiaqi (0x7c13) Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -62,7 +62,8 @@ private INotepadsCore NotepadsCore
_notepadsCore.TextEditorSaved += OnTextEditorSaved;
_notepadsCore.TextEditorMovedToAnotherAppInstance += OnTextEditorMovedToAnotherAppInstance;
_notepadsCore.TextEditorRenamed += (sender, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) SetupStatusBar(editor); };
_notepadsCore.TextEditorSelectionChanged += (sender, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) UpdateLineColumnIndicator(editor); };
_notepadsCore.TextEditorSelectionChanged += (sender, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) { UpdateLineColumnIndicator(editor); UpdateWordCountIndicator(editor); } };
_notepadsCore.TextEditorTextChanging += (_, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) UpdateWordCountIndicator(editor); };
_notepadsCore.TextEditorFontZoomFactorChanged += (sender, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) UpdateFontZoomIndicator(editor); };
_notepadsCore.TextEditorEncodingChanged += (sender, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) UpdateEncodingIndicator(editor.GetEncoding()); };
_notepadsCore.TextEditorLineEndingChanged += (sender, editor) => { if (NotepadsCore.GetSelectedTextEditor() == editor) { UpdateLineEndingIndicator(editor.GetLineEnding()); UpdateLineColumnIndicator(editor); } };
Expand Down