Blog

  • vegalite-for-powerbi

    PowerBi Custom Visual in Vega-Lite

    NOTE: This project is now archived. We recommend https://github.com/deneb-viz/deneb as a well maintained replacement for this project.

    This project demonstrates how Vega and Vega-Lite can be used in custom visuals in PowerBI. This custom visual is not intended for daily use. Think of it as a hello world for Vega and Vega-Lite in PowerBI custom visuals.

    Screenshot

    Install

    First install necessary dependencies with npm install. Then run npm run cert and follow the instructions at https://github.com/Microsoft/PowerBI-visuals/blob/master/tools/CertificateAddOSX.md.

    Run

    Run npm start in a terminal.

    The open PowerBI with developer mode enabled and create a developer visual.

    Contributing

    This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

    When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

    This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

    Visit original content creator repository https://github.com/microsoft/vegalite-for-powerbi
  • DynamicsCrm-Template-based-Code-Generator-Plugin

    DynamicsCrm-Template-based-Code-Generator-Plugin

    Join the chat at https://gitter.im/yagasoft/DynamicsCrm-TemplateBasedCodeGeneratorPlugin


    An XrmToolBox plugin that can be used to generate Early-bound code from a CRM Schema using a customisable T4 Template.

    Features

    • Preserved the original CrmSvcUtil structure and logic.
    • Customize the way the code is generated.
      • You get a default T4 template for the code that is generated, with a multitude more features than the official tool (features below).
      • You can rewrite the whole template if you wish for any possible requirements.
    • Replaced the SDK types with .NET types.
    • Generate only what’s needed
      • Only choose the entities required.
      • Only the fields required.
    • Additional control
      • Option to use display names of entities and fields as variable names instead of logical names.
      • Override field names inside the tool’s UI.
      • Ability to Lock variable names to avoid code errors on regeneration.
    • Support for strongly-typed alternate keys, for entities and Entity References.
    • Add annotations for model validation.
    • Generate metadata.
      • Field logical and schema names.
      • Localised labels.
    • Automatically limit attributes retrieved from CRM on any entity in a LINQ to the ones choosen (filtered) in the tool (check new entity constructors).
    • Many options to optimise generated code size even further.
    • Generate concrete classes for CRM Actions.
    • Support bulk relation loading.
      • Support filtering on relation loading.

    Usage

    Install (here).

    • Load data
    • Choose entities
    • Optionally edit the default T4 Template
    • Generate
    • Save output CS code

    A more sophisticated Visual Studio Extension can be found at VS Marketplace.

    The engine for this Plugin and the VS Extension is the same. The settings and T4 Templates can be used for both (with minor modifications).

    You can read a quick overview of the tool and its functionality here.

    Changes

    • Check Releases page for the later changes

    v1.0.0.3 to v2.3.1.1 (since 2020-08-25)

    • Added: all missing features from VS extension (click on ‘Quick Guide’ for more info), except Contracts
    • Added: keep track of paths (settings, template, and code) used in previous sessions and the links between them
    • Added: recent settings list (load history)
    • Added: reset option for the template text
    • Added: toast notification for clearer status
    • Added: Filter Details window row filtering
    • Improved: load and save logic
    • Improved: filtering feature now works over logical and display names, and renames
    • Changed: updated package name
    • Updated: latest custom libraries
    • Fixed: assembly issues
    • Fixed: layout issues
    • Fixed: fixed cancel button
    • Fixed: issues
    • Fixed: generated code ‘labels’ syntax error
    • Fixed: mishandling errors
    • Fixed: template issues

    v1.0.0.1 (2020-08-24)

    • Initial release

    Copyright © by Ahmed Elsawalhy (Yagasoft)GPL v3 Licence

    Visit original content creator repository https://github.com/yagasoft/DynamicsCrm-Template-based-Code-Generator-Plugin
  • generate-ddg

    Generate DDG

    GitHub Actions Build Workflow Status Static Badge

    Go program that allows you to generate DuckDuckGo email aliases from the command line. Demo

    Setup and Usage

    1. Create a Duck Address if you don’t already have one
    2. Run generate-ddg config to complete the initial setup.
      • Config key names can also be set as environment variables (capitalized and - replaced with _)
      • .env is loaded
    3. Run generate-ddg
      • In some cases, this may error if DuckDuckGo suspects you are a bot. If this happens, try to login normally (through DuckDuckGo) and when the magic link/phrase is sent to your email, run the program again with --otp "<phrase>".
      • The config files will be stored in <XDG_CONFIG_HOME>/generate-ddg/. The directory is dependent on your OS:
        • Linux: `~/.config/generate-ddg.
        • Windows: %APPDATA%\generate-ddg
        • MacOS: ~/Library/Application Support/generate-ddg
        • For more information, see adrg/xdg
    4. The program will generate a new email alias and print it to the console.

    Installation

    Binary

    Download the latest release from the releases page, ensuring you download the correct binary for your system.
    Execute the binary from the command line! Optionally, you can move it to a directory in your PATH.
    For example, on Linux, if you’ve downloaded generate-ddg_linux_amd64 to your Downloads directory:

    mv ~/Downloads/generate-ddg_linux_amd64 /usr/local/bin/generate-ddg
    chmod +x /usr/local/bin/generate-ddg
    generate-ddg # Run it!

    Building from source

    Ensure you have Go installed on your system.

    git clone https://github.com/slashtechno/generate-ddg.git
    cd generate-ddg
    go install

    Contributing

    Pull Requests are welcome!

    Acknowledgements

    • whatk233/ddg-email-panel
      • Ended up looking through the source code to get a better understanding of how DuckDuckGo’s authentication works.
    • DuckDuckGo
      • I’ve not run into any issues (at the time of writing) with their service and it’s worked quite well for me.
    • Bitwarden
      • They have a feature wherein you can input the API token for DuckDuckGo (retrieved from DevTools’ Network tab) allowing you to generate aliases from within the Bitwarden.
    Visit original content creator repository https://github.com/slashtechno/generate-ddg
  • Chameleody

    Chameleody: Music Player with most features which other music players have and more original features. I haven’t finished it yet. But, It is enough ready to use.

    Original Features that I am going to add and which is the reason I am developing and loving this project: Ability to add every information about the song: mood, genre, version, age added; also will be added bpm, singer’s voice, Ability to add smart templates, which later you can use for smart search and smart shuffle. It is like “Version : Original – 100%, Remix – 60%, Cover – 20%, Instrumental – 0%”. And for all other classifications When you will use it to searching it will show all bigger than 0% or only 100%. If You use it for smart shuffle, I think you understand how it will work

    Why I am doing this: Everyone uses shuffle in music players, But I wanted a smarter one, I used a 5-star classification of AIMP, but it wasn’t enough. Your specifications are changeable of your situation, mood. Sometimes you are sad, sometimes you energized, sometimes you are just only what to hear NightCore remixes, sometimes you want calm, dreaming songs.

    Final Project requirements:
    Link to a repository (30 pts max)✅
    Use of data storage (DB, Cloud or SharedPreferences) (20 pts max)✅ SharedPreferences, Room. (Also Firebase will be added, now there is only json file)
    Design and representation (figma design first is welcome) (20 pts max)✅ link
    Wise use of libraries and frameworks (20 pts max)✅ gradle Glide; Room; Coroutines; Lifecycle, Palette and Media from androidx
    Clean code (10 pts max)❌
    BONUS POINTS FOR (20 pts):
    Projects related to our University❌
    Projects which use Dagger, Glide other tools✅ Used Glide for all cover art displays and getting a palette of cover art in the player window Submit link to repository:
    commit history elder than 1 week (10 pts)✅
    apk in releases (5 pts)✅ will be
    screenshots, name and short description (15 pts)✅ will be

    Screenshots of UI

    Main window Player window
    UI colors of Player will change according to song’s art’s color
    Player has four tabs
    Lyrics Cover art General info Mood classification

    Screenshots of misc capabilities

    App icon Logo Asking for permission
    Searching songs Sorting songs list Notification
    Player has four shuffle types, on the left of play button, on the right new feature which has not implemented
    Repeat one, when next or prev pressed it will work like a Repeat All Repeat All Shuffle All Smart shuffle, this one doesn’t implemented yet. It is going to be one of the original features
    Visit original content creator repository https://github.com/DosU13/Chameleody
  • SwiftUI-Apple-Watch-Decimal-Pad

    SwiftUI Apple Watch Decimal Pad

    With SwiftUI currently, Apple has not provided a decimal keypad for watchOS. Nor have they provided the ability to switch input types on a TextField() for watchOS. This is my kinda dirty fix.

    Apple Watch 44mm

    Demo of Keyboard 44mm Screen Size

    Apple Watch 38mm

    Demo of Keyboard 38mm Screen Size

    Installation Instructions

    WatchOS also has a weird issue with Swift Packages where you have to manually add the framework to the Watch Extension.

    File > Swift Packages > add Package Dependecy... paste https://github.com/ApplebaumIan/SwiftUI-Apple-Watch-Decimal-Pad.git into the search bar. Once installed navigate to your Xcode Project and select the General tab. Select your watchOS Extension target and scroll to Frameworks, Libraries, and Embedded Content click the + button and add SwiftUI Apple Watch Decimal Pad framework.

    You should now be able to add import SwiftUI_Apple_Watch_Decimal_Pad to the top of your desired Swift file.

    Usage

    import SwiftUI
    import SwiftUI_Apple_Watch_Decimal_Pad
    struct ContentView: View {
    	@State public var presentingModal: Bool
    	var body: some View {
    		DigiTextView(placeholder: placeholder, 
    			text: text,
    			presentingModal: presentingModal
    			)
    	}
    }

    If you would like to set the alignment of the text withing the Textfield:

    DigiTextView(placeholder: placeholder,
    	text: text, 
    	presentingModal: presentKeyboard,
    +	alignment: .leading
    	)

    If you would like to use the Decimil Pad version of the keyboard:

    DigiTextView(placeholder: placeholder,
    	text: text, 
    	presentingModal: presentKeyboard,
    	alignment: .leading,
    + 	style: .decimal
    	)
    Visit original content creator repository https://github.com/ApplebaumIan/SwiftUI-Apple-Watch-Decimal-Pad
  • booklist

    booklist

    Booklist fullstack project using Spring Boot microservices for backend and Angular micro frontends for UI.

    User authentication using JWT refresh & access tokens, ability to view, paginate, add or remove books from/to ‘My Books’ or ‘Wishlist’.

    Application is using Mongo NoSQL database which is populated on books-service backend application startup using JSON file.

    Backend services communication with frontend is implemented through Spring Cloud API Gateway & Eureka Service Discovery using localhost:9090 URL.

    Frontend application is accessible through URL localhost:4201.
    Shell (base) micro-frontend application loads books micro-frontend as remote using WebPack Module Federation exporting remoteEntry.js file.

    Run application’s Docker containers

    docker compose -f "docker-compose.yml" up -d

    Use application

    As a guest (not logged-in user) you can navigate through books and search for book by author or title. Base URL to use is http://localhost:4201/

    Use application as logged-in user

    Backend applications endpoints

    Books microservice

    • Get book by ISBN
    [GET] http://localhost:9090/api/v1/books/{ISBN}
    
    • Get books with optional pagination (by default returns first 10 results)
    [GET] http://localhost:9090/api/v1/books?page=0&size=10
    
    • Create new book (requires authenticated user with ‘book:create’ authority set in JWT token as Authorization header)
    [POST] http://localhost:9090/api/v1/books
    

    {
        "author":  "J. K. Rowling",
        "title": "Harry Potter and the Order of the Phoenix",
        "isbn": "054579143X",
        "pages": "576",
        "hardTop": "true",
        "ebook": "false",
        "imageUrl": "https://m.media-amazon.com/images/I/51bZujlJxlL._SX422_BO1,204,203,200_.jpg"
    }
    
    • Update a book by ISBN (requires authenticated user with ‘book:update’ authority set in JWT token as Authorization header)
    [PUT] http://localhost:9090/api/v1/books/054579143X
    

    {
        "author":  "J. K. Rowling",
        "title": "Harry Potter and the Prisoner of Azkaban",
        "isbn": "9780439554923",
        "imageUrl": "https://m.media-amazon.com/images/P/1408855674.01._SCLZZZZZZZ_SX500_.jpg"
        "pages": "576"
    }
    
    • Partially update a book by ISBN (requires authenticated user with ‘book:update’ authority set in JWT token as Authorization header)
    [PATCH] http://localhost:9090/api/v1/books/054579143X
    

    {
        "pages": "577"
    }
    
    • Delete a book by ISBN (requires authenticated user with ‘book:delete’ authority set in JWT token as Authorization header)
    [DELETE] http://localhost:9090/api/v1/books/{ISBN}
    
    • Get My-Books with optional pagination (by default returns first 10 results) (requires authenticated user with ‘book:read’ (default) authority set in JWT token as Authorization header)
    [GET] http://localhost:9090/api/v1/my-books
    
    • Add new book by ISBN to My-Books (requires authenticated user with ‘book:read’ (default) authority set in JWT token as Authorization header)
    [POST] http://localhost:9090/api/v1/my-books/{ISBN}
    
    • Delete a book by ISBN from My-Books (requires authenticated user with ‘book:read’ (default) authority set in JWT token as Authorization header)
    [DELETE] http://localhost:9090/api/v1/my-books/{ISBN}
    
    • Get Wishlist with optional pagination (by default returns first 10 results) (requires authenticated user with ‘book:read’ (default) authority set in JWT token as Authorization header)
    [GET] http://localhost:9090/api/v1/wishlist
    
    • Add new book by ISBN to Wishlist (requires authenticated user with ‘book:read’ (default) authority set in JWT token as Authorization header)
    [POST] http://localhost:9090/api/v1/wishlist/{ISBN}
    
    • Delete a book by ISBN from Wishlist (requires authenticated user with ‘book:read’ (default) authority set in JWT token as Authorization header)
    [DELETE] http://localhost:9090/api/v1/wishlist/{ISBN}
    

    Users microservice (authentication)

    • Register to create new user with default ‘booklister’ role and ‘book:read’ authority. Created user is retured as response.
    [POST] http://localhost:9090/register
    

    {
        "firstName" : "Jacob",
        "lastName": "Oliver",
        "email": "jacob.oliver@example.com",
        "password": "password"
    }
    
    • Login to get JWT refresh token as Authorization header. JSON object should be sent with “email” and “password” fields.
    [POST] http://localhost:9090/login
    

    {
        "email": "jacob.oliver@example.com",
        "password": "password"
    }
    
    • Reset access token using refresh token stored in Local Storage after login (if using endpoints manually – refresh token should be sent as Authorization header & new access token in ‘Authorization’ header is returned)
    [POST] http://localhost:9090/resettoken
    

    Elastic Stack (formerly ELK) log aggregation

    Microservices logs is accessible in Elastic Stack using Kibana URL http://localhost:5601/app/kibana#/discover.

    Directions for first-time startup

    Visit original content creator repository
    https://github.com/MindaugasJasiunas/booklist

  • stock-trading-notif

    Python-Stock-Trading-News-Notifier

    Hello! This is a python program that is used for notifying Stock Trading News via SMS. I’ve referenced this from Angela’s 100 Days of Python Udemy Course. There are a few things that you will need to do in order to make this API work. an Example of a Stock Trading News Section is right here. Let’s take Tesla for example: tesla example What we want is a reproduction of this, but on an SMS.

    image

    The idea here is that we want to compare the closing prices of a certain company’s stock (In this case, it is Tesla) to the day before yesterday (y3) and yesterday (y2). If there is a difference in closing stock price, then depending on the situation, a news article will pop up in your SMS messanger (or in any phone number you specify it to).

    You will need to import a few libraries like so to get this python applicaiton running.

    image

    The request library is used for getting data and information from external APIs, and also establish connections with.

    You will also need to install the twilio rest library to connect python/your environment. The links for all the APIs:

    Twilio: https://www.twilio.com

    Alphavantage: https://www.alphavantage.co

    News API: https://newsapi.org

    Visit original content creator repository https://github.com/ArmandFS/stock-trading-notif
  • DSFPasscodeView

    DSFPasscodeView

    A passcode entry field for macOS similar to Apple’s two-factor authentication field.


    Swift Package Manager

    About

    The control is made up of multiple groups of passcode ‘cells’. Each cell holds a single ‘character’, and you define groups of cells using a group separator. The pattern you define provides the layout — containing # for a passcode cell and - for a group separator.

    For example, to create a passcode of six characters split evenly into two groups of three cells, you set the passcode pattern to "###-###"

    .---. .---. .---.   .---. .---. .---.
    |   | |   | |   |   |   | |   | |   |
    |   | |   | |   |   |   | |   | |   |
    `---' `---' `---'   `---' `---' `---'
    

    This control can be used in both autolayout and manual layout apps (internally the control does not use auto-layout)

    Note this control uses @VIViewInvalidating providing automatic NSView invalidation when properties value change. (automatically added as a dependency)

    Features

    • Configurable allowable character support
    • Character Viewer support (eg. hit Command-Ctrl-Space when a passcode cell is active)
    • Different fonts
    • Different spacing (intra-cell, edge insets, group and cell spacing)
    • Light and dark modes
    • High contrast support
    • Accessibility and VoiceOver support

    Installation

    Using Swift Package Manager, add https://github.com/dagronf/DSFPasscodeView to your project.

    Settings

    pattern (String)

    The cell pattern to use when displaying the passcode. A # represents a cell and a - represents a group space.

    The only valid characters are # (a cell) and – (group spacing). Attempting to set a pattern with any other character will result in a fatalError()

    Examples :-

    "###-###"
    .---. .---. .---.   .---. .---. .---.
    |   | |   | |   |   |   | |   | |   |
    |   | |   | |   |   |   | |   | |   |
    `---' `---' `---'   `---' `---' `---'
    
    "####-##-###"
    .---. .---. .---. .---.   .---. .---.   .---. .---. .---.
    |   | |   | |   | |   |   |   | |   |   |   | |   | |   |
    |   | |   | |   | |   |   |   | |   |   |   | |   | |   |
    `---' `---' `---' `---'   `---' `---'   `---' `---' `---'
    
    "##-##-#"
    .---. .---.   .---. .---.   .---.
    |   | |   |   |   | |   |   |   |
    |   | |   |   |   | |   |   |   |
    `---' `---'   `---' `---'   `---'
    

    cellSpacing (CGFloat)

    The spacing to use between adjacent cells

    groupSpacing (CGFloat)

    The spacing to use between cell groups

    font (NSFont)

    The font to use when displaying the character in a cell

    padding (CGSize)

    The padding to use between the character and the edge of its cell

    edgeInsets (NSEdgeInsets)

    The padding to use between the cells and the bounds of the control

    isEnabled (Bool)

    Enable or disable the control (observable)

    Validations

    There are two methods of validation

    allowableCharacters (String)

    This settings on the control allows you to specify a string containing the characters that are allowed within the control. By default, this is 0123456789.

    characterValidatorBlock

    For more complex validations, you can specify a callback block which can be used to validate each character

    It takes a string element and returns either a value transformed string element (for example, uppercased), or nil if the presented character isn’t valid for the control.

    // A validator block which allows numbers and case-insensitive A-F characters
    self.passcode.characterValidatorBlock = { element in
       let validChars = "0123456789ABCDEF"
       let s = element.uppercased()         // Always check against uppercase
       if validChars.contains(s) {          // If the validChars contains the uppercased char...
           return s.first                   //  ... return the uppercased version
       }
       return nil                           // Unsupported char, ignore by returning nil
    }

    Values

    You can bind to these member variables to receive updates as the control content changes.

    isValidPasscode (Bool)

    Is the passcode entered a valid passcode (ie. all the values are specified)

    isEmpty (Bool)

    Are there no values specified yet

    passcodeValue (String)

    If the passcode is valid, the passcode value as a string, otherwise nil.

    Delegate (DSFPasscodeViewHandling)

    You can attach a delegate to receive messages back from the view if binding is not your thing.

    func passcodeViewDidChange(
       _ view: DSFPasscodeView)

    Called when the content of the passcode view changes.

    func passcodeView(
       _ view: DSFPasscodeView,                        // The passcode view
       updatedPasscodeValue passcode: String)          // The valid passcode as a string of characters

    Called ONLY when the passcode is valid and complete.

    func passcodeView(
       _ view: DSFPasscodeView,                        // The passcode view 
       didTryInvalidCharacter invalidChar: String?,    // The invalid character, or nil for a special key
       atIndex index: Int)                             // The passcode cell index where the attempt failed

    Called if the user presses an unsupported character or key in a passcode cell.

    Known issues

    • Xcode has been broken for many years regarding support for @IBDesignable/@IBInspectable. Whilst this control provides support, Xcode’s support for @IBDesignable for a control provided from a package is completely broken.

    If you copy the DSFPasscodeView source files directly into your project the Designables work as expected (FB8358478).

    License

    MIT. Use it and abuse it for anything you want, just attribute my work. Let me know if you do use it somewhere, I’d love to hear about it!

    MIT License
    
    Copyright (c) 2021 Darren Ford
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    
    Visit original content creator repository https://github.com/dagronf/DSFPasscodeView
  • DSFPasscodeView

    DSFPasscodeView

    A passcode entry field for macOS similar to Apple’s two-factor authentication field.


    Swift Package Manager

    About

    The control is made up of multiple groups of passcode ‘cells’. Each cell holds a single ‘character’, and you define groups of cells using a group separator. The pattern you define provides the layout — containing # for a passcode cell and - for a group separator.

    For example, to create a passcode of six characters split evenly into two groups of three cells, you set the passcode pattern to "###-###"

    .---. .---. .---.   .---. .---. .---.
    |   | |   | |   |   |   | |   | |   |
    |   | |   | |   |   |   | |   | |   |
    `---' `---' `---'   `---' `---' `---'
    

    This control can be used in both autolayout and manual layout apps (internally the control does not use auto-layout)

    Note this control uses @VIViewInvalidating providing automatic NSView invalidation when properties value change. (automatically added as a dependency)

    Features

    • Configurable allowable character support
    • Character Viewer support (eg. hit Command-Ctrl-Space when a passcode cell is active)
    • Different fonts
    • Different spacing (intra-cell, edge insets, group and cell spacing)
    • Light and dark modes
    • High contrast support
    • Accessibility and VoiceOver support

    Installation

    Using Swift Package Manager, add https://github.com/dagronf/DSFPasscodeView to your project.

    Settings

    pattern (String)

    The cell pattern to use when displaying the passcode. A # represents a cell and a - represents a group space.

    The only valid characters are # (a cell) and – (group spacing). Attempting to set a pattern with any other character will result in a fatalError()

    Examples :-

    "###-###"
    .---. .---. .---.   .---. .---. .---.
    |   | |   | |   |   |   | |   | |   |
    |   | |   | |   |   |   | |   | |   |
    `---' `---' `---'   `---' `---' `---'
    
    "####-##-###"
    .---. .---. .---. .---.   .---. .---.   .---. .---. .---.
    |   | |   | |   | |   |   |   | |   |   |   | |   | |   |
    |   | |   | |   | |   |   |   | |   |   |   | |   | |   |
    `---' `---' `---' `---'   `---' `---'   `---' `---' `---'
    
    "##-##-#"
    .---. .---.   .---. .---.   .---.
    |   | |   |   |   | |   |   |   |
    |   | |   |   |   | |   |   |   |
    `---' `---'   `---' `---'   `---'
    

    cellSpacing (CGFloat)

    The spacing to use between adjacent cells

    groupSpacing (CGFloat)

    The spacing to use between cell groups

    font (NSFont)

    The font to use when displaying the character in a cell

    padding (CGSize)

    The padding to use between the character and the edge of its cell

    edgeInsets (NSEdgeInsets)

    The padding to use between the cells and the bounds of the control

    isEnabled (Bool)

    Enable or disable the control (observable)

    Validations

    There are two methods of validation

    allowableCharacters (String)

    This settings on the control allows you to specify a string containing the characters that are allowed within the control. By default, this is 0123456789.

    characterValidatorBlock

    For more complex validations, you can specify a callback block which can be used to validate each character

    It takes a string element and returns either a value transformed string element (for example, uppercased), or nil if the presented character isn’t valid for the control.

    // A validator block which allows numbers and case-insensitive A-F characters
    self.passcode.characterValidatorBlock = { element in
       let validChars = "0123456789ABCDEF"
       let s = element.uppercased()         // Always check against uppercase
       if validChars.contains(s) {          // If the validChars contains the uppercased char...
           return s.first                   //  ... return the uppercased version
       }
       return nil                           // Unsupported char, ignore by returning nil
    }

    Values

    You can bind to these member variables to receive updates as the control content changes.

    isValidPasscode (Bool)

    Is the passcode entered a valid passcode (ie. all the values are specified)

    isEmpty (Bool)

    Are there no values specified yet

    passcodeValue (String)

    If the passcode is valid, the passcode value as a string, otherwise nil.

    Delegate (DSFPasscodeViewHandling)

    You can attach a delegate to receive messages back from the view if binding is not your thing.

    func passcodeViewDidChange(
       _ view: DSFPasscodeView)

    Called when the content of the passcode view changes.

    func passcodeView(
       _ view: DSFPasscodeView,                        // The passcode view
       updatedPasscodeValue passcode: String)          // The valid passcode as a string of characters

    Called ONLY when the passcode is valid and complete.

    func passcodeView(
       _ view: DSFPasscodeView,                        // The passcode view 
       didTryInvalidCharacter invalidChar: String?,    // The invalid character, or nil for a special key
       atIndex index: Int)                             // The passcode cell index where the attempt failed

    Called if the user presses an unsupported character or key in a passcode cell.

    Known issues

    • Xcode has been broken for many years regarding support for @IBDesignable/@IBInspectable. Whilst this control provides support, Xcode’s support for @IBDesignable for a control provided from a package is completely broken.

    If you copy the DSFPasscodeView source files directly into your project the Designables work as expected (FB8358478).

    License

    MIT. Use it and abuse it for anything you want, just attribute my work. Let me know if you do use it somewhere, I’d love to hear about it!

    MIT License
    
    Copyright (c) 2021 Darren Ford
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    
    Visit original content creator repository https://github.com/dagronf/DSFPasscodeView
  • sca-blogs

    Visit original content creator repository
    https://github.com/Cordelya/sca-blogs