Skip to content

Commit

Permalink
CLEAR ACTION: introducing new action to clear all data + code refacto…
Browse files Browse the repository at this point in the history
…ring + documentation update
  • Loading branch information
Commit-La-Grenouille committed Mar 14, 2023
1 parent 265d8b4 commit d3061de
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 29 deletions.
Binary file not shown.
Binary file added GraphicsWorkMaterial/[email protected]
Binary file not shown.
103 changes: 77 additions & 26 deletions Sources/MyStreamDeckPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#import "ESDUtilities.h"
#import <AppKit/AppKit.h>

#define STORE_ACT @"net.localhost.streamdeck.clipboard-buddy"
#define NUKE_ACT @"net.localhost.streamdeck.clipboard-buddy-nuke"

#define MIN_LONG_PRESS 0.5
#define SECURE_PRESS 1.0
Expand Down Expand Up @@ -241,6 +243,50 @@ static CGImageRef ComposeImage(NSString *inImagePath, NSString *overlayText, NSC
}


//
// Utility function to init/reset the storage dict
//
static NSMutableDictionary * ResetDictContent(NSInteger thisDevHeight, NSInteger thisDevWidth) {

// A basic dict for our row-column to string transformation
NSMutableDictionary * tmpDict = [[NSMutableDictionary alloc] initWithCapacity:1];

// The final dict with the default values inside
NSMutableDictionary * rdyDict = [[NSMutableDictionary alloc] initWithCapacity: thisDevWidth*thisDevHeight];

// We need to initialize the dict for text (max the whole size of the device)
for (NSInteger row=0; row < thisDevWidth; row++) {
for (NSInteger col=0; col < thisDevHeight; col++) {
//
// We need to fake the usual structure we get while running to use the common keyFromCoord() method
// Unfortunately, a dict requires String or string-like elements so we have to do a formatting :(
//
tmpDict[@"row"] = [NSString stringWithFormat:@"%ld", row];
tmpDict[@"column"] = [NSString stringWithFormat:@"%ld", col];

rdyDict[ keyFromCoord(tmpDict) ] = keyFromCoord(tmpDict);
// using the key as default value should make any code misbehavior visible
}
}
return rdyDict;
}


//
// Utility function to properly clear a key (background + title)
//
static BOOL ClearKey(ESDConnectionManager *conMan, id thisContext, NSString *backgroundImage) {

// Changing the background to convey we have purged the data
[conMan setImage:backgroundImage withContext:thisContext withTarget:kESDSDKTarget_HardwareAndSoftware];

// And clearing the text if it was a secure entry
[conMan setTitle:@"" withContext:thisContext withTarget:kESDSDKTarget_HardwareAndSoftware];

return true;
}


// MARK: - MyStreamDeckPlugin

@interface MyStreamDeckPlugin ()
Expand All @@ -253,6 +299,8 @@ @interface MyStreamDeckPlugin ()
// The text we want to hold (one entry per key)
@property (strong) NSMutableDictionary *tileText;
@property BOOL dictInitialized;
@property (strong) NSMutableDictionary *tileContext;
// The context of each tile to simplify global actions (like the nuke)

// The global clipboard
@property NSPasteboard *pboard;
Expand All @@ -268,6 +316,10 @@ @interface MyStreamDeckPlugin ()
// For secure entries we store objects to reuse
@property (strong) NSDateFormatter *daFo;

// The information about the device we use to deal properly with the storage dict
@property NSInteger devHeight;
@property NSInteger devWidth;

@end


Expand Down Expand Up @@ -328,7 +380,21 @@ - (void)setupIfNeeded

- (void)keyDownForAction:(NSString *)action withContext:(id)context withPayload:(NSDictionary *)payload forDevice:(NSString *)deviceID
{
_keyPressed = [[NSDate alloc]init];
// Useful only when dealing with STORE_ACT actions but does not hurt for others
_keyPressed = [[NSDate alloc] init];

if([action isEqualToString:NUKE_ACT]) {

// We check which key holds data and make sure it gets purged properly (visually)
for(NSString * key in [_tileContext allKeys]) {
ClearKey(_connectionManager, _tileContext[key], _base64PostitSleepy);
[_tileContext removeObjectForKey:key];
}
// At this point, everything should be visually clean and we must ensure the text storage is too ;)
_tileText = [NSMutableDictionary dictionaryWithDictionary:ResetDictContent(_devHeight, _devWidth)];

[_connectionManager showOKForContext:context];
}
}


