TypeScript definitions for use-double-click
No description provided.
React Native Double Click/Tap
button double click for react-native
A simple React hook for differentiating single and double clicks on the same component.
Ash IDs - Time-sortable, double-click-selectable unique identifiers using Crockford Base32
A Vue directive to distinguish between click and double click
React Native Single and Double Click/Tap
react native double click component with instagram heart animation option
A double-click-to-edit text component for [Mantine](https://mantine.dev/), with precise caret placement.
Http file server with compression. Double click files and folders for the zip version
Handle click and double click events on same element on javascript.
Shows the meaning of a word when you double click on it
Register the .protoboard file type with its logo and a double-click handler across Windows, macOS, and Linux.
double-click-blocking-util
A Simple React Native Double Click preventing touchable
A Component for Double Click based on TouchableOpacity Wrapper. Build for React Native App and works on both Android and iOS.
Add double click dictionary definitions to your site!
Prevent double click on links with JS script
Drag-and-drop Claude Desktop installer for the Encima Board MCP server. Bundles the .mcpb so non-technical users can install in one double-click.
Double click confirmation hook for React
React-native pinch zoom view and double click
VueJS button plugin for bootstrap framework to show action in progress and avoid double click.
Non conflicting solutions of single click, double click and long press
A library for generating double clickable ids
System-wide keyboard navigation overlay: drive your desktop without the mouse.
Keyboard-driven mouse control
Borderless window with a custom titlebar for Slint applications on Windows, with native DWM shadows, rounded corners, and resize hit-testing.
Desktop app for monitoring GitHub Pull Requests and repository health
Terminal-based force-directed graph visualizer for markdown wikilinks
High-performance data visualization library for Rust, powered by Bevy
A simple Rust CLI to convert Markdown to HTML5 (styled with simple.css), with optional file watching
A VSCode-like file explorer TUI
run .jar files on double-click (windows only)
Blazing-fast lightweight PostgreSQL client built in Rust
Shared to msvcrt.dll or ucrtbase.dll and optimize the application file size.
Rack application for Google DFP. Comes packaged with optional and independant Rails and ad placeholder integrations.
Show Double Click for Publishers (DFP) ads over https for single page web apps
The Gui searches a default directory you specify in the data.rb file. The menu allows you to choose any directory on the system which will be searched for a match. Once a list of fetched files is displayed in the text window, you can open any one of these files by selecting it (clicked) and then double clicking the selection. The file will be opened in the associated editor such as Windows Notepad.
Perro is a light server built on top of mongrel that helps at least one developer be happy. If it had been designed as production server it would have a cooler name. Like "Dinosaur" or "Freckle". The Internet is a global system of interconnected computer networks. Developer creates files that are served through this global system. Developer may be tempted to develop such files by creating a folder, moving the files to such folder, double clicking them and watching what happens on the browser whose address bar reads "file:///Users/cohitre/development/my-project/index.html". Perro helps developer be happy by helping overcome temptation.
Twitterpunch =============== Twitterpunch is designed to work with PhotoBooth and OS X Folder Actions. When this script is called with the name of an image file, it will post the image to Twitter, along with a message randomly chosen from a list and a specified hashtag. If you call the script with the `--stream` argument instead, it will listen for tweets to that hashtag and download them to a specified directory. If the tweet came from another user, Twitterpunch will speak it aloud. Typically, you'll run one copy on an OSX laptop with PhotoBooth, and a separate copy on another machine (either Windows or OSX) for the viewer. You can also use a mobile device as a remote control, if you like. This will allow the user to enter a custom message for each photo that gets tweeted out, if they'd like. Configuration =========== Configure the program via the `~/.twitterpunch/config.yaml` YAML file. This file should look similar to the example below. --- :twitter: # twitter configuration :consumer_key: <consumer key> :consumer_secret: <consumer secret> :access_token: <access token> :access_token_secret: <access secret> :messages: # list of messages to attach - Hello there # to outgoing tweets - I'm a posting fool - minimally viable product :hashtag: Twitterpunch # The hashtag to post and listen to :handle: Twitterpunch # The twitter username to post as :photodir: ~/Pictures/twitterpunch/ # Where to save downloaded images :logfile: ~/.twitterpunch/activity.log # Where to save logs :viewer: # Use the built-in slideshow viewer :count: 5 # How many images to have onscreen at once :remote: :timeout: 45 # How long the button should remain disabled for :apptitle: dslrBooth # The photo booth application title :hotkey: space # Which hotkey to send to trigger a photo 1. Generate a skeleton configuration file * `twitterpunch --configure` 1. Edit the configuration file as needed. You'll be prompted with the path. * If you have your own Twitter application credentials, you're welcome to use them. 1. Authorize the application with the Twitter API. * `twitterpunch --authorize` Usage ========== ### Using OS X PhotoBooth 1. Start PhotoBooth at least once to generate its library. 1. Install the Twitterpunch Folder Action * `twitterpunch --install` * It may claim that it could not be attached, fear not. 1. Profit! * _and by that, I mean take some shots with PhotoBooth!_ *Note*: if the folder action doesn't seem to work and photos aren't posted to Twitter, here are some troubleshooting steps to take: 1. Run Twitterpunch by hand with photos as arguments. This may help you isolate configuration or authorization issues. * `twitterpunch foo.jpg` 1. Correct the path in the workflow. * `which twitterpunch` * Edit the Twitterpunch folder action to include that path. #### Using the remote web app Configure the remote web app using the `:remote` hash in `config.yaml`. You can usually find the title of the app using `system_profiler -detailLevel full SPApplicationsDataType` and grepping for the name or path to the `.app`. In this example, the title is _dslrBooth_. [ben@ganymede] ~ $ system_profiler -detailLevel full SPApplicationsDataType | grep -B8 dslrBooth.app dslrBooth: Version: 2.9 Obtained from: Identified Developer Last Modified: 10/14/17, 9:50 PM Kind: Intel 64-Bit (Intel): Yes Signed by: Developer ID Application: Hope Pictures LLC (MZR5GHAQX4), Developer ID Certification Authority, Apple Root CA Location: /Applications/dslrBooth.app 1. Run the app with `twitterpunch --remote` 1. Browse to the app with http://{address}:8080 1. [optional] If on an iOS device, add to your homescreen * This will give you "app behaviour", such as full screen, and a nice icon #### Troubleshooting. 1. Make sure the folder action is installed properly 1. Use the Finder to navigate to `~/Pictures/` 1. Right click on the `Photo Booth Library` icon and choose _Show Package Contents_. 1. Right click on the `Pictures` folder and choose `Services > Folder Actions Setup` 1. Make sure that the `Twitterpunch` action is attached. 1. Install the folder action 1. Open the `resources` folder of this gem. * Likely to be found in `/Library/Ruby/Gems/{version}/gems/twitterpunch-#{version}/resources/`. 1. Double click on the `Twitterpunch` folder action and install it. * It may claim that it could not be attached, fear not. ### Using something besides PhotoBooth Configure the program you are using for your photo shoot to call Twitterpunch each time it snaps a photo. Pass the name of the new photo as a command line argument. Alternatively, you could batch them, as Twitterpunch can accept multiple files at once. [ben@ganymede] ~ $ twitterpunch photo.jpg [photo2.jpg photo3.jpg photo4.jpg] You can manually install the Folder Action, or you can follow the automated install process after tweaking the workflow slightly. 1. Identify where the app stores the resulting image files. 1. Edit the Twitterpunch folder action to include that path. 1. Follow the steps above to install the Folder Action. ### Viewing the Twitter stream Twitterpunch will run on OS X or Windows equally well. Simply configure it on the computer that will act as the Twitter display and then run in streaming mode. [ben@ganymede] ~ $ twitterpunch --stream There are two modes that Twitterpunch can operate in. 1. If a `:hashtag` is defined then all images tweeted to the configured hashtag will be displayed in the slideshow. 1. Otherwise, Twitterpunch will stream the `:handle` Twitter user's stream and display all images either posted by that user or addressed to that user. With protected tweets, you can have rudimentary access control. In either mode, tweets that come from any other user will also be spoken aloud. If you don't want to use the built-in slideshow viewer, you can disable it by removing the `:viewer` key from your `~/.twitterpunch/config.yaml` config file. Twitterpunch will then simply download the tweeted images and save them into the `:photodir` directory. You can then use anything you like to view them. There are currently two decent viewing options I am aware of. * Windows background image: * Configure the Windows background to randomly cycle through photos in a directory. * Hide desktop icons. * Hide the taskbar. * Disable screensaver and power savings. * Drawbacks: You're using Windows and you have to install Ruby & RubyGems manually. * OS X screensaver: * Choose one of the sexy screensavers and configure it to show photos from the `:photodir` * Set screensaver to a super short timeout. * Disable power savings. * Drawbacks: The screensaver doesn't reload dynamically, so I have to kick it and you'll see it reloading each time a new tweet comes in. Limitations =========== * It currently requires manual setup for Folder Actions. * Rubygame is kind of a pain to set up. Contact ======= * Author: Ben Ford * Email: binford2k@gmail.com * Twitter: @binford2k * IRC (Freenode): binford2k
== Terminal UIs, the Ruby Way RatatuiRuby[https://rubygems.org/gems/ratatui_ruby] is a RubyGem built on Ratatui[https://ratatui.rs], a leading TUI library written in Rust[https://rust-lang.org]. You get native performance with the joy of Ruby. gem install ratatui_ruby {rdoc-image:https://ratatui-ruby.dev/hero.gif}[https://www.ratatui-ruby.dev/docs/v0.10/examples/app_cli_rich_moments/README_md.html] === Rich Moments Add a spinner, a progress bar, or an inline menu to your CLI script. No full-screen takeover. Your terminal history stays intact. ==== Inline Viewports Standard TUIs erase themselves on exit. Your carefully formatted CLI output disappears. Users lose their scrollback. <b>Inline viewports</b> solve this. They occupy a fixed number of lines, render rich UI, then leave the output in place when done. Perfect for spinners, menus, progress indicators—any brief moment of richness. require "ratatui_ruby" RatatuiRuby.run(viewport: :inline, height: 1) do |tui| until connected? status = tui.paragraph(text: "\#{spin} Connecting...") tui.draw { |frame| frame.render_widget(status, frame.area) } end end === Build Something Real Full-screen applications with {keyboard and mouse input}[https://www.ratatui-ruby.dev/docs/v0.10/examples/app_all_events/README_md.html]. The managed loop sets up the terminal and restores it on exit, even after crashes. RatatuiRuby.run do |tui| loop do tui.draw do |frame| frame.render_widget( tui.paragraph(text: "Hello, RatatuiRuby!", alignment: :center), frame.area ) end case tui.poll_event in { type: :key, code: "q" } then break else nil end end end ==== Widgets included: [Layout] {Block}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_block/README_md.html], {Center}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_center/README_md.html], {Clear (Popup, Modal)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_popup/README_md.html], {Layout (Split, Grid)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_layout_split/README_md.html], {Overlay}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_overlay/README_md.html] [Data] {Bar Chart}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_barchart/README_md.html], {Chart}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_chart/README_md.html], {Gauge}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_gauge/README_md.html], {Line Gauge}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_line_gauge/README_md.html], {Sparkline}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_sparkline/README_md.html], {Table}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_table/README_md.html] [Text] {Cell}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_cell/README_md.html], {List}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_list/README_md.html], {Rich Text (Line, Span)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_rich_text/README_md.html], {Scrollbar (Scroll)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_scrollbar/README_md.html], {Tabs}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_tabs/README_md.html] [Graphics] {Calendar}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_calendar/README_md.html], {Canvas}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_canvas/README_md.html], {Map (World Map)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_map/README_md.html] Need something else? {Build custom widgets}[https://www.ratatui-ruby.dev/docs/v0.10/doc/concepts/custom_widgets_md.html] in Ruby! --- === Testing Built In TUI testing is tedious. You need a headless terminal, event injection, snapshot comparisons, and style assertions. RatatuiRuby bundles all of it. require "ratatui_ruby/test_helper" class TestColorPicker < Minitest::Test include RatatuiRuby::TestHelper def test_swatch_widget with_test_terminal(10, 3) do RatatuiRuby.draw do |frame| frame.render_widget(Swatch.new(:red), frame.area) end assert_cell_style 2, 1, char: "█", bg: :red end end end ==== What's inside: - <b>Headless terminal</b> — No real TTY needed - <b>Snapshots</b> — Plain text and rich (ANSI colors) - <b>Event injection</b> — Keys, mouse, paste, resize - <b>Style assertions</b> — Color, bold, underline at any cell - <b>Test doubles</b> — Mock frames and stub rects - <b>UPDATE_SNAPSHOTS=1</b> — Regenerate baselines in one command --- ==== Inline Menu Example require "ratatui_ruby" # This example renders an inline menu. Arrow keys select, enter confirms. # The menu appears in-place, preserving scrollback. When the user chooses, # the TUI closes and the script continues with the selected value. class RadioMenu CHOICES = ["Production", "Staging", "Development"] # ASCII strings are universally supported. PREFIXES = { active: "●", inactive: "○" } # Some terminals may not support Unicode. CONTROLS = "↑/↓: Select | Enter: Choose | Ctrl+C: Cancel" # Let users know what keys you handle. TITLES = ["Select Environment", # The default title position is top left. { content: CONTROLS, # Multiple titles can save space. position: :bottom, # Titles go on the top or bottom, alignment: :right }] # aligned left, right, or center def call # This method blocks until a choice is made. RatatuiRuby.run(viewport: :inline, height: 5) do |tui| # RatauiRuby.run manages the terminal. @tui = tui # The TUI instance is safe to store. show_menu until chosen? # You can use any loop keyword you like. end # `run` won't return until your block does, RadioMenu::CHOICES[@choice] # so you can use it synchronously. end # Classes like RadioMenu are convenient for private # CLI authors to offer "rich moments." def show_menu = @tui.draw do |frame| # RatatuiRuby gives you low-level access. widget = @tui.paragraph( # But the TUI facade makes it easy to use. text: menu_items, # Text can be spans, lines, or paragraphs. block: @tui.block(borders: :all, titles: TITLES) # Blocks give you boxes and titles, and hold ) # one or more widgets. We only use one here, frame.render_widget(widget, frame.area) # but "area" lets you compose sub-views. end def chosen? # You are responsible for handling input. interaction = @tui.poll_event # Every frame, you receive an event object: return choose if interaction.enter? # Key, Mouse, Resize, Paste, FocusGained, # FocusLost, or None objects. They come with move_by(-1) if interaction.up? # predicates, support pattern matching, and move_by(1) if interaction.down? # can be inspected for properties directly. quit! if interaction.ctrl_c? # Your application must handle every input, false # even interrupts and other exit patterns. end def choose # Here, the loop is about to exit, and the prepare_next_line # block will return. The inline viewport @choice # will be torn down and the terminal will end # be restored, but you are responsible for # positioning the cursor. def prepare_next_line # To ensure the next output is on a new area = @tui.viewport_area # line, query the viewport area and move RatatuiRuby.cursor_position = [0, area.y + area.height] # the cursor to the start of the last line. puts # Then print a newline. end def quit! # All of your familiar Ruby control flow prepare_next_line # keywords work as expected, so we can exit 0 # use them to leave the TUI. end def move_by(line_count) # You are in full control of your UX, so @choice = (@choice + line_count) % CHOICES.size # you can implement any logic you need: end # Would you "wrap around" here, or not? # def menu_items = CHOICES.map.with_index do |choice, i| # Notably, RatatuiRuby has no concept of "\#{prefix_for(i)} \#{choice}" # "menus" or "radio buttons". You are in end # full control, but it also means you must def prefix_for(choice_index) # implement the logic yourself. For larger return PREFIXES[:active] if choice_index == @choice # applications, consider using Rooibos, PREFIXES[:inactive] # an MVU framework built with RatatuiRuby. end # Or, use the upcoming ratatui-ruby-kit, # our object-oriented component library. def initialize = @choice = 0 # However, those are both optional, and end # designed for full-screen Terminal UIs. # RatatuiRuby will always give you the most choice = RadioMenu.new.call # control, and is enough for "rich CLI puts "You chose \#{choice}!" # moments" like this one. --- === Full App Solutions RatatuiRuby renders. For complex applications, add a framework that manages state and composition. ==== Rooibos[https://www.rooibos.run] (Framework) Model-View-Update architecture. Inspired by Elm, Bubble Tea, and React + Redux. Your UI is a pure function of state. - Functional programming with MVU - Commands work off the main thread - Messages, not callbacks, drive updates ==== {Kit}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-3-the-object-path--kit] (Coming Soon) Component-based architecture. Encapsulate state, input handling, and rendering in reusable pieces. - OOP with stateful components - Separate UI state from domain logic - Built-in focus management & click handling Both use the same widget library and rendering engine. Pick the paradigm that fits your brain. --- === Why RatatuiRuby? Ruby deserves world-class terminal user interfaces. TUI developers deserve a world-class language. RatatuiRuby wraps Rust's Ratatui via native extension. The Rust library handles rendering. Your Ruby code handles design. >>> "Text UIs are seeing a renaissance with many new TUI libraries popping up. The Ratatui bindings have proven to be full featured and stable." — {Mike Perham}[https://www.mikeperham.com/], creator of Sidekiq[https://sidekiq.org/] and Faktory[https://contribsys.com/faktory/] ==== Why Rust? Why Ruby? Rust excels at low-level rendering. Ruby excels at expressing domain logic and UI. RatatuiRuby puts each language where it performs best. ==== Versus CharmRuby CharmRuby[https://charm-ruby.dev/] wraps Charm's Go libraries. Both projects give Ruby developers TUI options. [Integration] CharmRuby: Two runtimes, one process. RatatuiRuby: Native extension in Rust. [Runtime] CharmRuby: Go + Ruby (competing). RatatuiRuby: Ruby (Rust has no runtime). [Memory] CharmRuby: Two uncoordinated GCs. RatatuiRuby: One Garbage Collector. [Style] CharmRuby: The Elm Architecture (TEA). RatatuiRuby: TEA, OOP, or Imperative. --- === Links [Get Started] {Quickstart}[https://www.ratatui-ruby.dev/docs/v0.10/doc/getting_started/quickstart_md.html], {Examples}[https://www.ratatui-ruby.dev/docs/v0.10/examples/app_cli_rich_moments/README_md.html], {API Reference}[https://www.ratatui-ruby.dev/docs/v0.10/], {Guides}[https://www.ratatui-ruby.dev/docs/v0.10/doc/index_md.html] [Ecosystem] Rooibos[https://www.rooibos.run], {Kit}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-3-the-object-path--kit] (Planned), {Framework}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-5-the-framework] (Planned), {UI Widgets}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-6-licensing] (Planned) [Community] {Forum}[https://forum.setdef.com/c/ratatui-ruby/6], {Announcements}[https://forum.setdef.com/tags/c/ratatui-ruby/6/announcement], {Discussion}[https://forum.setdef.com/tags/c/ratatui-ruby/6/discussion], {Bug Tracker}[https://forum.setdef.com/tags/c/ratatui-ruby/6/bug] [Contribute] {Contributing Guide}[https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md], {Code of Conduct}[https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md], {Project History}[https://man.sr.ht/~kerrick/ratatui_ruby/history/index.md], {Pull Requests}[https://forum.setdef.com/tags/c/ratatui-ruby/6/patch] --- [Website] https://www.ratatui-ruby.dev [Source] https://github.com/setdef/RatatuiRuby [RubyGems] https://rubygems.org/gems/ratatui_ruby [Upstream] https://ratatui.rs [Build Status] https://builds.sr.ht/~kerrick/ratatui_ruby © 2026 Kerrick Long · Library: LGPL-3.0-or-later · Website: CC-BY-NC-ND-4.0 · Snippets: MIT-0
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.
No description provided.