introducting delete buttons for custom icons

This commit is contained in:
michael starke
2017-09-16 10:46:54 +02:00
parent 51a99a8bd0
commit 4493e8cb2c
10 changed files with 199 additions and 21 deletions

View File

@@ -23,12 +23,13 @@
<rect key="frame" x="0.0" y="0.0" width="380" height="270"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView focusRingType="none" id="58">
<collectionView focusRingType="none" selectable="YES" id="58">
<rect key="frame" x="0.0" y="0.0" width="380" height="270"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="primaryBackgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
<connections>
<outlet property="itemPrototype" destination="61" id="63"/>
<outlet property="menu" destination="vS0-bP-ZyJ" id="nAW-cJ-Vzp"/>
</connections>
</collectionView>
</subviews>
@@ -54,10 +55,13 @@
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8kv-BJ-IEk">
<rect key="frame" x="153" y="18" width="104" height="25"/>
<buttonCell key="cell" type="roundTextured" title="Download Icon" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="iaf-XW-XUo">
<buttonCell key="cell" type="roundTextured" title="Download Icon" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="iaf-XW-XUo">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="downloadIcon:" target="-2" id="VIQ-4U-K4z"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="His-4A-hcY">
<rect key="frame" x="89" y="18" width="56" height="25"/>
@@ -85,8 +89,9 @@
</constraints>
<point key="canvasLocation" x="-143" y="15"/>
</customView>
<collectionViewItem id="61">
<collectionViewItem id="61" customClass="MPCollectionViewItem">
<connections>
<outlet property="deleteImageButton" destination="MEC-x9-zrX" id="PSx-mD-G8C"/>
<outlet property="view" destination="113" id="128"/>
</connections>
</collectionViewItem>
@@ -94,6 +99,31 @@
<rect key="frame" x="0.0" y="0.0" width="48" height="48"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button translatesAutoresizingMaskIntoConstraints="NO" id="MEC-x9-zrX">
<rect key="frame" x="32" y="32" width="16" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="16" id="cau-QV-8TQ"/>
<constraint firstAttribute="height" constant="16" id="yHZ-qj-Rcy"/>
</constraints>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="NSRefreshFreestandingTemplate" imagePosition="overlaps" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="zWZ-Wt-ThY">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="61" name="argument" keyPath="representedObject" id="rJw-Yy-JjZ">
<dictionary key="options">
<bool key="NSConditionallySetsEnabled" value="NO"/>
<string key="NSSelectorName">_deleteIcon:</string>
</dictionary>
</binding>
<binding destination="-2" name="target" keyPath="self" previousBinding="rJw-Yy-JjZ" id="j04-R4-qhO">
<dictionary key="options">
<bool key="NSConditionallySetsEnabled" value="NO"/>
<string key="NSSelectorName">_deleteIcon:</string>
</dictionary>
</binding>
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="114">
<rect key="frame" x="8" y="8" width="32" height="32"/>
<constraints>
@@ -124,10 +154,27 @@
<constraints>
<constraint firstItem="114" firstAttribute="centerY" secondItem="113" secondAttribute="centerY" id="168"/>
<constraint firstItem="114" firstAttribute="centerX" secondItem="113" secondAttribute="centerX" id="169"/>
<constraint firstAttribute="trailing" secondItem="MEC-x9-zrX" secondAttribute="trailing" id="l85-hK-J0S"/>
<constraint firstItem="MEC-x9-zrX" firstAttribute="top" secondItem="113" secondAttribute="top" id="uEr-Jk-Jfa"/>
</constraints>
</customView>
<menu id="vS0-bP-ZyJ">
<items>
<menuItem title="Item 1" id="M2B-II-30N">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Item 2" id="Vc1-gW-L1b">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Item 3" id="cUN-GX-EWu">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
<point key="canvasLocation" x="298" y="163"/>
</menu>
</objects>
<resources>
<image name="NSAddTemplate" width="11" height="11"/>
<image name="NSRefreshFreestandingTemplate" width="14" height="14"/>
</resources>
</document>

View File

@@ -0,0 +1,15 @@
//
// MPCollectionViewItem.h
// MacPass
//
// Created by Michael Starke on 15.09.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MPCollectionViewItem : NSCollectionViewItem
@property BOOL showDeleteIndicator;
@end