Expand All @@ -348,6 +414,7 @@ - (void)keyUpForAction:(NSString *)action withContext:(id)context withPayload:(N
// Making sure we store the clipboard data into a separate entry specific to our button
NSString * dictKey = keyFromCoord(payload[@"coordinates"]);
_tileText[dictKey] = clipboardContent;
_tileContext[dictKey] = context;

// Picking also a pseudo-random color for the text we will display on the button
NSColor *thisColor = _textColorMatrix[ arc4random_uniform(sizeof(_textColorMatrix)) ];
Expand All @@ -374,12 +441,9 @@ - (void)keyUpForAction:(NSString *)action withContext:(id)context withPayload:(N
// Purging the struct by resetting to the default value
NSString * dictKey = keyFromCoord(payload[@"coordinates"]);
_tileText[dictKey] = dictKey;
[_tileContext removeObjectForKey:dictKey];

// Changing the background to convey we have purged the data
[_connectionManager setImage:_base64PostitSleepy withContext:context withTarget:kESDSDKTarget_HardwareAndSoftware];

// And clearing the text if it was a secure entry
[_connectionManager setTitle:@"" withContext:context withTarget:kESDSDKTarget_HardwareAndSoftware];
ClearKey(_connectionManager, context, _base64PostitSleepy);
}
else {
NSString * textToDisplay = _tileText[ keyFromCoord(payload[@"coordinates"]) ];
Expand Down Expand Up @@ -463,33 +527,20 @@ - (void)willDisappearForAction:(NSString *)action withContext:(id)context withPa
- (void)deviceDidConnect:(NSString *)deviceID withDeviceInfo:(NSDictionary *)deviceInfo
{
// Relaying the dimensions of the current device as integers
NSInteger devWidth = [deviceInfo[@"size"][@"rows"] integerValue];
NSInteger devHeight= [deviceInfo[@"size"][@"columns"] integerValue];
_devHeight= [deviceInfo[@"size"][@"columns"] integerValue];
_devWidth = [deviceInfo[@"size"][@"rows"] integerValue];

// Making sure we do not loose data if the computer is locked or goes to sleep ;)
if( _dictInitialized ) {
[_connectionManager logMessage:[NSString stringWithFormat:@"[DID-CONNECT] No need to re-intialize the internal text storage in order to avoid loosing existing data..."]];
}
else {
// Preparing our dictionary objects (as we need the device's buttons info)
_tileText = [[NSMutableDictionary alloc] initWithCapacity: devWidth*devHeight];
NSMutableDictionary * tmpDict = [[NSMutableDictionary alloc] initWithCapacity:1];

// We need to initialize the dict for text (max the whole size of the device)
for (NSInteger row=0; row < devWidth; row++) {
for (NSInteger col=0; col < devHeight; col++) {
//
// We need to fake the usual structure we get while running to use the common keyFromCoord() method
// Unfortunately, a dict requires String or string-like elements so we have to do a formatting :(
//
tmpDict[@"row"] = [NSString stringWithFormat:@"%ld", row];
tmpDict[@"column"] = [NSString stringWithFormat:@"%ld", col];

_tileText[ keyFromCoord(tmpDict) ] = keyFromCoord(tmpDict);
// using the key as default value should make any code misbehavior visible
}
}
// Preparing text dictionary (as we need the device's buttons info)
_tileText = [NSMutableDictionary dictionaryWithDictionary:ResetDictContent(_devHeight, _devWidth)];
_dictInitialized = TRUE;

// Preparing also the context dictionary (without any content for now)
_tileContext = [[NSMutableDictionary alloc] initWithCapacity: _devWidth*_devHeight];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
"SupportedInMultiActions": false,
"Tooltip": "",
"UUID": "net.localhost.streamdeck.clipboard-buddy"
},
{
"Icon": "postit-action",
"Name": "All clear slot",
"States": [
{
"Image": "postit-nuke",
"TitleAlignment": "middle",
"FontSize": "12",
"TitleColor": "cyan"
}
],
"SupportedInMultiActions": false,
"Tooltip": "",
"UUID": "net.localhost.streamdeck.clipboard-buddy-nuke"
}
],
"SDKVersion": 2,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 8 additions & 2 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

- [Plugin usage with a Stream Deck device](#plugin-usage-with-a-stream-deck-device)
- [Overview](#overview)
- [Step-by-step guides](#step-by-step-guides)
- [Step-by-step guide (for the Clipboard action)](#step-by-step-guide-for-the-clipboard-action)
- [Saving text](#saving-text)
- [Saving sensitive text](#saving-sensitive-text)
- [Clearing a key](#clearing-a-key)
- [Guide for the Clear All action](#guide-for-the-clear-all-action)

## Overview

The point of this plugin is to enable you to set aside some **text data** you have in your clipboard for later.
Once a key holds some text, you can paste it in most text areas by doing a quick press on the key.

## Step-by-step guides
## Step-by-step guide (for the Clipboard action)

### Saving text

Expand All @@ -33,3 +34,8 @@ Once a key holds some text, you can paste it in most text areas by doing a quick
- First, your key will contain either a regular text ![Regular text](documentation_images/regular-text.png) or secure text ![Secure text](documentation_images/secure-text.png)
- Do a long press on the key (**3 seconds or longer**)
- When you release the key it should be back to the empty image ![Empty key](documentation_images/unused.png)

## Guide for the Clear All action

This action is very simple: you activate it, it clears all the Clipboard actions on the Stream Deck (be careful !).
![Clear All](documentation_images/clear-all.png)
Binary file added documentation_images/clear-all.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified documentation_images/secure-text.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion scripts/local_test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/sh

# Let's stop at the first error
set -e

PROJ="Clipboard-Buddy"
HERE=$(dirname "$0")

Expand All @@ -15,4 +18,4 @@ xcodebuild -project "${HERE}/../Sources/${PROJ}.xcodeproj" -alltargets -configur
"${HERE}/_deploy-plugin-dev.sh"

# 4) RE-OPEN STREAM DECK TO LOAD THE LATEST VERSION OF THE PLUGIN
open "/Applications/Stream Deck.app"
open "/Applications/Elgato Stream Deck.app"

0 comments on commit d3061de

Please sign in to comment.