mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-163208: refactoring for obj-c code
Also implemented alpha-images and popovers support
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
typedef void (*callback)(void);
|
||||
@class TouchBar;
|
||||
|
||||
@interface ItemDesc : NSObject
|
||||
{
|
||||
NSString * _itemId;
|
||||
}
|
||||
@property (retain, nonatomic) NSString * uid;
|
||||
@end
|
||||
|
||||
@interface ButtonDesc : ItemDesc
|
||||
{
|
||||
callback _action;
|
||||
}
|
||||
- (id)init:(callback)act;
|
||||
@property (nonatomic) callback action;
|
||||
@end
|
||||
|
||||
@interface ButtonImgDesc : ButtonDesc
|
||||
{
|
||||
NSImage * _img;
|
||||
}
|
||||
- (id)init:(char*)praster width:(int)w height:(int)h act:(callback)act;
|
||||
@property (retain, nonatomic) NSImage * img;
|
||||
@end
|
||||
|
||||
@interface ButtonTextDesc : ButtonDesc
|
||||
{
|
||||
NSString * _text;
|
||||
}
|
||||
- (id)init:(NSString*)text act:(callback)act;
|
||||
@property (retain, nonatomic) NSString * text;
|
||||
@end
|
||||
|
||||
@interface PopoverDesc : ItemDesc
|
||||
{
|
||||
NSImage * _img;
|
||||
NSString * _text;
|
||||
TouchBar * _expandBar;
|
||||
TouchBar * _tapAndHoldBar;
|
||||
}
|
||||
- (id)init:(NSString*)text img:(char*)praster width:(int)w height:(int)h;
|
||||
@property (retain, nonatomic) NSImage * img;
|
||||
@property (retain, nonatomic) NSString * text;
|
||||
@property (retain, nonatomic) TouchBar * expandBar;
|
||||
@property (retain, nonatomic) TouchBar * tapHoldBar;
|
||||
@end
|
||||
@@ -0,0 +1,73 @@
|
||||
#import "ItemDesc.h"
|
||||
|
||||
static NSImage * createImgFrom4ByteRGBA(const unsigned char *bytes, int w, int h) {
|
||||
const int rowBytes = w*4;
|
||||
NSBitmapImageRep *rep =
|
||||
[[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: nil // allocate the pixel buffer inside
|
||||
pixelsWide: w
|
||||
pixelsHigh: h
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: 4
|
||||
hasAlpha: YES
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSDeviceRGBColorSpace
|
||||
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
|
||||
bytesPerRow: rowBytes
|
||||
bitsPerPixel: 0]; // this must agree with bitsPerSample and samplesPerPixel, If you specify 0 for this parameter, the object interprets the number of bits per pixel using the values in the bps and spp parameters
|
||||
|
||||
[rep autorelease];
|
||||
|
||||
unsigned char* pix = [rep bitmapData];
|
||||
memcpy(pix, bytes, h*rowBytes);
|
||||
|
||||
NSImage* nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(w, h)] autorelease];
|
||||
[nsimg addRepresentation:rep];
|
||||
return nsimg;
|
||||
}
|
||||
|
||||
@implementation ItemDesc
|
||||
@synthesize uid = _itemId;
|
||||
@end
|
||||
|
||||
@implementation ButtonDesc
|
||||
- (id)init:(callback)act {
|
||||
self = [super init];
|
||||
if (self)
|
||||
_action = act;
|
||||
return self;
|
||||
}
|
||||
@synthesize action = _action;
|
||||
@end
|
||||
|
||||
@implementation ButtonImgDesc
|
||||
- (id)init:(char*)raster width:(int)w height:(int)h act:(callback)act {
|
||||
self = [super init:act];
|
||||
if (self)
|
||||
self.img = createImgFrom4ByteRGBA((unsigned char *)raster, w, h);
|
||||
return self;
|
||||
}
|
||||
@synthesize img = _img;
|
||||
@end
|
||||
|
||||
@implementation ButtonTextDesc
|
||||
- (id)init:(NSString*)text act:(callback)act {
|
||||
self = [super init:act];
|
||||
if (self)
|
||||
self.text = text;
|
||||
return self;
|
||||
}
|
||||
@synthesize text = _text;
|
||||
@end
|
||||
|
||||
@implementation PopoverDesc
|
||||
- (id)init:(NSString*)text img:(char*)raster width:(int)w height:(int)h {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.img = createImgFrom4ByteRGBA((unsigned char *)raster, w, h);
|
||||
self.text = text;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@synthesize img = _img, text = _text, expandBar = _expandBar, tapHoldBar = _tapAndHoldBar;
|
||||
@end
|
||||
@@ -0,0 +1,4 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface TouchBar : NSObject<NSTouchBarDelegate>
|
||||
@end
|
||||
@@ -0,0 +1,210 @@
|
||||
#import "TouchBar.h"
|
||||
#import "ItemDesc.h"
|
||||
|
||||
//#define LOGGING_ENABLED
|
||||
|
||||
void nslog(NSString* format, ...) {
|
||||
#ifdef LOGGING_ENABLED
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
NSString* formattedMessage = [[NSString alloc] initWithFormat: format arguments: argList];
|
||||
va_end(argList);
|
||||
NSLog(@"%@", formattedMessage);
|
||||
[formattedMessage release];
|
||||
#endif // LOGGING_ENABLED
|
||||
}
|
||||
|
||||
@interface NSButtonWithDesc : NSButton
|
||||
{
|
||||
ButtonDesc * desc;
|
||||
}
|
||||
@property (retain) ButtonDesc * desc;
|
||||
@end
|
||||
|
||||
@implementation NSButtonWithDesc
|
||||
@synthesize desc;
|
||||
@end
|
||||
|
||||
@interface TouchBar() {
|
||||
int _counter; // for uid generation
|
||||
NSString * _name; // for debugging/logging
|
||||
NSMutableArray<ItemDesc *> * _items;
|
||||
NSTouchBar * _touchBar;
|
||||
}
|
||||
|
||||
- (id)init;
|
||||
- (void)dealloc;
|
||||
|
||||
- (void)registerItem:(ItemDesc *)idesc;
|
||||
- (void)selectAllItemsToShow;
|
||||
|
||||
- (void)performButtonAction:(id)sender;
|
||||
|
||||
@property (retain, nonatomic) NSString * name;
|
||||
@property (readonly) NSTouchBar * touchBar;
|
||||
@end
|
||||
|
||||
@implementation TouchBar
|
||||
|
||||
@synthesize name = _name;
|
||||
@synthesize touchBar = _touchBar;
|
||||
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_counter = 0;
|
||||
_items = [[NSMutableArray alloc] init];
|
||||
_touchBar = [[NSTouchBar alloc] init];
|
||||
[_touchBar setDelegate:self]; // NOTE: delegate-property of NSTouchBar is weak
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_items release];
|
||||
[_touchBar release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)registerItem:(ItemDesc *) idesc {
|
||||
if (idesc == nil) {
|
||||
nslog(@"ERROR: passed nil item-descriptor");
|
||||
return;
|
||||
}
|
||||
idesc.uid = [NSString stringWithFormat:@"%@.%@.%d", _name, [idesc class], _counter++];
|
||||
[_items addObject:idesc];
|
||||
nslog(@"TRACE: registered item-descriptor '%@' [%@]", [idesc class], idesc.uid);
|
||||
}
|
||||
|
||||
- (void)selectAllItemsToShow {
|
||||
const NSUInteger count = [_items count];
|
||||
NSMutableArray<NSTouchBarItemIdentifier> * all = [[NSMutableArray alloc] initWithCapacity:count];
|
||||
for (int c = 0; c < count; ++c)
|
||||
[all addObject:_items[c].uid];
|
||||
|
||||
[_touchBar setDefaultItemIdentifiers:all];
|
||||
[all release];
|
||||
}
|
||||
|
||||
- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
|
||||
const NSUInteger count = [_items count];
|
||||
ItemDesc * idesc = nil;
|
||||
for (int c = 0; c < count; ++c) {
|
||||
if ([_items[c].uid isEqualToString:identifier]) {
|
||||
idesc = _items[c];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idesc == nil) {
|
||||
nslog(@"ERROR: called makeTouchBarItem for unknown uid [%@]", identifier);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([idesc isKindOfClass:[ButtonDesc class]]) {
|
||||
SEL selAction = @selector(performButtonAction:);
|
||||
NSButtonWithDesc *theButton = nil;
|
||||
|
||||
if ([idesc isKindOfClass:[ButtonTextDesc class]]) {
|
||||
nslog(@"TRACE: create button.text [%@]", identifier);
|
||||
ButtonTextDesc * bdesc = (ButtonTextDesc *) idesc;
|
||||
theButton = [NSButtonWithDesc buttonWithTitle:bdesc.text target:self action:selAction];
|
||||
theButton.desc = bdesc;
|
||||
} else if ([idesc isKindOfClass:[ButtonImgDesc class]]) {
|
||||
nslog(@"TRACE: create button.img [%@]", identifier);
|
||||
ButtonImgDesc * bdesc = (ButtonImgDesc *) idesc;
|
||||
theButton = [NSButtonWithDesc buttonWithImage:bdesc.img target:self action:selAction];
|
||||
theButton.desc = bdesc;
|
||||
} else {
|
||||
nslog(@"ERROR: can't create unknown button subtype '%@' [%@]", idesc, identifier);
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSCustomTouchBarItem *customItemForButton = [[[NSCustomTouchBarItem alloc] initWithIdentifier:identifier] autorelease];
|
||||
customItemForButton.view = theButton; // NOTE: view is strong
|
||||
return customItemForButton;
|
||||
}
|
||||
|
||||
if ([idesc isKindOfClass:[PopoverDesc class]]) {
|
||||
nslog(@"TRACE: create popover [%@]", identifier);
|
||||
PopoverDesc * pdesc = (PopoverDesc *) idesc;
|
||||
|
||||
NSPopoverTouchBarItem * popoverTouchBarItem = [[[NSPopoverTouchBarItem alloc] initWithIdentifier:pdesc.uid] autorelease];
|
||||
popoverTouchBarItem.showsCloseButton = YES;
|
||||
|
||||
if (pdesc.img != nil)
|
||||
popoverTouchBarItem.collapsedRepresentationImage = pdesc.img;
|
||||
if (pdesc.text != nil)
|
||||
popoverTouchBarItem.collapsedRepresentationLabel = pdesc.text;
|
||||
|
||||
popoverTouchBarItem.popoverTouchBar = pdesc.expandBar.touchBar;
|
||||
popoverTouchBarItem.pressAndHoldTouchBar = pdesc.tapHoldBar.touchBar;
|
||||
return popoverTouchBarItem;
|
||||
}
|
||||
|
||||
nslog(@"ERROR: called makeTouchBarItem for uid '%@' that has unsopported type '%@'", identifier, [idesc class]);
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)performButtonAction:(id)sender {
|
||||
NSButtonWithDesc * butSender = (NSButtonWithDesc *)sender;
|
||||
nslog(@"TRACE: called performButtonAction for uid '%@'", butSender.desc.uid);
|
||||
(*butSender.desc.action)();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
id createTouchBar(char * name) {
|
||||
TouchBar * res = [[TouchBar alloc] init];
|
||||
res.name = [NSString stringWithUTF8String:name];
|
||||
return res;
|
||||
}
|
||||
|
||||
void releaseTouchBar(id tbobj) {
|
||||
[tbobj release];
|
||||
}
|
||||
|
||||
// NOTE:
|
||||
// We can obtain "item's descriptor" via java-callback (called from NSTouchBarDelegate:touchBar:makeItemForIdentifier).
|
||||
// This allows to alloc resources by request but it can produce latency in AppKit-thread theoretically (read icon from file, for example)
|
||||
|
||||
id registerButtonText(id tbobj, char* text, callback action) {
|
||||
ButtonDesc * bdesc = [[[ButtonTextDesc alloc] init:[NSString stringWithUTF8String:text] act:action] autorelease];
|
||||
[(TouchBar *)tbobj registerItem:bdesc];
|
||||
return bdesc;
|
||||
}
|
||||
|
||||
id registerButtonImg(id tbobj, char* raster4ByteRGBA, int w, int h, callback action) {
|
||||
if (w <= 0 || h <= 0) {
|
||||
nslog(@"ERROR: incorrect image sizes");
|
||||
return nil;
|
||||
}
|
||||
ButtonDesc * bdesc = [[[ButtonImgDesc alloc] init:raster4ByteRGBA width:w height:h act:action] autorelease];
|
||||
[(TouchBar *)tbobj registerItem:bdesc];
|
||||
return bdesc;
|
||||
}
|
||||
|
||||
id registerPopover(id tbobj, char* text, char* raster4ByteRGBA, int w, int h) {
|
||||
PopoverDesc * pdesc = [[[PopoverDesc alloc] init:[NSString stringWithUTF8String:text] img:raster4ByteRGBA width:w height:h] autorelease];
|
||||
[(TouchBar *)tbobj registerItem:pdesc];
|
||||
return pdesc;
|
||||
}
|
||||
|
||||
void setPopoverExpandTouchBar(id popoverobj, id expandTB) {
|
||||
PopoverDesc * pdesc = (PopoverDesc *) popoverobj;
|
||||
pdesc.expandBar = expandTB;
|
||||
nslog(@"TRACE: set expandTB to popover [%@], text='%@', tb='%@'", pdesc.uid, pdesc.text, pdesc.expandBar);
|
||||
}
|
||||
|
||||
void setPopoverTapAndHoldTouchBar(id popoverobj, id tapHoldTB) {
|
||||
PopoverDesc * pdesc = (PopoverDesc *) popoverobj;
|
||||
pdesc.tapHoldBar = tapHoldTB;
|
||||
nslog(@"TRACE: set tapHoldTB to popover [%@], text='%@', tb='%@'", pdesc.uid, pdesc.text, pdesc.tapHoldBar);
|
||||
}
|
||||
|
||||
void selectAllItemsToShow(id tb) {
|
||||
[(TouchBar *)tb selectAllItemsToShow];
|
||||
}
|
||||
|
||||
void setTouchBar(id tb) {
|
||||
[[NSApplication sharedApplication] setTouchBar:((TouchBar *)tb).touchBar];
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
typedef void (*callback)(void);
|
||||
|
||||
@interface ItemDesc : NSObject
|
||||
{
|
||||
NSString * myItemId;
|
||||
NSString * myType;
|
||||
}
|
||||
- (id)init:(NSString*)uid type:(NSString*)type;
|
||||
|
||||
@property (readonly, nonatomic) NSString * uid;
|
||||
@property (readonly, nonatomic) NSString * type;
|
||||
@end
|
||||
|
||||
@interface ButtonDesc : ItemDesc
|
||||
{
|
||||
callback myAction;
|
||||
}
|
||||
- (id)init:(NSString*)uid type:(NSString*)type act:(callback)act;
|
||||
@property (readonly, nonatomic) callback action;
|
||||
@end
|
||||
|
||||
@interface ButtonImgDesc : ButtonDesc
|
||||
{
|
||||
NSData * myImg;
|
||||
}
|
||||
- (id)init:(NSString*)uid type:(NSString*)type img:(char*)praster bytes:(int)bytesCount act:(callback)act;
|
||||
@property (readonly, nonatomic) NSData * imgData;
|
||||
@end
|
||||
|
||||
@interface ButtonTextDesc : ButtonDesc
|
||||
{
|
||||
NSString * myText;
|
||||
}
|
||||
- (id)init:(NSString*)uid type:(NSString*)type text:(NSString*)text act:(callback)act;
|
||||
@property (readonly, nonatomic) NSString * text;
|
||||
@end
|
||||
|
||||
|
||||
@implementation ItemDesc
|
||||
- (id)init:(NSString*)_uid type:(NSString*)_type {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
myItemId = _uid;
|
||||
[myItemId retain];
|
||||
myType = _type;
|
||||
[myType retain];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@synthesize uid = myItemId, type = myType;
|
||||
@end
|
||||
|
||||
@implementation ButtonDesc
|
||||
- (id)init:(NSString*)_uid type:(NSString*)_type act:(callback)_act {
|
||||
self = [super init:_uid type:_type];
|
||||
if (self)
|
||||
myAction = _act;
|
||||
return self;
|
||||
}
|
||||
@synthesize action = myAction;
|
||||
@end
|
||||
|
||||
@implementation ButtonImgDesc
|
||||
- (id)init:(NSString*)_uid type:(NSString*)_type img:(char*)_raster bytes:(int)_bytesCount act:(callback)_act {
|
||||
self = [super init:_uid type:_type act:_act];
|
||||
if (self) {
|
||||
myImg = [NSData dataWithBytes:_raster length:_bytesCount];
|
||||
[myImg retain];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@synthesize imgData = myImg;
|
||||
@end
|
||||
|
||||
@implementation ButtonTextDesc
|
||||
- (id)init:(NSString*)_uid type:(NSString*)_type text:(NSString*)_text act:(callback)_act {
|
||||
self = [super init:_uid type:_type act:_act];
|
||||
if (self) {
|
||||
myText = _text;
|
||||
[myText retain];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@synthesize text = myText;
|
||||
@end
|
||||
|
||||
// NOTE: futher improvements:
|
||||
// 1. map per TB-wrapper
|
||||
// 2. request "item's info" via java-callback called from NSTouchBarDelegate:touchBar:makeItemForIdentifier (alloc resources by request)
|
||||
static NSMutableDictionary *g_uid2desc = nil;
|
||||
|
||||
static void _registerItem(ItemDesc * idesc) {
|
||||
if (idesc == nil) {
|
||||
#ifdef LOGGING_ENABLED
|
||||
NSLog(@"ERROR: passed nil into _registerItem");
|
||||
#endif // LOGGING_ENABLED
|
||||
return;
|
||||
}
|
||||
if (g_uid2desc == nil)
|
||||
g_uid2desc = [[NSMutableDictionary alloc] init];
|
||||
g_uid2desc[idesc.uid] = idesc;
|
||||
}
|
||||
|
||||
void registerButtonText(char* uid, char* text, callback action) {
|
||||
ButtonDesc * bdesc = [[[ButtonTextDesc alloc] init:[NSString stringWithUTF8String:uid] type:@"button.text" text:[NSString stringWithUTF8String:text] act:action] autorelease];
|
||||
_registerItem(bdesc);
|
||||
}
|
||||
|
||||
void registerButtonImg(char* uid, char* bytes, int bytesCount, callback action) {
|
||||
ButtonDesc * bdesc = [[[ButtonImgDesc alloc] init:[NSString stringWithUTF8String:uid] type:@"button.img" img:bytes bytes:bytesCount act:action] autorelease];
|
||||
_registerItem(bdesc);
|
||||
}
|
||||
|
||||
@interface NSButtonWithDesc : NSButton
|
||||
{
|
||||
ButtonDesc * desc;
|
||||
}
|
||||
@property (retain) ButtonDesc * desc;
|
||||
@end
|
||||
|
||||
@implementation NSButtonWithDesc
|
||||
@synthesize desc;
|
||||
@end
|
||||
|
||||
@interface NSTDelegate : NSObject<NSTouchBarDelegate>
|
||||
- (void)performButtonAction:(id)sender;
|
||||
@end
|
||||
|
||||
//#define LOGGING_ENABLED
|
||||
|
||||
@implementation NSTDelegate
|
||||
|
||||
// This gets called while the NSTouchBar is being constructed, for each NSTouchBarItem to be created.
|
||||
- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier
|
||||
{
|
||||
if (g_uid2desc == nil) {
|
||||
#ifdef LOGGING_ENABLED
|
||||
NSLog(@"ERROR: called makeTouchBarItem for item '%@', but global items registry is empty", identifier);
|
||||
#endif // LOGGING_ENABLED
|
||||
return nil;
|
||||
}
|
||||
ItemDesc * idesc = g_uid2desc[identifier];
|
||||
if (idesc == nil) {
|
||||
#ifdef LOGGING_ENABLED
|
||||
NSLog(@"ERROR: called makeTouchBarItem for uid '%@' that wasn't registered", identifier);
|
||||
#endif // LOGGING_ENABLED
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([idesc.type isEqualToString:@"button.text"]) {
|
||||
#ifdef LOGGING_ENABLED
|
||||
NSLog(@"TRACE: called makeTouchBarItem for button.text '%@'", identifier);
|
||||
#endif // LOGGING_ENABLED
|
||||
SEL selAction = @selector(performButtonAction:);
|
||||
ButtonTextDesc * bdesc = (ButtonTextDesc *) idesc;
|
||||
NSButtonWithDesc *theButton = [NSButtonWithDesc buttonWithTitle:bdesc.text target:self action:selAction];
|
||||
theButton.desc = bdesc;
|
||||
|
||||
NSCustomTouchBarItem *customItemForButton =
|
||||
[[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
|
||||
customItemForButton.view = theButton;
|
||||
|
||||
// We want this label to always be visible no matter how many items are in the NSTouchBar instance.
|
||||
customItemForButton.visibilityPriority = NSTouchBarItemPriorityHigh;
|
||||
return customItemForButton;
|
||||
}
|
||||
|
||||
#ifdef LOGGING_ENABLED
|
||||
NSLog(@"ERROR: called makeTouchBarItem for uid '%@' that has unsopported type '%@'", identifier, idesc.type);
|
||||
#endif // LOGGING_ENABLED
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)performButtonAction:(id)sender {
|
||||
NSButtonWithDesc * butSender = (NSButtonWithDesc *)sender;
|
||||
#ifdef LOGGING_ENABLED
|
||||
NSLog(@"TRACE: called performButtonAction for uid '%@'", butSender.desc.uid);
|
||||
#endif // LOGGING_ENABLED
|
||||
(*butSender.desc.action)();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,37 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.mac.touchbar;
|
||||
|
||||
import com.intellij.ui.mac.foundation.ID;
|
||||
import com.sun.jna.Library;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
public interface NSTLibrary extends Library {
|
||||
void registerButtonText(String uid, String text, TBItemCallback action);
|
||||
void registerButtonImg(String uid, byte[] bytes, int bytesCount, TBItemCallback action);
|
||||
ID createTouchBar(String name);
|
||||
void releaseTouchBar(ID tbObj);
|
||||
|
||||
ID registerButtonText(ID tbObj, String text, TBItemCallback action);
|
||||
ID registerButtonImg(ID tbObj, byte[] raster4ByteRGBA, int w, int h, TBItemCallback action);
|
||||
ID registerPopover(ID tbObj, String text, byte[] raster4ByteRGBA, int w, int h);
|
||||
void setPopoverExpandTouchBar(ID popoverObj, ID expandTbObj);
|
||||
void setPopoverTapAndHoldTouchBar(ID popoverObj, ID tapHoldTbObj);
|
||||
|
||||
void selectAllItemsToShow(ID tbObj);
|
||||
void setTouchBar(ID tbObj);
|
||||
|
||||
static byte[] getRasterFromIcon(Icon icon) {
|
||||
final int w = icon.getIconWidth();
|
||||
final int h = icon.getIconHeight();
|
||||
final WritableRaster raster = Raster.createInterleavedRaster(new DataBufferByte(w * h * 4), w, h, 4 * w, 4, new int[]{0, 1, 2, 3}, (Point) null);
|
||||
final ColorModel colorModel = new ComponentColorModel(ColorModel.getRGBdefault().getColorSpace(), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
|
||||
final BufferedImage image = new BufferedImage(colorModel, raster, false, null);
|
||||
final Graphics2D g = image.createGraphics();
|
||||
g.setComposite(AlphaComposite.SrcOver);
|
||||
icon.paintIcon(null, g, 0, 0);
|
||||
g.dispose();
|
||||
|
||||
return ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.mac.touchbar;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.ui.mac.foundation.ID;
|
||||
|
||||
abstract class TBItem {
|
||||
protected String myItemID; // used as unique item's name inside native code
|
||||
protected ID myNativePeer;
|
||||
|
||||
String getItemId() { return myItemID; }
|
||||
void register(@NotNull String uid) {
|
||||
myItemID = uid;
|
||||
_register();
|
||||
void register(ID touchBar) {
|
||||
myNativePeer = _register(touchBar);
|
||||
}
|
||||
|
||||
protected abstract void _register();
|
||||
// NOTE: creates native peer and returns it's id
|
||||
protected abstract ID _register(ID tbOwner);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.mac.touchbar;
|
||||
|
||||
import com.intellij.ui.mac.foundation.ID;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class TBItemButtonImg extends TBItemButton {
|
||||
private final Icon myIcon;
|
||||
|
||||
public TBItemButtonImg(Icon icon, TBItemCallback action) {
|
||||
super(action);
|
||||
myIcon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ID _register(ID tbOwner) {
|
||||
return TouchBarManager.getNSTLibrary().registerButtonImg(
|
||||
tbOwner, NSTLibrary.getRasterFromIcon(myIcon),
|
||||
myIcon.getIconWidth(), myIcon.getIconHeight(), myAction
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.mac.touchbar;
|
||||
|
||||
import com.intellij.ui.mac.foundation.ID;
|
||||
|
||||
public class TBItemButtonText extends TBItemButton {
|
||||
private final String myText;
|
||||
|
||||
@@ -10,5 +12,7 @@ public class TBItemButtonText extends TBItemButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _register() { TouchBarManager.getNSTLibrary().registerButtonText(myItemID, myText, myAction); }
|
||||
public ID _register(ID tbOwner) {
|
||||
return TouchBarManager.getNSTLibrary().registerButtonText(tbOwner, myText, myAction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.mac.touchbar;
|
||||
|
||||
import com.intellij.ui.mac.foundation.ID;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class TBItemPopover extends TBItem {
|
||||
private final Icon myIcon;
|
||||
private final String myText;
|
||||
private TouchBar myExpandTB;
|
||||
private TouchBar myTapAndHoldTB;
|
||||
|
||||
public TBItemPopover(Icon icon, String text) {
|
||||
myIcon = icon;
|
||||
myText = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ID _register(ID tb) {
|
||||
return TouchBarManager.getNSTLibrary().registerPopover(
|
||||
tb, myText, NSTLibrary.getRasterFromIcon(myIcon),
|
||||
myIcon.getIconWidth(), myIcon.getIconHeight()
|
||||
);
|
||||
}
|
||||
|
||||
void setExpandTB(TouchBar expandTB) {
|
||||
myExpandTB = expandTB;
|
||||
TouchBarManager.getNSTLibrary().setPopoverExpandTouchBar(myNativePeer, myExpandTB.getNativePeer());
|
||||
TouchBarManager.getNSTLibrary().releaseTouchBar(myExpandTB.getNativePeer());// popover (native wrapper) owns tb now
|
||||
}
|
||||
|
||||
void setTapAndHoldTB(TouchBar tapHoldTB) {
|
||||
myTapAndHoldTB = tapHoldTB;
|
||||
TouchBarManager.getNSTLibrary().setPopoverTapAndHoldTouchBar(myNativePeer, myTapAndHoldTB.getNativePeer());
|
||||
TouchBarManager.getNSTLibrary().releaseTouchBar(myTapAndHoldTB.getNativePeer());// popover (native wrapper) owns tb now
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.mac.touchbar;
|
||||
|
||||
import com.intellij.ui.mac.foundation.Foundation;
|
||||
import com.intellij.ui.mac.foundation.ID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -10,42 +9,28 @@ import java.util.List;
|
||||
|
||||
public class TouchBar {
|
||||
private final String myTbName;
|
||||
private final ID myTb;
|
||||
private final ID myDelegate;
|
||||
private final ID myNativePeer;
|
||||
private final List<TBItem> myItems = new ArrayList<>();
|
||||
|
||||
TouchBar(String touchbarName) {
|
||||
myTbName = touchbarName;
|
||||
myTb = Foundation.invoke(Foundation.invoke("NSTouchBar", "alloc"), "init");
|
||||
myDelegate = Foundation.invoke(Foundation.invoke("NSTDelegate", "alloc"), "init");
|
||||
Foundation.invoke(myTb, "setDelegate:", myDelegate); // NOTE: delegate-property is weak, this java-wrapper holds both objects
|
||||
myNativePeer = TouchBarManager.getNSTLibrary().createTouchBar(touchbarName);
|
||||
}
|
||||
|
||||
ID getTbID() { return myTb; }
|
||||
ID getNativePeer() { return myNativePeer; }
|
||||
|
||||
void release() {
|
||||
Foundation.invoke(myTb, "release");
|
||||
Foundation.invoke(myDelegate, "release");
|
||||
}
|
||||
void release() { TouchBarManager.getNSTLibrary().releaseTouchBar(myNativePeer); }
|
||||
|
||||
// NOTE: must call 'flushItems' after filling
|
||||
// NOTE: must call 'selectAllItemsToShow' after filling
|
||||
void addItem(@NotNull TBItem tbi) {
|
||||
final int index = myItems.size();
|
||||
final String uid= String.format("%s.%d",myTbName, index);
|
||||
tbi.register(uid);
|
||||
tbi.register(myNativePeer);
|
||||
myItems.add(tbi);
|
||||
}
|
||||
|
||||
void flushItems() {
|
||||
void selectAllItemsToShow() {
|
||||
if (myItems.isEmpty())
|
||||
return;
|
||||
|
||||
Object[] ids = new Object[myItems.size()];
|
||||
int c = 0;
|
||||
for (TBItem tbi: myItems)
|
||||
ids[c++] = Foundation.nsString(tbi.getItemId());
|
||||
|
||||
final ID items = Foundation.invoke("NSArray", "arrayWithObjects:", ids);
|
||||
Foundation.invoke(myTb, "setDefaultItemIdentifiers:", items);
|
||||
TouchBarManager.getNSTLibrary().selectAllItemsToShow(myNativePeer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.execution.util.ExecUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
@@ -66,18 +67,35 @@ public class TouchBarManager {
|
||||
final ID pool = Foundation.invoke("NSAutoreleasePool", "new");
|
||||
try {
|
||||
if (this == main) {
|
||||
myTB = new TouchBar("main");
|
||||
myTB = new TouchBar(name());
|
||||
myTB.addItem(new TBItemButtonText("Debug", new TBItemAction("Debug")));
|
||||
myTB.addItem(new TBItemButtonText("Run", new TBItemAction("Run")));
|
||||
}
|
||||
else if (this == debug) {
|
||||
myTB = new TouchBar("debug");
|
||||
myTB = new TouchBar(name());
|
||||
myTB.addItem(new TBItemButtonText("Step", new TBItemAction("Step Over")));
|
||||
}
|
||||
else if (this == test) {
|
||||
myTB = new TouchBar("test");
|
||||
myTB = new TouchBar(name());
|
||||
myTB.addItem(new TBItemButtonText("test1", TBItemCallback.createPrintTextCallback("pressed test1 button")));
|
||||
myTB.addItem(new TBItemButtonText("test2", TBItemCallback.createPrintTextCallback("pressed test2 button")));
|
||||
myTB.addItem(new TBItemButtonImg(AllIcons.Toolwindows.ToolWindowRun, TBItemCallback.createPrintTextCallback("pressed image button")));
|
||||
|
||||
TBItemPopover popover = new TBItemPopover(AllIcons.Toolwindows.ToolWindowBuild, "test-popover");
|
||||
myTB.addItem(popover);
|
||||
|
||||
TouchBar expandTB = new TouchBar("main_popover_expand");
|
||||
expandTB.addItem(new TBItemButtonText("ptest", TBItemCallback.createPrintTextCallback("pressed ptest button")));
|
||||
expandTB.addItem(new TBItemButtonImg(AllIcons.Toolwindows.ToolWindowDebugger, TBItemCallback.createPrintTextCallback("pressed pimage button")));
|
||||
expandTB.selectAllItemsToShow();
|
||||
|
||||
popover.setExpandTB(expandTB);
|
||||
|
||||
TouchBar tapHoldTB = new TouchBar("main_popover_tap_and_hold");
|
||||
tapHoldTB.addItem(new TBItemButtonImg(AllIcons.Toolwindows.ToolWindowPalette, TBItemCallback.createPrintTextCallback("pressed pimage button")));
|
||||
tapHoldTB.selectAllItemsToShow();
|
||||
|
||||
popover.setTapAndHoldTB(tapHoldTB);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -85,7 +103,7 @@ public class TouchBarManager {
|
||||
}
|
||||
|
||||
if (myTB != null)
|
||||
myTB.flushItems();
|
||||
myTB.selectAllItemsToShow();
|
||||
}
|
||||
return myTB;
|
||||
}
|
||||
@@ -116,8 +134,7 @@ public class TouchBarManager {
|
||||
if (ourTouchbar == null)
|
||||
return;
|
||||
|
||||
final ID app = Foundation.invoke("NSApplication", "sharedApplication");
|
||||
Foundation.invoke(app, "setTouchBar:", ourTouchbar.getTbID());
|
||||
ourNSTLibrary.setTouchBar(ourTouchbar.getNativePeer());
|
||||
}
|
||||
|
||||
static NSTLibrary getNSTLibrary() { return ourNSTLibrary; }
|
||||
|
||||
Reference in New Issue
Block a user