mirror of
https://github.com/awatertrevi/xamarin-neo4j.git
synced 2026-09-22 09:05:29 +00:00
Syntax highlighting + command palette
This commit is contained in:
@@ -7,7 +7,11 @@
|
||||
// © Xamarin.Neo4j.iOS
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using CoreGraphics;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
@@ -19,12 +23,52 @@ namespace Xamarin.Neo4j.iOS.CustomRenderers
|
||||
{
|
||||
public class QueryEditorRenderer : EditorRenderer
|
||||
{
|
||||
private readonly string[] _keyWords =
|
||||
{
|
||||
// Clauses
|
||||
"CALL", "CREATE", "DELETE", "DETACH", "FOREACH", "LOAD", "MATCH", "MERGE", "OPTIONAL", "REMOVE", "RETURN", "SET", "START", "UNION", "UNWIND", "WITH",
|
||||
|
||||
// Subclauses
|
||||
"LIMIT", "ORDER", "SKIP", "WHERE", "YIELD",
|
||||
|
||||
// Modifiers
|
||||
"ASC", "ASCENDING", "ASSERT", "BY", "CSV", "DESC", "DESCENDING", "ON",
|
||||
|
||||
// Expressions
|
||||
"ALL", "CASE", "COUNT", "ELSE", "END", "EXISTS", "THEN", "WHEN",
|
||||
|
||||
// Operators
|
||||
"AND", "AS", "CONTAINS", "DISTINCT", "ENDS", "IN", "IS", "NOT", "OR", "STARTS", "XOR",
|
||||
|
||||
// Schema
|
||||
"CONSTRAINT", "CREATE", "DROP", "EXISTS", "INDEX", "NODE", "KEY", "UNIQUE",
|
||||
|
||||
// Hints
|
||||
"INDEX", "JOIN", "SCAN", "USING",
|
||||
|
||||
// Literals
|
||||
"FALSE", "NULL", "TRUE"
|
||||
};
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
Element.TextChanged += (sender, args) =>
|
||||
{
|
||||
HighlightWords(_keyWords);
|
||||
};
|
||||
}
|
||||
|
||||
if (Control != null && Element != null)
|
||||
{
|
||||
Control.AutocorrectionType = UITextAutocorrectionType.No;
|
||||
Control.AutocapitalizationType = UITextAutocapitalizationType.None;
|
||||
Control.SpellCheckingType = UITextSpellCheckingType.No;
|
||||
Control.KeyboardType = UIKeyboardType.Default;
|
||||
|
||||
var executeButton = new UIBarButtonItem("Execute", UIBarButtonItemStyle.Done, (sender, args) =>
|
||||
{
|
||||
if (Element is QueryEditor queryEditor)
|
||||
@@ -35,15 +79,85 @@ namespace Xamarin.Neo4j.iOS.CustomRenderers
|
||||
}
|
||||
});
|
||||
|
||||
var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
|
||||
toolbar.Items = new[]
|
||||
var keyButtons = new[]
|
||||
{
|
||||
new UIBarButtonItem("(", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("(")),
|
||||
new UIBarButtonItem(")", UIBarButtonItemStyle.Plain, (sender, args) => InsertText(")")),
|
||||
new UIBarButtonItem("[", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("[")),
|
||||
new UIBarButtonItem("]", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("]")),
|
||||
new UIBarButtonItem(":", UIBarButtonItemStyle.Plain, (sender, args) => InsertText(":")),
|
||||
new UIBarButtonItem("-", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("-")),
|
||||
new UIBarButtonItem("\u2192", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("->")),
|
||||
new UIBarButtonItem("\u2190", UIBarButtonItemStyle.Plain, (sender, args) => InsertText("<-")),
|
||||
|
||||
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
|
||||
|
||||
executeButton
|
||||
};
|
||||
|
||||
var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
|
||||
toolbar.Items = keyButtons;
|
||||
|
||||
Control.InputAccessoryView = toolbar;
|
||||
}
|
||||
}
|
||||
|
||||
private void HighlightWords(IEnumerable<string> wordsToHighlight)
|
||||
{
|
||||
var text = PreprocessText(Control.Text);
|
||||
var attributedText = new NSMutableAttributedString(text);
|
||||
|
||||
// Iterate through the array and apply formatting to the editor's text.
|
||||
foreach (var word in wordsToHighlight)
|
||||
{
|
||||
var regex = new Regex("\\b" + Regex.Escape(word) + "\\b", RegexOptions.IgnoreCase);
|
||||
|
||||
foreach (Match match in regex.Matches(text))
|
||||
{
|
||||
attributedText.AddAttribute(UIStringAttributeKey.ForegroundColor, Color.FromHex("#89982e").ToUIColor(),
|
||||
new NSRange(match.Index, match.Length));
|
||||
}
|
||||
}
|
||||
|
||||
// Apply text color formatting for text inside single quotes.
|
||||
ApplyQuoteTextColorFormatting(text, attributedText, "'(.*?)'", Color.FromHex("#ae8b2d").ToUIColor());
|
||||
|
||||
// Apply text color formatting for text inside double quotes.
|
||||
ApplyQuoteTextColorFormatting(text, attributedText, "\"(.*?)\"", Color.FromHex("#ae8b2d").ToUIColor());
|
||||
|
||||
attributedText.AddAttribute(UIStringAttributeKey.Font, UIFont.SystemFontOfSize((nfloat) Element.FontSize), new NSRange(0, attributedText.Length));
|
||||
|
||||
Control.AttributedText = attributedText;
|
||||
}
|
||||
|
||||
private void InsertText(string text)
|
||||
{
|
||||
Control.InsertText(text);
|
||||
}
|
||||
|
||||
private static void ApplyQuoteTextColorFormatting(string text, NSMutableAttributedString attributedText,
|
||||
string quotePattern, UIColor color)
|
||||
{
|
||||
var quoteRegex = new Regex(quotePattern);
|
||||
|
||||
foreach (Match match in quoteRegex.Matches(text))
|
||||
{
|
||||
attributedText.AddAttribute(UIStringAttributeKey.ForegroundColor, color,
|
||||
new NSRange(match.Index, match.Length));
|
||||
}
|
||||
}
|
||||
|
||||
private static string PreprocessText(string text)
|
||||
{
|
||||
// Replace single quotation marks and their curly variants with: '
|
||||
text = text.Replace("‘", "'");
|
||||
text = text.Replace("’", "'");
|
||||
|
||||
// Replace double quotation marks and their curly variants with: "
|
||||
text = text.Replace("“", "\"");
|
||||
text = text.Replace("”", "\"");
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>nl.resoftware.pocketgraph</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.3</string>
|
||||
<string>4</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xamarin.Forms;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
@@ -27,3 +28,5 @@ using System.Runtime.InteropServices;
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
[assembly: ExportFont("RobotoMono-Regular.ttf", Alias = "RobotoMonoRegular")]
|
||||
|
||||
@@ -11,6 +11,7 @@ using UIKit;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.iOS.Services;
|
||||
using Xamarin.Neo4j.Services;
|
||||
using Xamarin.Neo4j.Services.Interfaces;
|
||||
|
||||
[assembly: Dependency(typeof(ScreenSizeService))]
|
||||
namespace Xamarin.Neo4j.iOS.Services
|
||||
|
||||
@@ -11,6 +11,7 @@ using Neo4j.Driver;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.iOS.Services;
|
||||
using Xamarin.Neo4j.Services;
|
||||
using Xamarin.Neo4j.Services.Interfaces;
|
||||
|
||||
[assembly: Dependency(typeof(TrustManagerService))]
|
||||
namespace Xamarin.Neo4j.iOS.Services
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// VersionService.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 02-03-2024
|
||||
//
|
||||
// © Xamarin.Neo4j.iOS
|
||||
//
|
||||
|
||||
using Foundation;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.iOS.Services;
|
||||
using Xamarin.Neo4j.Services.Interfaces;
|
||||
|
||||
[assembly: Dependency(typeof(VersionService))]
|
||||
namespace Xamarin.Neo4j.iOS.Services
|
||||
{
|
||||
public class VersionService : IVersionService
|
||||
{
|
||||
public string GetVersion() => NSBundle.MainBundle.InfoDictionary["CFBundleShortVersionString"]?.ToString();
|
||||
|
||||
public string GetBuild() => NSBundle.MainBundle.InfoDictionary["CFBundleVersion"]?.ToString();
|
||||
}
|
||||
}
|
||||
@@ -100,6 +100,7 @@
|
||||
<Compile Include="Security\NativeTrustManager.cs" />
|
||||
<Compile Include="Services\ScreenSizeService.cs" />
|
||||
<Compile Include="Services\TrustManagerService.cs" />
|
||||
<Compile Include="Services\VersionService.cs" />
|
||||
<None Include="Entitlements.plist" />
|
||||
<None Include="Info.plist" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
Binary file not shown.
@@ -18,6 +18,11 @@ namespace Xamarin.Neo4j.Controls
|
||||
|
||||
public event EventHandler ExecuteClicked;
|
||||
|
||||
public QueryEditor()
|
||||
{
|
||||
FontFamily = "RobotoMonoRegular";
|
||||
}
|
||||
|
||||
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
|
||||
{
|
||||
var sizeRequest = base.OnMeasure(widthConstraint, heightConstraint);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<TableView VerticalOptions="StartAndExpand" Intent="Settings" Background="Transparent">
|
||||
<TableRoot>
|
||||
<TableSection>
|
||||
<TextCell Text="{Binding VersionLabel}" />
|
||||
<TextCell Text="Software Licenses" Command="{Binding Commands[OpenLicensesPage]}" />
|
||||
</TableSection>
|
||||
</TableRoot>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Xamarin.Neo4j.Services
|
||||
namespace Xamarin.Neo4j.Services.Interfaces
|
||||
{
|
||||
public interface IScreenSizeService
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Neo4j.Driver;
|
||||
|
||||
namespace Xamarin.Neo4j.Services
|
||||
namespace Xamarin.Neo4j.Services.Interfaces
|
||||
{
|
||||
public interface ITrustManagerService
|
||||
{
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Xamarin.Neo4j.Services.Interfaces
|
||||
{
|
||||
public interface IVersionService
|
||||
{
|
||||
string GetVersion();
|
||||
|
||||
string GetBuild();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ using Neo4jClient.Cypher;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.Services;
|
||||
using Xamarin.Neo4j.Services.Interfaces;
|
||||
using Xamarin.Neo4j.Utilities;
|
||||
|
||||
[assembly: Dependency(typeof(Neo4jService))]
|
||||
|
||||
@@ -22,6 +22,7 @@ using Xamarin.Neo4j.Annotations;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.Pages;
|
||||
using Xamarin.Neo4j.Services;
|
||||
using Xamarin.Neo4j.Services.Interfaces;
|
||||
using Xamarin.Neo4j.Utilities;
|
||||
|
||||
namespace Xamarin.Neo4j.ViewModels
|
||||
|
||||
@@ -14,13 +14,18 @@ using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Annotations;
|
||||
using Xamarin.Neo4j.Pages;
|
||||
using Xamarin.Neo4j.Services.Interfaces;
|
||||
|
||||
namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
public class SettingsViewModel : ViewModelBase, INotifyPropertyChanged
|
||||
{
|
||||
private string _versionLabel { get; set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private IVersionService _versionService { get; set; }
|
||||
|
||||
public SettingsViewModel(INavigation navigation) : base(navigation)
|
||||
{
|
||||
Commands.Add("OpenReSoftwareSite", new Command(async () =>
|
||||
@@ -32,6 +37,10 @@ namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
await Navigation.PushAsync(new LicensesPage());
|
||||
}));
|
||||
|
||||
_versionService = DependencyService.Get<IVersionService>();
|
||||
|
||||
VersionLabel = $"Version: {_versionService.GetVersion()} (Build: {_versionService.GetBuild()})";
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
@@ -39,5 +48,22 @@ namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
#region Bindable Properties
|
||||
|
||||
public string VersionLabel
|
||||
{
|
||||
get => _versionLabel;
|
||||
|
||||
set
|
||||
{
|
||||
_versionLabel = value;
|
||||
|
||||
OnPropertyChanged(nameof(VersionLabel));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,5 +23,7 @@
|
||||
<EmbeddedResource Include="Visualization\neovis.html" />
|
||||
<None Remove="Resources\licenses.json" />
|
||||
<EmbeddedResource Include="Resources\licenses.json" />
|
||||
<None Remove="Assets\Fonts\RobotoMono-Regular.ttf" />
|
||||
<EmbeddedResource Include="Assets\Fonts\RobotoMono-Regular.ttf" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user