View File

@@ -0,0 +1,32 @@
//
// MPCollectionViewItem.m
// MacPass
//
// Created by Michael Starke on 15.09.17.
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
//
#import "MPCollectionViewItem.h"
#import "MPIconSelectViewController.h"
@interface MPCollectionViewItem ()
@property (strong) IBOutlet NSButton *deleteImageButton;
@end
@implementation MPCollectionViewItem
@dynamic showDeleteIndicator;
- (void)viewDidLoad {
self.showDeleteIndicator = NO;
}
- (void)setShowDeleteIndicator:(BOOL)showDeleteIndicator {
self.deleteImageButton.hidden = !showDeleteIndicator;
}
- (BOOL)showDeleteIndicator {
return !self.deleteImageButton.hidden;
}
@end

View File

@@ -80,9 +80,9 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
NSMenuItem *emptyTrash = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"EMPTY_TRASH", @"")
action:[MPActionHelper actionOfType:MPActionEmptyTrash]
keyEquivalent:@""];
[emptyTrash setKeyEquivalentModifierMask:(NSShiftKeyMask | NSCommandKeyMask)];
emptyTrash.keyEquivalentModifierMask = (NSShiftKeyMask | NSCommandKeyMask);
unichar backSpace = NSBackspaceCharacter;
[emptyTrash setKeyEquivalent:[NSString stringWithCharacters:&backSpace length:1]];
emptyTrash.keyEquivalent = [NSString stringWithCharacters:&backSpace length:1];
[items addObject:emptyTrash];
}
@@ -95,12 +95,12 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
NSMenuItem *copyPassword = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_PASSWORD", @"")
action:[MPActionHelper actionOfType:MPActionCopyPassword]
keyEquivalent:@"c"];
[copyPassword setKeyEquivalentModifierMask:[copyPassword keyEquivalentModifierMask] | NSAlternateKeyMask];
copyPassword.keyEquivalentModifierMask = (copyPassword.keyEquivalentModifierMask | NSAlternateKeyMask);
NSMenu *urlMenu = [[NSMenu alloc] init];
NSMenuItem *urlItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"URL", @"")
action:0
keyEquivalent:@""];
[urlItem setSubmenu:urlMenu];
urlItem.submenu = urlMenu;
NSMenuItem *copyURL = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_URL", @"")
action:[MPActionHelper actionOfType:MPActionCopyURL]

View File

@@ -54,8 +54,7 @@
continue; // Skip all non-db Keys
}
MPIconType iconType = (MPIconType)iconNumber.integerValue;
KPKIcon *icon = [[KPKIcon alloc] init];
icon.image = [MPIconHelper icon:iconType];
KPKIcon *icon = [[KPKIcon alloc] initWithImage:[MPIconHelper icon:iconType]];
[mutableIcons addObject:icon];
}
icons = [mutableIcons copy];

View File

@@ -23,9 +23,12 @@
#import "MPViewController.h"
@class MPDocument;
@class MPCollectionViewItem;
@interface MPIconSelectViewController : MPViewController <NSCollectionViewDelegate>
@property (weak, nullable) NSPopover *popover;
- (IBAction)didSelectCollectionViewItem:(id _Nullable)sender;
@end

View File

