diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 8c7cf7d2..7ba2cb41 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -1,65 +1,65 @@ :root { - --vp-home-hero-name-color: #fa5c15; - --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #fa5c15, rgb(251, 70, 202)); - --vp-font-family-mono: ui-monospace, 'SF Mono SC', SFMono-Regular, 'SF Mono', 'Cascadia Code', Menlo, 'JetBrains Mono', Monaco, - Consolas, 'Liberation Mono', 'Courier New', monospace; - --vp-font-family-base: 'Chinese Quotes', 'Inter var', 'Inter', ui-sans-serif, - system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, - 'Helvetica Neue', Helvetica, Arial, 'Noto Sans', sans-serif, - 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; - --vp-c-brand-1: #2cbc23; - --vp-c-indigo-2: #fa5c15; + --vp-home-hero-name-color: #fa5c15; + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #fa5c15, rgb(251, 70, 202)); + --vp-font-family-mono: 'Noto Mono', 'SF Mono SC', 'SF Mono', 'Cascadia Code', Menlo, 'JetBrains Mono', Monaco, + Consolas, 'Liberation Mono', 'Courier New', ui-monospace, monospace; + --vp-font-family-base: 'Chinese Quotes', 'Inter var', 'Inter', ui-sans-serif, + system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Helvetica, Arial, 'Noto Sans', sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --vp-c-brand-1: #2cbc23; + --vp-c-indigo-2: #fa5c15; } .dark { - --vp-code-block-bg: #282c34; - --vp-c-bg: #21252b; - --vp-c-bg-alt: #282c34; - --vp-c-bg-elv: #282c34; - --vp-c-bg-soft: #282c34; - /* inline code color */ - --vp-code-color: #2dbc24; + --vp-code-block-bg: #282c34; + --vp-c-bg: #21252b; + --vp-c-bg-alt: #282c34; + --vp-c-bg-elv: #282c34; + --vp-c-bg-soft: #282c34; + /* inline code color */ + --vp-code-color: #2dbc24; } /* bold for second level sidebar-item */ #VPSidebarNav h3 { - font-weight: bold; + font-weight: bold; } .VPImage { - border-radius: 20%; + border-radius: 20%; } /* #region impl blur bav-bar */ :root { - --nav-c-bg: rgba(255, 255, 255, 0.5); + --nav-c-bg: rgba(255, 255, 255, 0.5); } .dark { - --nav-c-bg: rgba(30, 30, 32, 0.5); + --nav-c-bg: rgba(30, 30, 32, 0.5); } .curtain { - display: none !important; + display: none !important; } .fill { - background: transparent !important; + background: transparent !important; } .content-body { - background: var(--nav-c-bg) !important; + background: var(--nav-c-bg) !important; } .content-body::after { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - backdrop-filter: saturate(180%) blur(5px); - z-index: -1; + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + backdrop-filter: saturate(180%) blur(5px); + z-index: -1; } -/* #endregion */ \ No newline at end of file +/* #endregion */ diff --git a/docs/document/Articles/docs/Language Thoughts.md b/docs/document/Articles/docs/Language Thoughts.md index 1f153624..fb886f41 100644 --- a/docs/document/Articles/docs/Language Thoughts.md +++ b/docs/document/Articles/docs/Language Thoughts.md @@ -90,7 +90,7 @@ It should offer benefits: ```ts let foo = 360deg let bar = 6.28rad // for literal -let baz = Math.PI // for non literal, or (Math.PI)rad ? What if we need a tuple in future? violates generic property? +let baz = Math.PI // for non literal, or (Math.PI)rad ? What if we need a tuple in future? this also conflicts with generic property? let a = 2 * 3deg // evaluates to (2 * 3)deg, unit type as target type always let b = 1 - 2deg // error: only scalars can be applied, should do (1 - 2)deg instead let f = (): => 1rad // bracketed annotation for differ from normal types diff --git a/docs/document/Avalonia/docs/Beginner/1. Project basics/1. Project Structure.md b/docs/document/Avalonia/docs/Beginner/1. Fundamentals/1. How Avalonia Loads.md similarity index 60% rename from docs/document/Avalonia/docs/Beginner/1. Project basics/1. Project Structure.md rename to docs/document/Avalonia/docs/Beginner/1. Fundamentals/1. How Avalonia Loads.md index da0ae702..8487ad95 100644 --- a/docs/document/Avalonia/docs/Beginner/1. Project basics/1. Project Structure.md +++ b/docs/document/Avalonia/docs/Beginner/1. Fundamentals/1. How Avalonia Loads.md @@ -1,4 +1,11 @@ -# Project Structure +# How Avalonia Loads + +- `Programs.cs`: Entry point of the app, uses a `Avaloni.Application` type to build up the program. + - `App.axaml`: Stores global themes, resources, styles. + - `App.axaml.cs`: Contains a class inherited from `Avalonia.Application` used as loader. + - `MainWindow.axaml.cs`: Contains a class inherited from `Avalonia.Controls.Window`, used as a source for `App` + - `MainWindow.axaml`: The view of `MainWindow` + - `MainWindowViewModel.cs`: Represents the data context of the main window. ## Entry Point - `Program.cs` @@ -21,9 +28,8 @@ class Program .StartWithClassicDesktopLifetime(args); // Avalonia configuration, don't remove; also used by visual designer. - // !!! Register configuration from some dependencies here as extension methods public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() + => AppBuilder.Configure() // `App` is child of `Application`// [!code highlight] .UsePlatformDetect() .WithInterFont() .LogToTrace() @@ -31,66 +37,38 @@ class Program } ``` -## ViewLocator - -The term "locator" in "ViewLocator" refers to the role of the class in **"locating" or finding the appropriate View for a given ViewModel**. In other words, it helps the application determine which View should be used to display the data and operations defined in a ViewModel. - -Once the `Match` method has determined the correct View type, this type is passed to the `Build` method, which is responsible for creating an instance of the View. - -```cs -using System; -using Avalonia.Controls; -using Avalonia.Controls.Templates; -using AvaloniaApplication.ViewModels; +## `App.axaml` -namespace AvaloniaApplication; - -public class ViewLocator : IDataTemplate -{ - public Control Build(object data) - { - // Rule for matching View for a ViewModel. - var name = data.GetType().FullName!.Replace("ViewModel", "View"); - var type = Type.GetType(name); - // Then create an instance of the View. - if (type is { }) - { - return (Control)Activator.CreateInstance(type)!; - } - // Else return a control with warning. - return new TextBlock { Text = "Not Found: " + name }; - } - - public bool Match(object data) - { - // Matching rules can be more complex... - return data is ViewModelBase; - } -} -``` - -## App.axaml - -:::code-group +`App.axaml` is for configuring styles, themes, data templates and resources **globally**. ```xml + RequestedThemeVariant="Default"> - - - + + + - - - + + + + + + #7f98c7 + #98acd0 + + ``` +The `App.axaml.cs` is the code behind the `App.axaml`. +- Initialize the app +- Loads the `MainWindow` + ```cs using Avalonia; using Avalonia.Controls.ApplicationLifetimes; @@ -104,30 +82,25 @@ public partial class App : Application { public override void Initialize() { - AvaloniaXamlLoader.Load(this); + AvaloniaXamlLoader.Load(this); // attach the component from xaml to this `App` // [!code highlight] } public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - desktop.MainWindow = new MainWindow + desktop.MainWindow = new MainWindow // [!code highlight] { - DataContext = new MainWindowViewModel(), + DataContext = new MainWindowViewModel(), // [!code highlight] }; } - base.OnFrameworkInitializationCompleted(); } } ``` -::: - ## Main Window -:::code-group - ```xml |binds to| B[ViewModel] + B -->|notifies| A + B -->|interacts with| C[Model] + C -->|updates| B + A -->|displays data from| C +``` + +##