├── .github ├── FUNDING.yml ├── release-drafter.yml └── workflows │ └── release-drafter.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── imgs ├── add_page_dark.png ├── banner.png ├── code_view_page.png ├── cutcode.gif ├── fav_page.png ├── main_page.png ├── main_page_light.png ├── main_page_search.png ├── setting_dark.png └── setting_light.png └── src ├── .gitattributes ├── .gitignore ├── CutCode.CrossPlatform ├── .gitignore ├── App.axaml ├── App.axaml.cs ├── Assets │ ├── Fonts │ │ ├── Inconsolata-Regular.ttf │ │ ├── Poppins-Regular.ttf │ │ └── Poppins-SemiBold.ttf │ ├── Images │ │ ├── Developers │ │ │ ├── abdesol.png │ │ │ └── piero.png │ │ ├── logo.ico │ │ └── logo.png │ └── avalonia-logo.ico ├── BootStrappers │ ├── EntryBootstrapper.cs │ ├── NavigationBootstrapper.cs │ └── ServicesBootstrapper.cs ├── Controls │ ├── AnimatedListBox.cs │ ├── AnimatedListBoxItem.cs │ ├── CustomComboBox.axaml │ ├── CustomComboBox.axaml.cs │ ├── CustomSearchBar.axaml │ ├── CustomSearchBar.axaml.cs │ ├── NavigationItem.axaml │ ├── NavigationItem.axaml.cs │ ├── WindowButtons.axaml │ └── WindowButtons.axaml.cs ├── Converters │ ├── BitmapAssetValueConverter.cs │ ├── StringToFontFamily.cs │ └── StringToGeometryConverter.cs ├── CutCode.CrossPlatform.csproj ├── FodyWeavers.xml ├── Helpers │ ├── ButtonExts.cs │ ├── Extensions.cs │ ├── GlobalEvents.cs │ ├── IconPaths.cs │ ├── Languages.cs │ ├── SystemColorsConfig.cs │ └── UpdateChecker.cs ├── Models │ ├── CodeModel.cs │ ├── CodesTable.cs │ ├── NotificationModels.cs │ ├── PrefModel.cs │ ├── SideBarBtnModel.cs │ ├── SyncBtnModel.cs │ ├── TabItemModel.cs │ └── ThemeButtonModel.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Services │ ├── DatabaseService.cs │ ├── NotificationService.cs │ ├── PageService.cs │ └── ThemeService.cs ├── Styles │ ├── AnimatedListBoxItem.axaml │ ├── ButtonStyles.axaml │ ├── ComboBox.axaml │ ├── ScrollBarStyles.axaml │ └── TextBoxStyles.axaml ├── ViewLocator.cs ├── ViewModels │ ├── AddViewModel.cs │ ├── CodeCardViewModel.cs │ ├── CodeCellViewModel.cs │ ├── CodeViewModel.cs │ ├── FavoritesViewModel.cs │ ├── HomeViewModel.cs │ ├── MainWindowViewModel.cs │ ├── NotificationViewModel.cs │ ├── PageBaseViewModel.cs │ ├── SettingsViewModel.cs │ └── ViewModelBase.cs ├── Views │ ├── AddView.axaml │ ├── AddView.axaml.cs │ ├── CodeCardView.axaml │ ├── CodeCardView.axaml.cs │ ├── CodeCellView.axaml │ ├── CodeCellView.axaml.cs │ ├── CodeView.axaml │ ├── CodeView.axaml.cs │ ├── FavoritesView.axaml │ ├── FavoritesView.axaml.cs │ ├── HomeView.axaml │ ├── HomeView.axaml.cs │ ├── MainWindow.axaml │ ├── MainWindow.axaml.cs │ ├── NotificationView.axaml │ ├── NotificationView.axaml.cs │ ├── SettingsView.axaml │ └── SettingsView.axaml.cs ├── global.json └── nuget.config ├── CutCode.sln ├── global.json └── nuget.config /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: "https://www.buymeacoffee.com/abdesol" 4 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$RESOLVED_VERSION 🌈' 2 | tag-template: 'v$RESOLVED_VERSION' 3 | categories: 4 | - title: '🚀 Features' 5 | labels: 6 | - 'feature' 7 | - 'enhancement' 8 | - title: '🐛 Bug Fixes' 9 | labels: 10 | - 'fix' 11 | - 'bugfix' 12 | - 'bug' 13 | - title: '🧰 Maintenance' 14 | label: 'chore' 15 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 16 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 17 | version-resolver: 18 | major: 19 | labels: 20 | - 'major' 21 | minor: 22 | labels: 23 | - 'minor' 24 | patch: 25 | labels: 26 | - 'patch' 27 | default: patch 28 | template: | 29 | ## Changes 30 | 31 | $CHANGES 32 | autolabeler: 33 | - label: 'bug' 34 | title: 35 | - '/fix/i' 36 | - label: 'feature' 37 | title: 38 | - '/feature/i' 39 | - label: 'chore' 40 | title: 41 | - '/chore/i' -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - master 8 | # pull_request event is required only for autolabeler 9 | pull_request: 10 | # Only following types are handled by the action, but one can default to all as well 11 | types: [ opened, reopened, synchronize ] 12 | # pull_request_target event is required for autolabeler to support PRs from forks 13 | # pull_request_target: 14 | # types: [opened, reopened, synchronize] 15 | 16 | jobs: 17 | update_release_draft: 18 | runs-on: ubuntu-latest 19 | steps: 20 | # (Optional) GitHub Enterprise requires GHE_HOST variable set 21 | #- name: Set GHE_HOST 22 | # run: | 23 | # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV 24 | 25 | # Drafts your next Release notes as Pull Requests are merged into "master" 26 | - uses: release-drafter/release-drafter@v5 27 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 28 | # with: 29 | # config-name: my-config.yml 30 | # disable-autolabeler: true 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | abdesoltak@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Abdella Solomon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Banner](https://user-images.githubusercontent.com/63385587/135706502-35fee274-a8d2-48da-b9a9-50213ae3104a.png) 2 | 3 | 4 | # CutCode 5 | 6 | As a developer, we often search on Google / StackOverFlow for doubts, issues related to our code and our projects, when programming / developing. As a result, we visit a lot of different posts, different websites to find the right solution to our problem, but time and (time) again, when we find a proper solution to your problem, we tend to forget where we found it or even the solution. Hence, we decided to create a tool that helps us save our answers as small snippets, so that we do not have remember it all the time and we can access our solutions anytime we want. 7 | 8 | CutCode is an open source tool made for developers to boost their productivity and save their time by helping them save essential code as snippets in safe place. These code snippets are stored in an orderly fashion and can be searched and accessed at anytime. It is a very helpful tool as the developers no longer need to remember their solutions and where they originally found them. 9 | 10 | 11 | # CutCode in Action 🎨 12 | ![Example](https://github.com/Abdesol/CutCode/blob/master/imgs/cutcode.gif) 13 | 14 | 15 | # Features ✨ 16 | 17 | 1. **Dark and Light mode support. We recommend using dark mode for a better experience.** 18 | 2. **Your code snippets are saved safely in a database, in your system.** 19 | 3. **You can give your code snippets title, description, and also you can add them to your favourite snippets list.** 20 | 4. **You can add cells into your code so that you can manage your code snippets easily.** 21 | 5. **The code snippets are stored in orderly fashion, so you can search your snippets based on its name, programming language, and creation date.** 22 | 6. **CutCode has minimalistic UI design and it is user-friendly.** 23 | 7. **You can import and export your code from your system and save them as snippets.** 24 | 8. **CutCode is supported on both Windows and Linux.** 25 | 26 | # Coming Soon 27 | 1. **Syntax highlighting for all the programming languages supported by CutCode.** 28 | 2. **MacOS support.** 29 | 3. **Theme changing and plugins.** 30 | 4. **Automatic updater.** 31 | 5. **Animations everywhere** 32 | 33 | # Contributors 34 | 35 | 36 | 37 | 38 |
39 | 40 | Made with [contrib.rocks](https://contrib.rocks). 41 | 42 | # Credits 43 | This project is **MIT licensed** and entirely open source, hence, it is completely free to use. However, if you are inspired from this project and have used the source code of this project in your own projects, please consider giving credits to us. 44 | You can get the latest version of CutCode from the release page [here](https://github.com/CutCode-org/CutCode/releases/latest) 45 | 46 | **Thank you for using CutCode!** 47 | **Star and share this project with your programmer friends.** 48 | -------------------------------------------------------------------------------- /imgs/add_page_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/add_page_dark.png -------------------------------------------------------------------------------- /imgs/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/banner.png -------------------------------------------------------------------------------- /imgs/code_view_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/code_view_page.png -------------------------------------------------------------------------------- /imgs/cutcode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/cutcode.gif -------------------------------------------------------------------------------- /imgs/fav_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/fav_page.png -------------------------------------------------------------------------------- /imgs/main_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/main_page.png -------------------------------------------------------------------------------- /imgs/main_page_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/main_page_light.png -------------------------------------------------------------------------------- /imgs/main_page_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/main_page_search.png -------------------------------------------------------------------------------- /imgs/setting_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/setting_dark.png -------------------------------------------------------------------------------- /imgs/setting_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/imgs/setting_light.png -------------------------------------------------------------------------------- /src/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | .idea/ 39 | # Uncomment if you have tasks that create the project's static files in wwwroot 40 | #wwwroot/ 41 | 42 | # Visual Studio 2017 auto generated files 43 | Generated\ Files/ 44 | 45 | # MSTest test Results 46 | [Tt]est[Rr]esult*/ 47 | [Bb]uild[Ll]og.* 48 | 49 | # NUnit 50 | *.VisualState.xml 51 | TestResult.xml 52 | nunit-*.xml 53 | 54 | # Build Results of an ATL Project 55 | [Dd]ebugPS/ 56 | [Rr]eleasePS/ 57 | dlldata.c 58 | 59 | # Benchmark Results 60 | BenchmarkDotNet.Artifacts/ 61 | 62 | # .NET Core 63 | project.lock.json 64 | project.fragment.lock.json 65 | artifacts/ 66 | 67 | # ASP.NET Scaffolding 68 | ScaffoldingReadMe.txt 69 | 70 | # StyleCop 71 | StyleCopReport.xml 72 | 73 | # Files built by Visual Studio 74 | *_i.c 75 | *_p.c 76 | *_h.h 77 | *.ilk 78 | *.meta 79 | *.obj 80 | *.iobj 81 | *.pch 82 | *.pdb 83 | *.ipdb 84 | *.pgc 85 | *.pgd 86 | *.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *_wpftmp.csproj 94 | *.log 95 | *.vspscc 96 | *.vssscc 97 | .builds 98 | *.pidb 99 | *.svclog 100 | *.scc 101 | 102 | # Chutzpah Test files 103 | _Chutzpah* 104 | 105 | # Visual C++ cache files 106 | ipch/ 107 | *.aps 108 | *.ncb 109 | *.opendb 110 | *.opensdf 111 | *.sdf 112 | *.cachefile 113 | *.VC.db 114 | *.VC.VC.opendb 115 | 116 | # Visual Studio profiler 117 | *.psess 118 | *.vsp 119 | *.vspx 120 | *.sap 121 | 122 | # Visual Studio Trace Files 123 | *.e2e 124 | 125 | # TFS 2012 Local Workspace 126 | $tf/ 127 | 128 | # Guidance Automation Toolkit 129 | *.gpState 130 | 131 | # ReSharper is a .NET coding add-in 132 | _ReSharper*/ 133 | *.[Rr]e[Ss]harper 134 | *.DotSettings.user 135 | 136 | # TeamCity is a build add-in 137 | _TeamCity* 138 | 139 | # DotCover is a Code Coverage Tool 140 | *.dotCover 141 | 142 | # AxoCover is a Code Coverage Tool 143 | .axoCover/* 144 | !.axoCover/settings.json 145 | 146 | # Coverlet is a free, cross platform Code Coverage Tool 147 | coverage*.json 148 | coverage*.xml 149 | coverage*.info 150 | 151 | # Visual Studio code coverage results 152 | *.coverage 153 | *.coveragexml 154 | 155 | # NCrunch 156 | _NCrunch_* 157 | .*crunch*.local.xml 158 | nCrunchTemp_* 159 | 160 | # MightyMoose 161 | *.mm.* 162 | AutoTest.Net/ 163 | 164 | # Web workbench (sass) 165 | .sass-cache/ 166 | 167 | # Installshield output folder 168 | [Ee]xpress/ 169 | 170 | # DocProject is a documentation generator add-in 171 | DocProject/buildhelp/ 172 | DocProject/Help/*.HxT 173 | DocProject/Help/*.HxC 174 | DocProject/Help/*.hhc 175 | DocProject/Help/*.hhk 176 | DocProject/Help/*.hhp 177 | DocProject/Help/Html2 178 | DocProject/Help/html 179 | 180 | # Click-Once directory 181 | publish/ 182 | 183 | # Publish Web Output 184 | *.[Pp]ublish.xml 185 | *.azurePubxml 186 | # Note: Comment the next line if you want to checkin your web deploy settings, 187 | # but database connection strings (with potential passwords) will be unencrypted 188 | *.pubxml 189 | *.publishproj 190 | 191 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 192 | # checkin your Azure Web App publish settings, but sensitive information contained 193 | # in these scripts will be unencrypted 194 | PublishScripts/ 195 | 196 | # NuGet Packages 197 | *.nupkg 198 | # NuGet Symbol Packages 199 | *.snupkg 200 | # The packages folder can be ignored because of Package Restore 201 | **/[Pp]ackages/* 202 | # except build/, which is used as an MSBuild target. 203 | !**/[Pp]ackages/build/ 204 | # Uncomment if necessary however generally it will be regenerated when needed 205 | #!**/[Pp]ackages/repositories.config 206 | # NuGet v3's project.json files produces more ignorable files 207 | *.nuget.props 208 | *.nuget.targets 209 | 210 | # Microsoft Azure Build Output 211 | csx/ 212 | *.build.csdef 213 | 214 | # Microsoft Azure Emulator 215 | ecf/ 216 | rcf/ 217 | 218 | # Windows Store app package directories and files 219 | AppPackages/ 220 | BundleArtifacts/ 221 | Package.StoreAssociation.xml 222 | _pkginfo.txt 223 | *.appx 224 | *.appxbundle 225 | *.appxupload 226 | 227 | # Visual Studio cache files 228 | # files ending in .cache can be ignored 229 | *.[Cc]ache 230 | # but keep track of directories ending in .cache 231 | !?*.[Cc]ache/ 232 | 233 | # Others 234 | ClientBin/ 235 | ~$* 236 | *~ 237 | *.dbmdl 238 | *.dbproj.schemaview 239 | *.jfm 240 | *.pfx 241 | *.publishsettings 242 | orleans.codegen.cs 243 | 244 | # Including strong name files can present a security risk 245 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 246 | #*.snk 247 | 248 | # Since there are multiple workflows, uncomment next line to ignore bower_components 249 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 250 | #bower_components/ 251 | 252 | # RIA/Silverlight projects 253 | Generated_Code/ 254 | 255 | # Backup & report files from converting an old project file 256 | # to a newer Visual Studio version. Backup files are not needed, 257 | # because we have git ;-) 258 | _UpgradeReport_Files/ 259 | Backup*/ 260 | UpgradeLog*.XML 261 | UpgradeLog*.htm 262 | ServiceFabricBackup/ 263 | *.rptproj.bak 264 | 265 | # SQL Server files 266 | *.mdf 267 | *.ldf 268 | *.ndf 269 | 270 | # Business Intelligence projects 271 | *.rdl.data 272 | *.bim.layout 273 | *.bim_*.settings 274 | *.rptproj.rsuser 275 | *- [Bb]ackup.rdl 276 | *- [Bb]ackup ([0-9]).rdl 277 | *- [Bb]ackup ([0-9][0-9]).rdl 278 | 279 | # Microsoft Fakes 280 | FakesAssemblies/ 281 | 282 | # GhostDoc plugin setting file 283 | *.GhostDoc.xml 284 | 285 | # Node.js Tools for Visual Studio 286 | .ntvs_analysis.dat 287 | node_modules/ 288 | 289 | # Visual Studio 6 build log 290 | *.plg 291 | 292 | # Visual Studio 6 workspace options file 293 | *.opt 294 | 295 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 296 | *.vbw 297 | 298 | # Visual Studio LightSwitch build output 299 | **/*.HTMLClient/GeneratedArtifacts 300 | **/*.DesktopClient/GeneratedArtifacts 301 | **/*.DesktopClient/ModelManifest.xml 302 | **/*.Server/GeneratedArtifacts 303 | **/*.Server/ModelManifest.xml 304 | _Pvt_Extensions 305 | 306 | # Paket dependency manager 307 | .paket/paket.exe 308 | paket-files/ 309 | 310 | # FAKE - F# Make 311 | .fake/ 312 | 313 | # CodeRush personal settings 314 | .cr/personal 315 | 316 | # Python Tools for Visual Studio (PTVS) 317 | __pycache__/ 318 | *.pyc 319 | 320 | # Cake - Uncomment if you are using it 321 | # tools/** 322 | # !tools/packages.config 323 | 324 | # Tabs Studio 325 | *.tss 326 | 327 | # Telerik's JustMock configuration file 328 | *.jmconfig 329 | 330 | # BizTalk build output 331 | *.btp.cs 332 | *.btm.cs 333 | *.odx.cs 334 | *.xsd.cs 335 | 336 | # OpenCover UI analysis results 337 | OpenCover/ 338 | 339 | # Azure Stream Analytics local run output 340 | ASALocalRun/ 341 | 342 | # MSBuild Binary and Structured Log 343 | *.binlog 344 | 345 | # NVidia Nsight GPU debugger configuration file 346 | *.nvuser 347 | 348 | # MFractors (Xamarin productivity tool) working folder 349 | .mfractor/ 350 | 351 | # Local History for Visual Studio 352 | .localhistory/ 353 | 354 | # BeatPulse healthcheck temp database 355 | healthchecksdb 356 | 357 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 358 | MigrationBackup/ 359 | 360 | # Ionide (cross platform F# VS Code tools) working folder 361 | .ionide/ 362 | 363 | # Fody - auto-generated XML schema 364 | FodyWeavers.xsd -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/App.axaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | avares://CutCode.CrossPlatform/Assets/Fonts/Poppins-SemiBold.ttf#Poppins 12 | avares://CutCode.CrossPlatform/Assets/Fonts/Poppins-Regular.ttf#Poppins 13 | avares://CutCode.CrossPlatform/Assets/Fonts/Inconsolata-Regular.ttf#Inconsolata 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/App.axaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Drawing; 4 | using System.Threading; 5 | using Avalonia; 6 | using Avalonia.Controls.ApplicationLifetimes; 7 | using Avalonia.Markup.Xaml; 8 | using Avalonia.Markup.Xaml.Styling; 9 | using Avalonia.Media; 10 | using Avalonia.ReactiveUI; 11 | using CutCode.CrossPlatform.Helpers; 12 | using CutCode.CrossPlatform.ViewModels; 13 | using CutCode.CrossPlatform.Views; 14 | using CutCode.CrossPlatform.Services; 15 | using ReactiveUI; 16 | using Splat; 17 | using Color = Avalonia.Media.Color; 18 | 19 | namespace CutCode.CrossPlatform 20 | { 21 | public class App : Application 22 | { 23 | public override void Initialize() 24 | { 25 | AvaloniaXamlLoader.Load(this); 26 | } 27 | 28 | public override void OnFrameworkInitializationCompleted() 29 | { 30 | if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) 31 | { 32 | if(ThemeService.Current.Theme == ThemeType.Light) SystemColorsConfig.LightThemeColors(); 33 | else SystemColorsConfig.DarkThemeColors(); 34 | ThemeService.Current.ThemeChanged += (sender, args) => 35 | { 36 | if(ThemeService.Current.Theme == ThemeType.Light) SystemColorsConfig.LightThemeColors(); 37 | else SystemColorsConfig.DarkThemeColors(); 38 | }; 39 | 40 | desktop.MainWindow = new MainWindow 41 | { 42 | DataContext = new MainWindowViewModel() 43 | }; 44 | 45 | ThemeService.Current.Theme = DatabaseService.Current.Theme; 46 | 47 | desktop.Exit += (s, e) => 48 | { 49 | DatabaseService.Current.ChangeTheme(ThemeService.Current.Theme); 50 | }; 51 | var updateThread = new Thread(UpdateChecker.Run); 52 | updateThread.Start(); 53 | } 54 | base.OnFrameworkInitializationCompleted(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Fonts/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Fonts/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Fonts/Poppins-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Fonts/Poppins-Regular.ttf -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Fonts/Poppins-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Fonts/Poppins-SemiBold.ttf -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Images/Developers/abdesol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Images/Developers/abdesol.png -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Images/Developers/piero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Images/Developers/piero.png -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Images/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Images/logo.ico -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/Images/logo.png -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Assets/avalonia-logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutCode-org/CutCode/5d495274afa9041bce88831c73bfd10903895ff7/src/CutCode.CrossPlatform/Assets/avalonia-logo.ico -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/BootStrappers/EntryBootstrapper.cs: -------------------------------------------------------------------------------- 1 | // --------------------------------------------- 2 | // --- CutCode.CrossPlatform by Scarementus --- 3 | // --- Licence MIT --- 4 | // --------------------------------------------- 5 | 6 | using Splat; 7 | 8 | namespace CutCode.CrossPlatform.BootStrappers; 9 | 10 | public static class EntryBootstrapper 11 | { 12 | public static void Register(IMutableDependencyResolver services, IReadonlyDependencyResolver resolver) 13 | { 14 | ServicesBootstrapper.RegisterServices(services, resolver); 15 | NavigationBootstrapper.RegisterViewModels(services, resolver); 16 | } 17 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/BootStrappers/NavigationBootstrapper.cs: -------------------------------------------------------------------------------- 1 | // --------------------------------------------- 2 | // --- CutCode.CrossPlatform by Scarementus --- 3 | // --- Licence MIT --- 4 | // --------------------------------------------- 5 | 6 | using CutCode.CrossPlatform.ViewModels; 7 | using CutCode.CrossPlatform.Views; 8 | using ReactiveUI; 9 | using Splat; 10 | 11 | namespace CutCode.CrossPlatform.BootStrappers; 12 | 13 | public static class NavigationBootstrapper 14 | { 15 | public static void RegisterViewModels(IMutableDependencyResolver services, IReadonlyDependencyResolver resolver) 16 | { 17 | services.Register(() => new HomeView(), typeof(IViewFor)); 18 | services.Register(() => new AddView(), typeof(IViewFor)); 19 | services.Register(() => new FavoritesView(), typeof(IViewFor)); 20 | services.Register(() => new SettingsView(), typeof(IViewFor)); 21 | services.Register(() => new CodeView(), typeof(IViewFor)); 22 | } 23 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/BootStrappers/ServicesBootstrapper.cs: -------------------------------------------------------------------------------- 1 | // --------------------------------------------- 2 | // --- CutCode.CrossPlatform by Scarementus --- 3 | // --- Licence MIT --- 4 | // --------------------------------------------- 5 | 6 | using Splat; 7 | 8 | namespace CutCode.CrossPlatform.BootStrappers; 9 | 10 | public class ServicesBootstrapper 11 | { 12 | public static void RegisterServices(IMutableDependencyResolver services, IReadonlyDependencyResolver resolver) 13 | { 14 | } 15 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/AnimatedListBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Avalonia; 4 | using Avalonia.Controls; 5 | using Avalonia.Controls.Generators; 6 | using Avalonia.Controls.Metadata; 7 | using Avalonia.Styling; 8 | using AvaloniaEdit; 9 | 10 | namespace CutCode.CrossPlatform.Controls; 11 | 12 | public class AnimatedListBox : ListBox, IStyleable 13 | { 14 | Type IStyleable.StyleKey => typeof(ListBox); 15 | 16 | protected override IItemContainerGenerator CreateItemContainerGenerator() 17 | { 18 | return new ItemContainerGenerator( 19 | this, 20 | AnimatedListBoxItem.ContentProperty, 21 | AnimatedListBoxItem.ContentTemplateProperty); 22 | } 23 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/AnimatedListBoxItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using Avalonia; 4 | using Avalonia.Animation; 5 | using Avalonia.Controls; 6 | using Avalonia.Controls.Metadata; 7 | using Avalonia.Input; 8 | using Avalonia.LogicalTree; 9 | using Avalonia.Styling; 10 | using Microsoft.CodeAnalysis.CSharp.Syntax; 11 | 12 | namespace CutCode.CrossPlatform.Controls; 13 | 14 | [PseudoClasses(":Added", ":Removed")] 15 | public class AnimatedListBoxItem : ListBoxItem, IStyleable 16 | { 17 | public AnimatedListBoxItem() 18 | { 19 | } 20 | Type IStyleable.StyleKey => typeof(AnimatedListBoxItem); 21 | 22 | private bool isAttached = false; 23 | protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) 24 | { 25 | if (isAttached) return; 26 | PseudoClasses.Set(":Added", true); 27 | isAttached = true; 28 | base.OnAttachedToVisualTree(e); 29 | } 30 | 31 | protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) 32 | { 33 | PseudoClasses.Set(":Removed", true); 34 | base.OnDetachedFromVisualTree(e); 35 | } 36 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/CustomComboBox.axaml: -------------------------------------------------------------------------------- 1 |  7 | 9 | 101 | 102 | -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/CustomComboBox.axaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Input; 4 | using Avalonia; 5 | using Avalonia.Controls; 6 | using Avalonia.Data; 7 | using Avalonia.Markup.Xaml; 8 | using Avalonia.Media; 9 | using CutCode.CrossPlatform.Helpers; 10 | 11 | namespace CutCode.CrossPlatform.Controls 12 | { 13 | public class CustomComboBox : UserControl 14 | { 15 | private Label nameLabel; 16 | private ComboBox comboBox; 17 | 18 | static CustomComboBox() 19 | { 20 | BackgroundProperty.Changed.Subscribe(BackgroundPropertyChanged); 21 | ForegroundProperty.Changed.Subscribe(ForegroundPropertyChanged); 22 | OverlayBrushProperty.Changed.Subscribe(OverlayBrushPropertyChanged); 23 | 24 | NameProperty.Changed.Subscribe(NamePropertyChanged); 25 | ItemsProperty.Changed.Subscribe(ItemsPropertyChanged); 26 | SelectedIndexProperty.Changed.Subscribe(SelectedIndexPropertyChanged); 27 | } 28 | 29 | public CustomComboBox() 30 | { 31 | InitializeComponent(); 32 | this.GetControl("nameLabel", out nameLabel); 33 | this.GetControl("comboBox", out comboBox); 34 | 35 | comboBox.SelectionChanged += (sender, e) => 36 | { 37 | ItemSelected?.Execute((sender as ComboBox)?.SelectedItem as string); 38 | }; 39 | } 40 | 41 | private void InitializeComponent() 42 | { 43 | AvaloniaXamlLoader.Load(this); 44 | } 45 | 46 | public new static readonly StyledProperty BackgroundProperty = 47 | AvaloniaProperty.Register(nameof(Background)); 48 | 49 | public new IBrush Background 50 | { 51 | get => GetValue(BackgroundProperty); 52 | set => SetValue(BackgroundProperty, value); 53 | } 54 | 55 | private static void BackgroundPropertyChanged(AvaloniaPropertyChangedEventArgs e) 56 | { 57 | if (e.Sender is CustomComboBox ctrl) 58 | { 59 | ctrl.comboBox.Background = e.NewValue.Value; 60 | } 61 | } 62 | 63 | public new static readonly StyledProperty ForegroundProperty = 64 | AvaloniaProperty.Register(nameof(Foreground)); 65 | 66 | public new IBrush Foreground 67 | { 68 | get => GetValue(ForegroundProperty); 69 | set => SetValue(ForegroundProperty, value); 70 | } 71 | 72 | private static void ForegroundPropertyChanged(AvaloniaPropertyChangedEventArgs e) 73 | { 74 | if (e.Sender is CustomComboBox ctrl) 75 | { 76 | ctrl.nameLabel.Foreground = e.NewValue.Value; 77 | ctrl.comboBox.Foreground = e.NewValue.Value; 78 | } 79 | } 80 | 81 | public new static readonly StyledProperty OverlayBrushProperty = 82 | AvaloniaProperty.Register(nameof(OverlayBrush)); 83 | 84 | public new IBrush OverlayBrush 85 | { 86 | get => GetValue(OverlayBrushProperty); 87 | set => SetValue(OverlayBrushProperty, value); 88 | } 89 | 90 | private static void OverlayBrushPropertyChanged(AvaloniaPropertyChangedEventArgs e) 91 | { 92 | if (e.Sender is CustomComboBox ctrl) 93 | { 94 | ctrl.comboBox.BorderBrush = e.NewValue.Value; 95 | } 96 | } 97 | 98 | public static readonly StyledProperty NameProperty = 99 | AvaloniaProperty.Register(nameof(Name), defaultValue:"Combo Box"); 100 | 101 | public string Name 102 | { 103 | get => GetValue(NameProperty); 104 | set => SetValue(NameProperty, value); 105 | } 106 | 107 | private static void NamePropertyChanged(AvaloniaPropertyChangedEventArgs e) 108 | { 109 | if (e.Sender is CustomComboBox ctrl) 110 | { 111 | ctrl.nameLabel.Content = e.NewValue.Value; 112 | } 113 | } 114 | 115 | public new static readonly StyledProperty> ItemsProperty = 116 | AvaloniaProperty.Register>(nameof(Items)); 117 | 118 | public IList Items 119 | { 120 | get => GetValue(ItemsProperty); 121 | set => SetValue(ItemsProperty, value); 122 | } 123 | 124 | private static void ItemsPropertyChanged(AvaloniaPropertyChangedEventArgs> e) 125 | { 126 | if (e.Sender is CustomComboBox ctrl) 127 | { 128 | ctrl.comboBox.Items = e.NewValue.Value; 129 | } 130 | } 131 | 132 | public new static readonly StyledProperty ItemSelectedProperty = 133 | AvaloniaProperty.Register(nameof(ItemSelected)); 134 | 135 | public ICommand ItemSelected 136 | { 137 | get => GetValue(ItemSelectedProperty); 138 | set => SetValue(ItemSelectedProperty, value); 139 | } 140 | 141 | public static readonly StyledProperty SelectedIndexProperty = 142 | AvaloniaProperty.Register(nameof(SelectedIndex), defaultValue:-1, defaultBindingMode:BindingMode.TwoWay); 143 | 144 | public int SelectedIndex 145 | { 146 | get => GetValue(SelectedIndexProperty); 147 | set => SetValue(SelectedIndexProperty, value); 148 | } 149 | 150 | private static void SelectedIndexPropertyChanged(AvaloniaPropertyChangedEventArgs e) 151 | { 152 | if (e.Sender is CustomComboBox ctrl) 153 | { 154 | ctrl.comboBox.SelectedIndex = e.NewValue.Value; 155 | } 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/CustomSearchBar.axaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/CustomSearchBar.axaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reactive.Linq; 3 | using System.Windows.Input; 4 | using Avalonia; 5 | using Avalonia.Controls; 6 | using Avalonia.Data; 7 | using Avalonia.Interactivity; 8 | using Avalonia.Markup.Xaml; 9 | using Avalonia.Media; 10 | using CutCode.CrossPlatform.Helpers; 11 | using CutCode.CrossPlatform.Services; 12 | using ReactiveUI; 13 | 14 | namespace CutCode.CrossPlatform.Controls 15 | { 16 | public class CustomSearchBar : UserControl 17 | { 18 | private TextBox textBox; 19 | private ProgressBar progressBar; 20 | private Button CloseButton; 21 | private Grid panel; 22 | static CustomSearchBar() 23 | { 24 | BackgroundProperty.Changed.Subscribe(BackgroundPropertyChanged); 25 | ForegroundProperty.Changed.Subscribe(ForegroundPropertyChanged); 26 | OverlayBrushProperty.Changed.Subscribe(OverlayBrushPropertyChanged); 27 | TextProperty.Changed.Subscribe(TextPropertyChanged); 28 | PlaceHolderTextProperty.Changed.Subscribe(PlaceHolderTextPropertyChanged); 29 | IsSearchBusyProperty.Changed.Subscribe(IsSearchBusyPropertyChanged); 30 | } 31 | public CustomSearchBar() 32 | { 33 | InitializeComponent(); 34 | this.GetControl("textBox", out textBox); 35 | this.GetControl("progressBar", out progressBar); 36 | this.GetControl("CloseButton", out CloseButton); 37 | this.GetControl("panel", out panel); 38 | 39 | textBox.DataContext = this; 40 | progressBar.IsVisible = false; 41 | 42 | CloseButton.Foreground = ThemeService.Current.Theme == ThemeType.Light ? Brushes.Black : Brushes.White; 43 | ThemeService.Current.ThemeChanged += (sender, args) => 44 | { 45 | var service = (ThemeService)sender!; 46 | textBox.CaretBrush = ThemeService.Current.Theme == ThemeType.Light ? Brushes.Black : Brushes.White; 47 | CloseButton.Foreground = ThemeService.Current.Theme == ThemeType.Light ? Brushes.Black : Brushes.White; 48 | }; 49 | 50 | this.WhenAnyValue(x => x.textBox.Text) 51 | .Throttle(TimeSpan.FromMilliseconds(700)) 52 | .ObserveOn(RxApp.MainThreadScheduler) 53 | .Subscribe(SearchActivate!); 54 | 55 | CloseButton.Click += CloseButtonOnClick; 56 | } 57 | 58 | private void CloseButtonOnClick(object? sender, RoutedEventArgs e) 59 | { 60 | textBox.Clear(); 61 | Text = string.Empty; 62 | CloseButton.IsVisible = false; 63 | SearchCancelled?.Execute(null); 64 | } 65 | 66 | private void InitializeComponent() 67 | { 68 | AvaloniaXamlLoader.Load(this); 69 | } 70 | 71 | private string _oldText = ""; 72 | private async void SearchActivate(string s) 73 | { 74 | if (string.IsNullOrWhiteSpace(s) || s == _oldText) 75 | { 76 | IsSearchBusy = false; 77 | CloseButton.IsVisible = false; 78 | SearchCancelled?.Execute(s); 79 | return; 80 | } 81 | CloseButton.IsVisible = true; 82 | _oldText = s; 83 | SearchCommand?.Execute(s); 84 | } 85 | 86 | public new static readonly StyledProperty BackgroundProperty = 87 | AvaloniaProperty.Register(nameof(Background)); 88 | 89 | public new IBrush Background 90 | { 91 | get => GetValue(BackgroundProperty); 92 | set => SetValue(BackgroundProperty, value); 93 | } 94 | 95 | private static void BackgroundPropertyChanged(AvaloniaPropertyChangedEventArgs e) 96 | { 97 | if (e.Sender is CustomSearchBar ctrl) 98 | { 99 | ctrl.textBox.Background = e.NewValue.Value; 100 | ctrl.panel.Background = e.NewValue.Value; 101 | } 102 | } 103 | 104 | public new static readonly StyledProperty ForegroundProperty = 105 | AvaloniaProperty.Register(nameof(Foreground)); 106 | 107 | public new IBrush Foreground 108 | { 109 | get => GetValue(ForegroundProperty); 110 | set => SetValue(ForegroundProperty, value); 111 | } 112 | 113 | private static void ForegroundPropertyChanged(AvaloniaPropertyChangedEventArgs e) 114 | { 115 | if (e.Sender is CustomSearchBar ctrl) 116 | { 117 | ctrl.textBox.Foreground = e.NewValue.Value; 118 | } 119 | } 120 | 121 | public new static readonly StyledProperty OverlayBrushProperty = 122 | AvaloniaProperty.Register(nameof(OverlayBrush)); 123 | 124 | public new IBrush OverlayBrush 125 | { 126 | get => GetValue(OverlayBrushProperty); 127 | set => SetValue(OverlayBrushProperty, value); 128 | } 129 | 130 | private static void OverlayBrushPropertyChanged(AvaloniaPropertyChangedEventArgs e) 131 | { 132 | if (e.Sender is CustomSearchBar ctrl) 133 | { 134 | ctrl.textBox.BorderBrush = e.NewValue.Value; 135 | } 136 | } 137 | 138 | public new static readonly StyledProperty TextProperty = 139 | AvaloniaProperty.Register(nameof(TextProperty), defaultBindingMode: BindingMode.TwoWay); 140 | 141 | public new string Text 142 | { 143 | get => GetValue(TextProperty); 144 | set => SetValue(TextProperty, value); 145 | } 146 | 147 | private static void TextPropertyChanged(AvaloniaPropertyChangedEventArgs e) 148 | { 149 | if (e.Sender is CustomSearchBar ctrl) 150 | { 151 | ctrl.textBox.Text = e.NewValue.Value; 152 | } 153 | } 154 | 155 | public new static readonly StyledProperty PlaceHolderTextProperty = 156 | AvaloniaProperty.Register(nameof(PlaceHolderText)); 157 | 158 | public new string PlaceHolderText 159 | { 160 | get => GetValue(PlaceHolderTextProperty); 161 | set => SetValue(PlaceHolderTextProperty, value); 162 | } 163 | 164 | private static void PlaceHolderTextPropertyChanged(AvaloniaPropertyChangedEventArgs e) 165 | { 166 | if (e.Sender is CustomSearchBar ctrl) 167 | { 168 | ctrl.textBox.Watermark = e.NewValue.Value; 169 | } 170 | } 171 | 172 | public new static readonly StyledProperty SearchCommandProperty = 173 | AvaloniaProperty.Register(nameof(SearchCommand)); 174 | public ICommand SearchCommand 175 | { 176 | get => GetValue(SearchCommandProperty); 177 | set => SetValue(SearchCommandProperty, value); 178 | } 179 | 180 | public new static readonly StyledProperty SearchCancelledProperty = 181 | AvaloniaProperty.Register(nameof(SearchCancelled)); 182 | public ICommand SearchCancelled 183 | { 184 | get => GetValue(SearchCancelledProperty); 185 | set => SetValue(SearchCancelledProperty, value); 186 | } 187 | 188 | public new static readonly StyledProperty IsSearchBusyProperty = 189 | AvaloniaProperty.Register(nameof(IsSearchBusy)); 190 | 191 | public bool IsSearchBusy 192 | { 193 | get => GetValue(IsSearchBusyProperty); 194 | set => SetValue(IsSearchBusyProperty, value); 195 | } 196 | 197 | private static void IsSearchBusyPropertyChanged(AvaloniaPropertyChangedEventArgs e) 198 | { 199 | if (e.Sender is CustomSearchBar ctrl) 200 | { 201 | ctrl.progressBar.IsVisible = e.NewValue.Value; 202 | } 203 | } 204 | } 205 | } -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/NavigationItem.axaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 22 | 25 | 26 | 27 | 28 | 30 | 35 | 36 | -------------------------------------------------------------------------------- /src/CutCode.CrossPlatform/Controls/NavigationItem.axaml.cs: -------------------------------------------------------------------------------- 1 | // --------------------------------------------- 2 | // --- CutCode.CrossPlatform by Scarementus --- 3 | // --- Licence MIT --- 4 | // --------------------------------------------- 5 | 6 | using System.Windows.Input; 7 | using Aura.UI.Extensions; 8 | using Avalonia; 9 | using Avalonia.Controls; 10 | using Avalonia.Controls.Shapes; 11 | using Avalonia.Interactivity; 12 | using Avalonia.Markup.Xaml; 13 | using Avalonia.Media; 14 | using Avalonia.Xaml.Interactions.Custom; 15 | 16 | namespace CutCode.CrossPlatform.Controls; 17 | 18 | public class NavigationItem : UserControl 19 | { 20 | private Path IconPath => this.FindControl(nameof(IconPath)); 21 | 22 | private Border ActiveBorder => this.FindControl(nameof(ActiveBorder)); 23 | 24 | private Button MainButton => this.FindControl