@@ -23,6 +23,7 @@
#import "MPIconSelectViewController.h"
#import "MPIconHelper.h"
#import "MPDocument.h"
#import "MPCollectionViewItem.h"
@interface MPIconSelectViewController () <NSCollectionViewDelegate>
@@ -45,10 +46,7 @@
self.iconCollectionView.delegate = self;
[self.iconCollectionView registerForDraggedTypes:@[(NSString *)kUTTypeURL, (NSString *)kUTTypeFileURL]];
MPDocument *document = [NSDocumentController sharedDocumentController].currentDocument;
self.iconCollectionView.content = document.tree.metaData.customIcons;
self.iconCollectionView.content = [[MPIconHelper databaseIcons] arrayByAddingObjectsFromArray:document.tree.metaData.customIcons];
[self _updateCollectionViewContent];
}
- (IBAction)useDefault:(id)sender {
@@ -62,15 +60,64 @@
- (IBAction)downloadIcon:(id)sender {
KPKNode *node = self.representedObject;
[self.observer willChangeModelProperty];
[self.observer didChangeModelProperty];
[self.view.window performClose:sender];
if(!node.asEntry) {
return;
}
NSString *rawURL = node.asEntry.url;
if([rawURL hasPrefix:@"http://"] || ![rawURL hasPrefix:@"https://"]) {
rawURL = [@"https://" stringByAppendingString:rawURL];
}
NSURL *url = [NSURL URLWithString:rawURL];
if(!url) {
return;
}
NSString *urlString = [NSString stringWithFormat:@"%@://%@/favicon.ico", url.scheme, url.host ? url.host : @""];
NSURL *favIconURL = [NSURL URLWithString:urlString];
if(!favIconURL) {
return;
}
KPKMetaData *metaData = ((MPDocument *)[NSDocumentController sharedDocumentController].currentDocument).tree.metaData;
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:favIconURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(data) {
dispatch_async(dispatch_get_main_queue(), ^{
KPKIcon *newIcon = [[KPKIcon alloc] initWithImageData:data];
if(newIcon) {
[metaData addCustomIcon:newIcon];
[self _updateCollectionViewContent];
}
});
}
}];
[task resume];
}
- (void)_deleteIcon:(KPKIcon *)icon {
NSUInteger iconIndex = [self.iconCollectionView.content indexOfObject:icon];
if(iconIndex < [MPIconHelper databaseIcons].count) {
return; // defautl icons cannot be delted
}
MPDocument *document = [NSDocumentController sharedDocumentController].currentDocument;
[document.tree.metaData removeCustomIcon:icon];
[self _updateCollectionViewContent];
}
- (IBAction)cancel:(id)sender {
[self.view.window performClose:sender];
}
- (void)didSelectCollectionViewItem:(id)sender {
if(![sender isKindOfClass:[NSCollectionViewItem class]]) {
return;
}
NSCollectionViewItem *item = sender;
NSLog(@"selected item.frame: %@", NSStringFromRect(item.view.frame));
//[self _selectIcon:item.representedObject];
}
- (void)_selectIcon:(KPKIcon *)icon {
KPKNode *node = self.representedObject;
NSUInteger iconIndex = [self.iconCollectionView.content indexOfObject:icon];
@@ -105,16 +152,45 @@
for(NSURL *url in urls) {
KPKIcon *icon = [[KPKIcon alloc] initWithImageAtURL:url];
if(icon.image) {
NSLog(@"Added Icon at:%@", url);
[document.tree.metaData addCustomIcon:icon];
success = YES;
}
}
if(success) {
self.iconCollectionView.content = document.tree.metaData.customIcons;
self.iconCollectionView.content = [[MPIconHelper databaseIcons] arrayByAddingObjectsFromArray:document.tree.metaData.customIcons];
[self _updateCollectionViewContent];
}
return success;
}
- (BOOL)collectionView:(NSCollectionView *)collectionView writeItemsAtIndexes:(NSIndexSet *)indexes toPasteboard:(NSPasteboard *)pasteboard {
NSLog(@"dragStart for indexes:%@", indexes);
[pasteboard declareTypes:@[(NSString *)kUTTypeText] owner:nil];
return YES;
}
- (void)collectionView:(NSCollectionView *)collectionView draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint dragOperation:(NSDragOperation)operation {
if(nil == [self.view hitTest:screenPoint]) {
NSLog(@"Delete Item!");
}
else {
NSLog(@"Keep Item!");
}
}
- (void)_updateCollectionViewContent {
MPDocument *document = [NSDocumentController sharedDocumentController].currentDocument;
self.iconCollectionView.content = [[MPIconHelper databaseIcons] arrayByAddingObjectsFromArray:document.tree.metaData.customIcons];
}
- (void)flagsChanged:(NSEvent *)theEvent {
BOOL altDown = (0 != (theEvent.modifierFlags & NSEventModifierFlagOption));
for(NSUInteger index = 0; index < self.iconCollectionView.content.count; index++) {
MPCollectionViewItem *item = (MPCollectionViewItem *)[self.iconCollectionView itemAtIndex:index];
item.showDeleteIndicator = altDown;
}
}
@end