mirror of
https://github.com/taigrr/wails.git
synced 2026-04-17 12:15:02 -07:00
Compare commits
8 Commits
v2.0.0-alp
...
v2.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1203ae64b8 | ||
|
|
26ed8002b9 | ||
|
|
cf23bffc67 | ||
|
|
d70f6fffe7 | ||
|
|
54c99fc386 | ||
|
|
86c1ea5e6a | ||
|
|
b394c1914c | ||
|
|
91c2ddf155 |
@@ -39,6 +39,9 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
compilerCommand := "go"
|
compilerCommand := "go"
|
||||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
||||||
|
|
||||||
|
compress := false
|
||||||
|
command.BoolFlag("compress", "Compress final binary", &compress)
|
||||||
|
|
||||||
// Setup Platform flag
|
// Setup Platform flag
|
||||||
platform := runtime.GOOS
|
platform := runtime.GOOS
|
||||||
command.StringFlag("platform", "Platform to target", &platform)
|
command.StringFlag("platform", "Platform to target", &platform)
|
||||||
@@ -114,6 +117,10 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
return fmt.Errorf("platform %s is not supported", platform)
|
return fmt.Errorf("platform %s is not supported", platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if compress && platform == "darwin/universal" {
|
||||||
|
println("Warning: compress flag unsupported for universal binaries. Ignoring.")
|
||||||
|
compress = false
|
||||||
|
}
|
||||||
// Create BuildOptions
|
// Create BuildOptions
|
||||||
buildOptions := &build.Options{
|
buildOptions := &build.Options{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
@@ -127,6 +134,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
KeepAssets: keepAssets,
|
KeepAssets: keepAssets,
|
||||||
AppleIdentity: appleIdentity,
|
AppleIdentity: appleIdentity,
|
||||||
Verbosity: verbosity,
|
Verbosity: verbosity,
|
||||||
|
Compress: compress,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate platform and arch
|
// Calculate platform and arch
|
||||||
@@ -147,10 +155,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write out the system information
|
// Write out the system information
|
||||||
|
fmt.Fprintf(w, "\n")
|
||||||
fmt.Fprintf(w, "App Type: \t%s\n", buildOptions.OutputType)
|
fmt.Fprintf(w, "App Type: \t%s\n", buildOptions.OutputType)
|
||||||
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
|
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
|
||||||
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
|
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
|
||||||
fmt.Fprintf(w, "Compiler: \t%s\n", buildOptions.Compiler)
|
fmt.Fprintf(w, "Compiler: \t%s\n", buildOptions.Compiler)
|
||||||
|
fmt.Fprintf(w, "Compress: \t%t\n", buildOptions.Compress)
|
||||||
fmt.Fprintf(w, "Build Mode: \t%s\n", buildModeText)
|
fmt.Fprintf(w, "Build Mode: \t%s\n", buildModeText)
|
||||||
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||||
fmt.Fprintf(w, "Clean Build Dir: \t%t\n", buildOptions.CleanBuildDirectory)
|
fmt.Fprintf(w, "Clean Build Dir: \t%t\n", buildOptions.CleanBuildDirectory)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
var version = "v2.0.0-alpha.59"
|
var version = "v2.0.0-alpha.62"
|
||||||
|
|||||||
@@ -1049,22 +1049,26 @@ void SetDebug(void *applicationPointer, int flag) {
|
|||||||
void AddContextMenu(struct Application *app, const char *contextMenuJSON) {
|
void AddContextMenu(struct Application *app, const char *contextMenuJSON) {
|
||||||
// Guard against calling during shutdown
|
// Guard against calling during shutdown
|
||||||
if( app->shuttingDown ) return;
|
if( app->shuttingDown ) return;
|
||||||
|
ON_MAIN_THREAD (
|
||||||
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
|
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateContextMenu(struct Application *app, const char* contextMenuJSON) {
|
void UpdateContextMenu(struct Application *app, const char* contextMenuJSON) {
|
||||||
// Guard against calling during shutdown
|
// Guard against calling during shutdown
|
||||||
if( app->shuttingDown ) return;
|
if( app->shuttingDown ) return;
|
||||||
|
ON_MAIN_THREAD(
|
||||||
UpdateContextMenuInStore(app->contextMenuStore, contextMenuJSON);
|
UpdateContextMenuInStore(app->contextMenuStore, contextMenuJSON);
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTrayMenu(struct Application *app, const char *trayMenuJSON) {
|
void AddTrayMenu(struct Application *app, const char *trayMenuJSON) {
|
||||||
// Guard against calling during shutdown
|
// Guard against calling during shutdown
|
||||||
if( app->shuttingDown ) return;
|
if( app->shuttingDown ) return;
|
||||||
|
|
||||||
AddTrayMenuToStore(TrayMenuStoreSingleton, trayMenuJSON);
|
ON_MAIN_THREAD(
|
||||||
|
AddTrayMenuToStore(TrayMenuStoreSingleton, trayMenuJSON);
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTrayMenu(struct Application *app, const char* trayMenuJSON) {
|
void SetTrayMenu(struct Application *app, const char* trayMenuJSON) {
|
||||||
@@ -1372,211 +1376,6 @@ void parseMenuRole(struct Application *app, id parentMenu, JsonNode *item) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id parseTextMenuItem(struct Application *app, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers, const char *menuCallback) {
|
|
||||||
id item = ALLOC("NSMenuItem");
|
|
||||||
id wrappedId = ((id(*)(id, SEL, const char*))objc_msgSend)(c("NSValue"), s("valueWithPointer:"), menuid);
|
|
||||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
|
||||||
|
|
||||||
id key = processAcceleratorKey(acceleratorkey);
|
|
||||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title),
|
|
||||||
s(menuCallback), key);
|
|
||||||
|
|
||||||
msg_bool(item, s("setEnabled:"), !disabled);
|
|
||||||
msg_reg(item, s("autorelease"));
|
|
||||||
|
|
||||||
// Process modifiers
|
|
||||||
if( modifiers != NULL ) {
|
|
||||||
unsigned long modifierFlags = parseModifiers(modifiers);
|
|
||||||
msg_int(item, s("setKeyEquivalentModifierMask:"), modifierFlags);
|
|
||||||
}
|
|
||||||
msg_id(parentMenu, s("addItem:"), item);
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
id parseCheckboxMenuItem(struct Application *app, id parentmenu, const char
|
|
||||||
*title, const char *menuid, bool disabled, bool checked, const char *key,
|
|
||||||
struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction) {
|
|
||||||
id item = ALLOC("NSMenuItem");
|
|
||||||
|
|
||||||
// Store the item in the menu item map
|
|
||||||
hashmap_put(menuItemMap, (char*)menuid, strlen(menuid), item);
|
|
||||||
|
|
||||||
id wrappedId = msg_id(c("NSValue"), s("valueWithPointer:"), (id)menuid);
|
|
||||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
|
||||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s(checkboxCallbackFunction), str(key));
|
|
||||||
msg_bool(item, s("setEnabled:"), !disabled);
|
|
||||||
msg_reg(item, s("autorelease"));
|
|
||||||
msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff));
|
|
||||||
msg_id(parentmenu, s("addItem:"), item);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
id parseRadioMenuItem(struct Application *app, id parentmenu, const char *title,
|
|
||||||
const char *menuid, bool disabled, bool checked, const char *acceleratorkey,
|
|
||||||
struct hashmap_s *menuItemMap, const char *radioCallbackFunction) {
|
|
||||||
id item = ALLOC("NSMenuItem");
|
|
||||||
|
|
||||||
// Store the item in the menu item map
|
|
||||||
hashmap_put(menuItemMap, (char*)menuid, strlen(menuid), item);
|
|
||||||
|
|
||||||
id wrappedId = msg_id(c("NSValue"), s("valueWithPointer:"), (id)menuid);
|
|
||||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
|
||||||
|
|
||||||
id key = processAcceleratorKey(acceleratorkey);
|
|
||||||
|
|
||||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s(radioCallbackFunction), key);
|
|
||||||
|
|
||||||
msg_bool(item, s("setEnabled:"), !disabled);
|
|
||||||
msg_reg(item, s("autorelease"));
|
|
||||||
msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff));
|
|
||||||
|
|
||||||
msg_id(parentmenu, s("addItem:"), item);
|
|
||||||
return item;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseMenuItem(struct Application *app, id parentMenu, JsonNode *item,
|
|
||||||
struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char
|
|
||||||
*radioCallbackFunction, const char *menuCallbackFunction) {
|
|
||||||
|
|
||||||
// Check if this item is hidden and if so, exit early!
|
|
||||||
bool hidden = false;
|
|
||||||
getJSONBool(item, "Hidden", &hidden);
|
|
||||||
if( hidden ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the role
|
|
||||||
JsonNode *role = json_find_member(item, "Role");
|
|
||||||
if( role != NULL ) {
|
|
||||||
parseMenuRole(app, parentMenu, role);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this is a submenu
|
|
||||||
JsonNode *submenu = json_find_member(item, "SubMenu");
|
|
||||||
if( submenu != NULL ) {
|
|
||||||
// Get the label
|
|
||||||
JsonNode *menuNameNode = json_find_member(item, "Label");
|
|
||||||
const char *name = "";
|
|
||||||
if ( menuNameNode != NULL) {
|
|
||||||
name = menuNameNode->string_;
|
|
||||||
}
|
|
||||||
|
|
||||||
id thisMenuItem = createMenuItemNoAutorelease(str(name), NULL, "");
|
|
||||||
id thisMenu = createMenu(str(name));
|
|
||||||
|
|
||||||
msg_id(thisMenuItem, s("setSubmenu:"), thisMenu);
|
|
||||||
msg_id(parentMenu, s("addItem:"), thisMenuItem);
|
|
||||||
|
|
||||||
// Loop over submenu items
|
|
||||||
JsonNode *item;
|
|
||||||
json_foreach(item, submenu) {
|
|
||||||
// Get item label
|
|
||||||
parseMenuItem(app, thisMenu, item, menuItemMap, checkboxCallbackFunction, radioCallbackFunction, menuCallbackFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a user menu. Get the common data
|
|
||||||
// Get the label
|
|
||||||
const char *label = getJSONString(item, "Label");
|
|
||||||
if ( label == NULL) {
|
|
||||||
label = "(empty)";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *menuid = getJSONString(item, "ID");
|
|
||||||
if ( menuid == NULL) {
|
|
||||||
menuid = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool disabled = false;
|
|
||||||
getJSONBool(item, "Disabled", &disabled);
|
|
||||||
|
|
||||||
// Get the Accelerator
|
|
||||||
JsonNode *accelerator = json_find_member(item, "Accelerator");
|
|
||||||
const char *acceleratorkey = NULL;
|
|
||||||
const char **modifiers = NULL;
|
|
||||||
|
|
||||||
// If we have an accelerator
|
|
||||||
if( accelerator != NULL ) {
|
|
||||||
// Get the key
|
|
||||||
acceleratorkey = getJSONString(accelerator, "Key");
|
|
||||||
// Check if there are modifiers
|
|
||||||
JsonNode *modifiersList = json_find_member(accelerator, "Modifiers");
|
|
||||||
if ( modifiersList != NULL ) {
|
|
||||||
// Allocate an array of strings
|
|
||||||
int noOfModifiers = json_array_length(modifiersList);
|
|
||||||
|
|
||||||
// Do we have any?
|
|
||||||
if (noOfModifiers > 0) {
|
|
||||||
modifiers = malloc(sizeof(const char *) * (noOfModifiers + 1));
|
|
||||||
JsonNode *modifier;
|
|
||||||
int count = 0;
|
|
||||||
// Iterate the modifiers and save a reference to them in our new array
|
|
||||||
json_foreach(modifier, modifiersList) {
|
|
||||||
// Get modifier name
|
|
||||||
modifiers[count] = modifier->string_;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
// Null terminate the modifier list
|
|
||||||
modifiers[count] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get the Type
|
|
||||||
JsonNode *type = json_find_member(item, "Type");
|
|
||||||
if( type != NULL ) {
|
|
||||||
|
|
||||||
if( STREQ(type->string_, "Text")) {
|
|
||||||
parseTextMenuItem(app, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, menuCallbackFunction);
|
|
||||||
}
|
|
||||||
else if ( STREQ(type->string_, "Separator")) {
|
|
||||||
addSeparator(parentMenu);
|
|
||||||
}
|
|
||||||
else if ( STREQ(type->string_, "Checkbox")) {
|
|
||||||
// Get checked state
|
|
||||||
bool checked = false;
|
|
||||||
getJSONBool(item, "Checked", &checked);
|
|
||||||
|
|
||||||
parseCheckboxMenuItem(app, parentMenu, label, menuid, disabled, checked, "", menuItemMap, checkboxCallbackFunction);
|
|
||||||
}
|
|
||||||
else if ( STREQ(type->string_, "Radio")) {
|
|
||||||
// Get checked state
|
|
||||||
bool checked = false;
|
|
||||||
getJSONBool(item, "Checked", &checked);
|
|
||||||
|
|
||||||
parseRadioMenuItem(app, parentMenu, label, menuid, disabled, checked, "", menuItemMap, radioCallbackFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( modifiers != NULL ) {
|
|
||||||
free(modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseMenu(struct Application *app, id parentMenu, JsonNode *menu, struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char *radioCallbackFunction, const char *menuCallbackFunction) {
|
|
||||||
JsonNode *items = json_find_member(menu, "Items");
|
|
||||||
if( items == NULL ) {
|
|
||||||
// Parse error!
|
|
||||||
Fatal(app, "Unable to find Items in Menu");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate items
|
|
||||||
JsonNode *item;
|
|
||||||
json_foreach(item, items) {
|
|
||||||
// Get item label
|
|
||||||
parseMenuItem(app, parentMenu, item, menuItemMap, checkboxCallbackFunction, radioCallbackFunction, menuCallbackFunction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpMemberList(const char *name, id *memberList) {
|
void dumpMemberList(const char *name, id *memberList) {
|
||||||
void *member = memberList[0];
|
void *member = memberList[0];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -1589,43 +1388,6 @@ void dumpMemberList(const char *name, id *memberList) {
|
|||||||
printf("]\n");
|
printf("]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void processRadioGroup(JsonNode *radioGroup, struct hashmap_s *menuItemMap,
|
|
||||||
struct hashmap_s *radioGroupMap) {
|
|
||||||
|
|
||||||
int groupLength;
|
|
||||||
getJSONInt(radioGroup, "Length", &groupLength);
|
|
||||||
JsonNode *members = json_find_member(radioGroup, "Members");
|
|
||||||
JsonNode *member;
|
|
||||||
|
|
||||||
// Allocate array
|
|
||||||
size_t arrayLength = sizeof(id)*(groupLength+1);
|
|
||||||
id memberList[arrayLength];
|
|
||||||
|
|
||||||
// Build the radio group items
|
|
||||||
int count=0;
|
|
||||||
json_foreach(member, members) {
|
|
||||||
// Get menu by id
|
|
||||||
id menuItem = (id)hashmap_get(menuItemMap, (char*)member->string_, strlen(member->string_));
|
|
||||||
// Save Member
|
|
||||||
memberList[count] = menuItem;
|
|
||||||
count = count + 1;
|
|
||||||
}
|
|
||||||
// Null terminate array
|
|
||||||
memberList[groupLength] = 0;
|
|
||||||
|
|
||||||
// dumpMemberList("memberList", memberList);
|
|
||||||
|
|
||||||
// Store the members
|
|
||||||
json_foreach(member, members) {
|
|
||||||
// Copy the memberList
|
|
||||||
char *newMemberList = (char *)malloc(arrayLength);
|
|
||||||
memcpy(newMemberList, memberList, arrayLength);
|
|
||||||
// add group to each member of group
|
|
||||||
hashmap_put(radioGroupMap, member->string_, strlen(member->string_), newMemberList);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateMenu replaces the current menu with the given one
|
// updateMenu replaces the current menu with the given one
|
||||||
void updateMenu(struct Application *app, const char *menuAsJSON) {
|
void updateMenu(struct Application *app, const char *menuAsJSON) {
|
||||||
Debug(app, "Menu is now: %s", menuAsJSON);
|
Debug(app, "Menu is now: %s", menuAsJSON);
|
||||||
@@ -1649,7 +1411,9 @@ void SetApplicationMenu(struct Application *app, const char *menuAsJSON) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update menu
|
// Update menu
|
||||||
updateMenu(app, menuAsJSON);
|
ON_MAIN_THREAD (
|
||||||
|
updateMenu(app, menuAsJSON);
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void processDialogIcons(struct hashmap_s *hashmap, const unsigned char *dialogIcons[]) {
|
void processDialogIcons(struct hashmap_s *hashmap, const unsigned char *dialogIcons[]) {
|
||||||
|
|||||||
@@ -578,30 +578,26 @@ id processCheckboxMenuItem(Menu *menu, id parentmenu, const char *title, const c
|
|||||||
|
|
||||||
id createAttributedString(const char* title, const char* fontName, int fontSize, const char* RGBA) {
|
id createAttributedString(const char* title, const char* fontName, int fontSize, const char* RGBA) {
|
||||||
|
|
||||||
// Process Menu Item attributes
|
// Create new Dictionary
|
||||||
id dictionary = ALLOC_INIT("NSMutableDictionary");
|
id dictionary = ALLOC_INIT("NSMutableDictionary");
|
||||||
|
|
||||||
// Process font
|
|
||||||
CGFloat fontSizeFloat = (CGFloat)fontSize;
|
CGFloat fontSizeFloat = (CGFloat)fontSize;
|
||||||
|
|
||||||
// Check if valid
|
// Use default font
|
||||||
id fontNameAsNSString = str(fontName);
|
id font = ((id(*)(id, SEL, CGFloat))objc_msgSend)(c("NSFont"), s("menuBarFontOfSize:"), fontSizeFloat);
|
||||||
id font = ((id(*)(id, SEL, id, CGFloat))objc_msgSend)(c("NSFont"), s("fontWithName:size:"), fontNameAsNSString, fontSizeFloat);
|
|
||||||
if( font == NULL ) {
|
// Check user supplied font
|
||||||
bool supportsMonospacedDigitSystemFont = (bool) ((id(*)(id, SEL, SEL))objc_msgSend)(c("NSFont"), s("respondsToSelector:"), s("monospacedDigitSystemFontOfSize:weight:"));
|
if( STR_HAS_CHARS(fontName) ) {
|
||||||
if( supportsMonospacedDigitSystemFont ) {
|
id fontNameAsNSString = str(fontName);
|
||||||
font = ((id(*)(id, SEL, CGFloat, CGFloat))objc_msgSend)(c("NSFont"), s("monospacedDigitSystemFontOfSize:weight:"), fontSizeFloat, (CGFloat)NSFontWeightRegular);
|
id userFont = ((id(*)(id, SEL, id, CGFloat))objc_msgSend)(c("NSFont"), s("fontWithName:size:"), fontNameAsNSString, fontSizeFloat);
|
||||||
} else {
|
if( userFont != NULL ) {
|
||||||
font = ((id(*)(id, SEL, CGFloat))objc_msgSend)(c("NSFont"), s("menuFontOfSize:"), fontSizeFloat);
|
font = userFont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add font to dictionary
|
// Add font to dictionary
|
||||||
id fan = lookupStringConstant(str("NSFontAttributeName"));
|
id fan = lookupStringConstant(str("NSFontAttributeName"));
|
||||||
msg_id_id(dictionary, s("setObject:forKey:"), font, fan);
|
msg_id_id(dictionary, s("setObject:forKey:"), font, fan);
|
||||||
id offset = msg_float(c("NSNumber"), s("numberWithFloat:"), (float)0.0);
|
|
||||||
id offsetAttrName = lookupStringConstant(str("NSBaselineOffsetAttributeName"));
|
|
||||||
msg_id_id(dictionary, s("setObject:forKey:"), offset, offsetAttrName);
|
|
||||||
// RGBA
|
// RGBA
|
||||||
if( RGBA != NULL && strlen(RGBA) > 0) {
|
if( RGBA != NULL && strlen(RGBA) > 0) {
|
||||||
unsigned short r, g, b, a;
|
unsigned short r, g, b, a;
|
||||||
@@ -617,14 +613,13 @@ id createAttributedString(const char* title, const char* fontName, int fontSize,
|
|||||||
(CGFloat)a / (CGFloat)255.0);
|
(CGFloat)a / (CGFloat)255.0);
|
||||||
id NSForegroundColorAttributeName = lookupStringConstant(str("NSForegroundColorAttributeName"));
|
id NSForegroundColorAttributeName = lookupStringConstant(str("NSForegroundColorAttributeName"));
|
||||||
msg_id_id(dictionary, s("setObject:forKey:"), colour, NSForegroundColorAttributeName);
|
msg_id_id(dictionary, s("setObject:forKey:"), colour, NSForegroundColorAttributeName);
|
||||||
msg_reg(colour, s("autorelease"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id attributedString = ALLOC("NSMutableAttributedString");
|
id attributedString = ALLOC("NSMutableAttributedString");
|
||||||
msg_id_id(attributedString, s("initWithString:attributes:"), str(title), dictionary);
|
msg_id_id(attributedString, s("initWithString:attributes:"), str(title), dictionary);
|
||||||
msg_reg(attributedString, s("autorelease"));
|
msg_reg(attributedString, s("autorelease"));
|
||||||
msg_reg(dictionary, s("release"));
|
msg_reg(dictionary, s("autorelease"));
|
||||||
return attributedString;
|
return attributedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -695,38 +690,6 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is a submenu
|
|
||||||
JsonNode *submenu = json_find_member(item, "SubMenu");
|
|
||||||
if( submenu != NULL ) {
|
|
||||||
// Get the label
|
|
||||||
JsonNode *menuNameNode = json_find_member(item, "Label");
|
|
||||||
const char *name = "";
|
|
||||||
if ( menuNameNode != NULL) {
|
|
||||||
name = menuNameNode->string_;
|
|
||||||
}
|
|
||||||
|
|
||||||
id thisMenuItem = createMenuItemNoAutorelease(str(name), NULL, "");
|
|
||||||
id thisMenu = createMenu(str(name));
|
|
||||||
|
|
||||||
msg_id(thisMenuItem, s("setSubmenu:"), thisMenu);
|
|
||||||
msg_id(parentMenu, s("addItem:"), thisMenuItem);
|
|
||||||
|
|
||||||
JsonNode *submenuItems = json_find_member(submenu, "Items");
|
|
||||||
// If we have no items, just return
|
|
||||||
if ( submenuItems == NULL ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop over submenu items
|
|
||||||
JsonNode *item;
|
|
||||||
json_foreach(item, submenuItems) {
|
|
||||||
// Get item label
|
|
||||||
processMenuItem(menu, thisMenu, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a user menu. Get the common data
|
// This is a user menu. Get the common data
|
||||||
// Get the label
|
// Get the label
|
||||||
const char *label = getJSONString(item, "Label");
|
const char *label = getJSONString(item, "Label");
|
||||||
@@ -792,9 +755,36 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
|||||||
// Get the Type
|
// Get the Type
|
||||||
JsonNode *type = json_find_member(item, "Type");
|
JsonNode *type = json_find_member(item, "Type");
|
||||||
if( type != NULL ) {
|
if( type != NULL ) {
|
||||||
|
if( STREQ(type->string_, "Text") || STREQ(type->string_, "Submenu")) {
|
||||||
|
id thisMenuItem = processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image, fontName, fontSize, RGBA, templateImage, alternate);
|
||||||
|
|
||||||
if( STREQ(type->string_, "Text")) {
|
// Check if this node has a submenu
|
||||||
processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image, fontName, fontSize, RGBA, templateImage, alternate);
|
JsonNode *submenu = json_find_member(item, "SubMenu");
|
||||||
|
if( submenu != NULL ) {
|
||||||
|
// Get the label
|
||||||
|
JsonNode *menuNameNode = json_find_member(item, "Label");
|
||||||
|
const char *name = "";
|
||||||
|
if ( menuNameNode != NULL) {
|
||||||
|
name = menuNameNode->string_;
|
||||||
|
}
|
||||||
|
|
||||||
|
id thisMenu = createMenu(str(name));
|
||||||
|
|
||||||
|
msg_id(thisMenuItem, s("setSubmenu:"), thisMenu);
|
||||||
|
|
||||||
|
JsonNode *submenuItems = json_find_member(submenu, "Items");
|
||||||
|
// If we have no items, just return
|
||||||
|
if ( submenuItems == NULL ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over submenu items
|
||||||
|
JsonNode *item;
|
||||||
|
json_foreach(item, submenuItems) {
|
||||||
|
// Get item label
|
||||||
|
processMenuItem(menu, thisMenu, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( STREQ(type->string_, "Separator")) {
|
else if ( STREQ(type->string_, "Separator")) {
|
||||||
addSeparator(parentMenu);
|
addSeparator(parentMenu);
|
||||||
@@ -813,7 +803,6 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
|||||||
|
|
||||||
processRadioMenuItem(menu, parentMenu, label, menuid, disabled, checked, "");
|
processRadioMenuItem(menu, parentMenu, label, menuid, disabled, checked, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( modifiers != NULL ) {
|
if ( modifiers != NULL ) {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
"github.com/wailsapp/wails/v2/internal/assetdb"
|
"github.com/wailsapp/wails/v2/internal/assetdb"
|
||||||
"github.com/wailsapp/wails/v2/internal/fs"
|
"github.com/wailsapp/wails/v2/internal/fs"
|
||||||
@@ -291,6 +293,27 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
return fmt.Errorf("%s\n%s", err, string(stde.Bytes()))
|
return fmt.Errorf("%s\n%s", err, string(stde.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !options.Compress {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we have upx installed?
|
||||||
|
if !shell.CommandExists("upx") {
|
||||||
|
println("Warning: Cannot compress binary: upx not found")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
println(" Compressing with:", "upx", "--best", "--no-color", "--no-progress", options.CompiledBinary)
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := exec.Command(options.BuildDirectory, "upx", "--best", "--no-color", "--no-progress", options.CompiledBinary).Output()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error during compression:")
|
||||||
|
}
|
||||||
|
if verbose {
|
||||||
|
println(output)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ type Options struct {
|
|||||||
BuildDirectory string // Directory to use for building the application
|
BuildDirectory string // Directory to use for building the application
|
||||||
CleanBuildDirectory bool // Indicates if the build directory should be cleaned before building
|
CleanBuildDirectory bool // Indicates if the build directory should be cleaned before building
|
||||||
CompiledBinary string // Fully qualified path to the compiled binary
|
CompiledBinary string // Fully qualified path to the compiled binary
|
||||||
KeepAssets bool // /Keep the generated assets/files
|
KeepAssets bool // Keep the generated assets/files
|
||||||
Verbosity int // Verbosity level (0 - silent, 1 - default, 2 - verbose)
|
Verbosity int // Verbosity level (0 - silent, 1 - default, 2 - verbose)
|
||||||
|
Compress bool // Compress the final binary
|
||||||
AppleIdentity string
|
AppleIdentity string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user