mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-09 12:17:13 +00:00
Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03195b66bc | ||
|
|
2349aacc3e | ||
|
|
1be7bbe0dc | ||
|
|
ea332d5492 | ||
|
|
aedede7381 | ||
|
|
d4cd46c331 | ||
|
|
62450c3bb1 | ||
|
|
bafba81f56 | ||
|
|
651b445c75 | ||
|
|
5adc3c6a99 | ||
|
|
4914ff8205 | ||
|
|
783205c731 | ||
|
|
00ab2d1f3a | ||
|
|
98dcbdd87a | ||
|
|
4a936a6eef | ||
|
|
ef7ee1b699 | ||
|
|
4e70c1fb10 | ||
|
|
21d4fa5176 | ||
|
|
f16b2e8243 | ||
|
|
4e550a22b0 | ||
|
|
c2404d3c67 | ||
|
|
f1a5467d04 | ||
|
|
512486f2e8 | ||
|
|
f1d95fa883 | ||
|
|
31cf9b8527 | ||
|
|
e0e8e8c6cc | ||
|
|
6653690d0c | ||
|
|
e63f59d33e | ||
|
|
3702c18df5 | ||
|
|
dfe215f34c | ||
|
|
621a559585 | ||
|
|
61317eff71 | ||
|
|
b314a951da | ||
|
|
1a1c105c71 | ||
|
|
3f8ee35ddb | ||
|
|
d2ea74ea14 | ||
|
|
8e1fb771e0 | ||
|
|
bbe5c82700 | ||
|
|
95e3ff3349 | ||
|
|
00c3b2083b | ||
|
|
8549858951 | ||
|
|
4730c3f4b5 | ||
|
|
19ba66fd9d | ||
|
|
589c26192d | ||
|
|
8471aeea1b | ||
|
|
58c39c14a5 | ||
|
|
2cfe45950b | ||
|
|
688671db6a | ||
|
|
1d2e50dfa2 | ||
|
|
7a70036c8f | ||
|
|
ab88a3b236 | ||
|
|
266e14063e | ||
|
|
3af0296779 | ||
|
|
5ff05503a4 | ||
|
|
13e6782cf1 | ||
|
|
24052e6369 | ||
|
|
9b17ce5524 | ||
|
|
e4c2d62eb0 | ||
|
|
27fa37a7e1 | ||
|
|
987da2b812 | ||
|
|
d1611bae12 | ||
|
|
96a3c4b9dd | ||
|
|
8ef40dced5 | ||
|
|
4a6ddb901f | ||
|
|
a5094e0acc | ||
|
|
fffcca592d | ||
|
|
341584c032 | ||
|
|
a1e178d0d7 | ||
|
|
6d78b9b6df | ||
|
|
0669ce06f2 | ||
|
|
767d9378e3 | ||
|
|
c2d62b7a13 | ||
|
|
10e33298a9 | ||
|
|
ecc88112d5 | ||
|
|
b190063264 | ||
|
|
0c9c0c0239 | ||
|
|
ae333ecb77 | ||
|
|
72a85d11df | ||
|
|
f642330306 | ||
|
|
ae1a39322e | ||
|
|
29502d10eb | ||
|
|
37550b9fb0 | ||
|
|
efd2ed1960 | ||
|
|
3a164c8080 | ||
|
|
fb9223c6c3 | ||
|
|
6c6f69d4e5 | ||
|
|
e836226174 | ||
|
|
9f9044b164 |
@@ -5,9 +5,9 @@ name: Node build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ node ]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ node ]
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -385,6 +385,18 @@ CPAMPMDateType = 6;
|
||||
return;
|
||||
}
|
||||
|
||||
// if we enter a day that is too high for the current month
|
||||
// we need to increase the month by one
|
||||
// if we do not do this, the user input would be silently reset
|
||||
// very poor user experience
|
||||
|
||||
if (parseInt(anObjectValue, 10) > [dateValue _daysInMonth])
|
||||
{
|
||||
[_datePickerElementView._textFieldMonth setIntValue:(dateValue.getMonth() + 2)];
|
||||
[super setObjectValue:objectValue];
|
||||
return;
|
||||
}
|
||||
|
||||
[super setObjectValue:objectValue];
|
||||
break;
|
||||
|
||||
|
||||
@@ -561,10 +561,11 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
}
|
||||
else if (aName === "right-segment-bezel")
|
||||
{
|
||||
return CGRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
|
||||
bezelInset.top,
|
||||
contentInset.right,
|
||||
height);
|
||||
// we have to FLOOR the coordinates to prevent a 1px glitch in Safari
|
||||
return CGRectMake(FLOOR(CGRectGetWidth([self bounds]) - contentInset.right),
|
||||
FLOOR(bezelInset.top),
|
||||
FLOOR(contentInset.right),
|
||||
FLOOR(height));
|
||||
}
|
||||
else if (aName.indexOf("segment-bezel") === 0)
|
||||
{
|
||||
|
||||
@@ -312,6 +312,12 @@ var AFFINITY = 5;
|
||||
if (!trackRect || CGRectIsEmpty(trackRect))
|
||||
trackRect = bounds;
|
||||
|
||||
if (_allowsTickMarkValuesOnly)
|
||||
{
|
||||
[self closestTickMarkValueToValue:[self doubleValue]]; // we only need the side effect …
|
||||
_currentTickMarkSegment = _closestTickMarkIndex;
|
||||
}
|
||||
|
||||
if (_isCircular)
|
||||
{
|
||||
var angle = 3 * PI_2 - (1.0 - [self doubleValue] - _minValue) / (_maxValue - _minValue) * PI2,
|
||||
|
||||
@@ -2718,8 +2718,6 @@ var _CPCopyPlaceholder = '-';
|
||||
if (![currentFirstResponder respondsToSelector:@selector(_activateNativeInputElement:)])
|
||||
return false; // prevent the default behaviour
|
||||
|
||||
var charCode = _CPNativeInputField.innerHTML.charCodeAt(0);
|
||||
|
||||
// chrome-trigger: keypressed is omitted for deadkeys
|
||||
if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyPressedCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder && _CPNativeInputField.innerHTML.length < 3)
|
||||
{
|
||||
|
||||
@@ -585,6 +585,12 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
// Snap to the token if it's only half visible due to mouse wheel scrolling.
|
||||
_shouldScrollTo = aToken;
|
||||
}
|
||||
|
||||
// this is a hack to compensate for a recent adoption in FR management as introduced by commit #26aab29
|
||||
// this PR makes the tokenfield loose FR status prematurely, so we have to regain here in order to make deleteForward: and friends work
|
||||
setTimeout(function(){
|
||||
[[self window] makeFirstResponder:self];
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// ===========
|
||||
@@ -965,8 +971,8 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
[self _selectToken:tokenView byExtendingSelection:NO];
|
||||
}
|
||||
}
|
||||
else
|
||||
[self _removeSelectedTokens:nil];
|
||||
// we have to remove unconditionally because the backspace is not propagated anymore starting from commit #26aab29
|
||||
[self _removeSelectedTokens:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+12
-1
@@ -44,6 +44,7 @@
|
||||
@class CPClipView
|
||||
@class CPScrollView
|
||||
@class CALayer
|
||||
@class CPBinder
|
||||
|
||||
@global appkit_tag_dom_elements
|
||||
|
||||
@@ -232,7 +233,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
JSObject _ephemeralSubviews;
|
||||
|
||||
JSObject _ephemeralSubviewsForNames;
|
||||
CPSet _ephereralSubviews;
|
||||
CPSet _ephemeralSubviews;
|
||||
|
||||
// Key View Support
|
||||
CPView _nextKeyView;
|
||||
@@ -3732,6 +3733,16 @@ var CPAppearanceVibrantDark = [CPAppearance appearanceNamed:CPAppearanceNameVibr
|
||||
[owners[i] updateTrackingAreas];
|
||||
}
|
||||
|
||||
// needed by CPWindow's releasedWhenClosed property
|
||||
- (void)_releaseRecursively
|
||||
{
|
||||
[_subviews makeObjectsPerformSelector:@selector(_releaseRecursively)];
|
||||
|
||||
[self _removeObservers];
|
||||
[CPBinder unbindAllForObject:self];
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
|
||||
@@ -186,6 +186,7 @@ var CPWindowActionMessageKeys = [
|
||||
BOOL _constrainsToUsableScreen;
|
||||
unsigned _shadowStyle;
|
||||
BOOL _showsResizeIndicator;
|
||||
BOOL _releasedWhenClosed @accessors(property=releasedWhenClosed);
|
||||
|
||||
int _positioningMask;
|
||||
CGRect _positioningScreenRect;
|
||||
@@ -2536,6 +2537,9 @@ CPTexturedBackgroundWindowMask
|
||||
[_parentWindow removeChildWindow:self];
|
||||
[self _orderOutRecursively:NO];
|
||||
[self _detachFromChildrenClosing:!_parentWindow];
|
||||
|
||||
if (_releasedWhenClosed)
|
||||
[_contentView _releaseRecursively];
|
||||
}
|
||||
|
||||
- (void)_detachFromChildrenClosing:(BOOL)shouldCloseChildren
|
||||
|
||||
@@ -570,6 +570,16 @@ var CPStringNull = [CPNull null];
|
||||
return aString && aString != "" && self.indexOf(aString) == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c YES if the receiver contains
|
||||
the specified string. If \c aString
|
||||
is empty, the method will return \c NO.
|
||||
*/
|
||||
- (BOOL)containsString:(CPString)aString
|
||||
{
|
||||
return aString && aString != "" && self.indexOf(aString) >= 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c YES if the receiver ends
|
||||
with the specified string. If \c aString
|
||||
|
||||
+120
-59
@@ -2,48 +2,45 @@
|
||||
[](
|
||||
https://gitter.im/cappuccino/cappuccino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Welcome to Cappuccino!
|
||||
======================
|
||||
# Welcome to Cappuccino!
|
||||
|
||||
Introduction
|
||||
------------
|
||||
Cappuccino is an open source framework that makes it easy to build
|
||||
desktop-caliber applications that run in a web browser.
|
||||
Cappuccino, a open-source web application framework in Objective-J (*a superset of JavaScript which is transpiled for deployment but can also run in the browser directly*), enhances app development by faithfully implementing the NeXTSTEP/Apple Cocoa® APIs for browsers as web browser restrictions permit. Leveraging this well-established architecture, Cappuccino facilitates scalable application development for those usage cases requiring developer productivity, reliability and sophisticated interaction support. Resulting applications are served from any web server and deployed to any modern web browser - without plugins or extensions of any kind. Cappuccino has been developed continuously since 2008 and is licensed under the LGPL version 2.
|
||||
|
||||
With Cappuccino, you don't concern yourself with HTML, CSS, or the DOM. You write applications with the APIs from
|
||||
Apple's Cocoa frameworks and the Objective-J language.
|
||||
### Benefits of Cappuccino for Application Development:
|
||||
|
||||
* Developer productivity – a rich palette of interface controls and robust event managment APIs go well beyond the functionality provided by current browser standards, allowing rich applications to quickly be built up using high-level constructs that are designed to work well together.
|
||||
* Consistency – predictable behavior across different platforms with desktop-class usability and user experience.
|
||||
* Stability – use of time-tested APIs means an absense of the churn which is all too common in the browser-app ecosystem found elsewhere.
|
||||
* Cross-platform development – any programmer's text editor or IDE is sufficient. The compiler and other parts of the toolchain (used to prepare applications for deployment) are hosted by Node.js.
|
||||
* Extensibility – custom interface controls can reliably build on framework-included controls, when extended or new functionality is required.
|
||||
* Objective-J's [message-passing architecture](https://en.wikipedia.org/wiki/Message_passing), which the Cappuccino APIs leverage, promotes loose coupling of an app's component functionality — making large scale development more managable.
|
||||
* Comprehensive documentation for Objective-J is supplemented by over two decades of resources for Objective-C and Cocoa®. Additionally, a large public catalog of native Objective-C applications offers valuable guidance for development. Translation of such sample code to Objective-J is often trivial (see below).
|
||||
|
||||
Check out a [live demo of the widgets in Cappuccino](https://cappuccino-testbook.5apps.com/#ThemeKitchenSink)
|
||||
Check out a [live demo of the standard interface controls provided by Cappuccino](https://cappuccino-testbook.5apps.com/#ThemeKitchenSink)
|
||||
|
||||
Check out some [tutorials](https://cappuccino-cookbook.5apps.com)
|
||||
|
||||
For more information, see the
|
||||
- [Official website](http://cappuccino-project.org)
|
||||
- [Github Wiki](https://github.com/cappuccino/cappuccino/wiki)
|
||||
- [FAQ](http://cappuccino-project.org/support/faq.html)
|
||||
- [Documentation](http://cappuccino-project.org/learn/)
|
||||
- [Mailing list](http://groups.google.com/group/objectivej)
|
||||
- [Official website](http://cappuccino.dev)
|
||||
- [Gitter](https://gitter.im/cappuccino/cappuccino)
|
||||
- [Github Wiki](https://github.com/cappuccino/cappuccino/wiki)
|
||||
- [FAQ](http://cappuccino.dev/support/faq.html)
|
||||
- [Documentation](http://cappuccino.dev/learn/)
|
||||
- [Mailing list (inactive – for historical purposes only)](http://groups.google.com/group/objectivej)
|
||||
|
||||
Follow [@cappuccino](https://twitter.com/cappuccino) on Twitter for updates on the project.
|
||||
Bugs and enhancement requrests can be reported by [creating a Github issue](http://github.com/cappuccino/cappuccino/issues).
|
||||
|
||||
If you discover any bugs, please [file a ticket](http://github.com/cappuccino/cappuccino/issues).
|
||||
## System Requirements
|
||||
|
||||
System Requirements
|
||||
-------------------
|
||||
To run Cappuccino applications, all you need is a HTML5 compliant web browser.
|
||||
* Any modern web browser can run Cappuccino applications.
|
||||
* Any web server can serve Cappuccino applications.
|
||||
* Any programmer's editor can be used for coding.
|
||||
* macOS users can use Xcode - which leverages the visual development tools from Apple for creation of complex applications with minimal coding.
|
||||
|
||||
You can develop Cappuccino applications with only a simple text editor on any platform.
|
||||
## Installation instructions
|
||||
To try Cappuccino:
|
||||
|
||||
If you are on a Mac, our integration with Xcode leverages the world-class visual development tools from Apple to create complex applications with minimal coding.
|
||||
|
||||
Node.js version alpha
|
||||
------------------
|
||||
|
||||
There is currently an ongoing effort to switch JavaScript platform from [Narwhal](https://narwhaljs.org/) to Node.js.
|
||||
To try the Node.js version, do the following:
|
||||
|
||||
1. Install Node.js and npm from the [Node.js website](https://nodejs.org/en/).
|
||||
1. Install Node.js and npm from the [Node.js website](https://nodejs.org/download/) or the OS-specific package manager of your choice. Long-term Support (LTS) versions are tested although others will probably work as intended.
|
||||
|
||||
2. Run `npm set prefix ~/.npm`. This will set the default install location for npm to `~/.npm`. The reasoning behind
|
||||
this is outlined in the section about permission issues below.
|
||||
@@ -57,29 +54,40 @@ this is outlined in the section about permission issues below.
|
||||
|
||||
5. Run `npm install -g @objj/cappuccino`.
|
||||
|
||||
6. Done! See below for basic usage.
|
||||
6. Done! See below for basic usage.
|
||||
|
||||
### Basic usage
|
||||
|
||||
On successful installation, follow these steps to create a basic and fully-functional Cappuccino application:
|
||||
|
||||
1. `capp gen HelloWorld`
|
||||
2. `cd HelloWorld`
|
||||
3. `python3 -m http.server` (any local http server can be used)
|
||||
4. Open [http://localhost:8000](http://localhost:8000) (any modern browser can be used)
|
||||
|
||||
### Technical notes
|
||||
|
||||
Cappuccino compiles source code files written in Objective-J to pure Javascript but can also run Objective-J directly in the browser. Pure Javascript code can be intermixed with Objective-J, just as Objective-C allows pure C code. This is because each language is a strict superset of its base language.
|
||||
|
||||
For app compilation and running other toolchain components in preparation for deployment to production, a desktop Javascript engine supporting CommonJS for accessing local resources is required.
|
||||
Historically, this engine was [Narwhal](https://narwhaljs.org/).
|
||||
A transition to [Node.js](https://nodejs.org) is being finalized.
|
||||
|
||||
The results of this transition are available as a **Release Candidate**.
|
||||
While an official production release is scheduled for early-autumn 2024, it should be considered production-ready as-is. Multiple production deployments over the last twelve months have confirmed this.
|
||||
In addition to the Node.js-based toolchain, the next formal release will include both maintenance improvements and enhancements to the API.
|
||||
|
||||
### Permisson issues
|
||||
|
||||
By default npm uses `/usr/local/lib/node_modules` as the install location for globally installed packages. This causes
|
||||
problems since users typically lack write permissions there. It is therefore recommended to either use a version
|
||||
manager, or change npm's default install location manually (which is what we did above). For more details on how to do
|
||||
this, see [this article](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).
|
||||
|
||||
### Basic usage
|
||||
|
||||
If the install succeeded you will be able to do the following to create a simple Cappuccino application:
|
||||
|
||||
1. `capp gen HelloWorld`
|
||||
2. `cd HelloWorld`
|
||||
3. `python3 -m http.server`
|
||||
4. Go to `localhost:8000` in your web browser.
|
||||
manager, or change npm's default install location manually (which is what we did above with the `npm set prefix…` command). For more details see [this article](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).
|
||||
|
||||
### Building Cappuccino from source
|
||||
|
||||
If you want to build Cappuccino from source you should clone the GitHub repository at
|
||||
https://github.com/cappuccino/cappuccino/ and checkout the `node` branch. Then you can use the command
|
||||
`jake install` to install Cappuccino and its tools locally.
|
||||
To build Cappuccino from source (for the latest version, including un-released changes) clone the GitHub repository at
|
||||
https://github.com/cappuccino/cappuccino/ and checkout the `main` branch. Use the command
|
||||
`jake install` to install the Cappuccino frameworks and toolchain locally.
|
||||
|
||||
To build from source, do:
|
||||
|
||||
@@ -87,33 +95,86 @@ To build from source, do:
|
||||
|
||||
2. `cd cappuccino`
|
||||
|
||||
3. `git checkout node`
|
||||
|
||||
4. `npm install`
|
||||
|
||||
5. Make any desired changes to the codebase.
|
||||
3. `npm install`. Cappuccino source currently uses the release distribution from npm to bootstrap the toolchain.
|
||||
|
||||
6. Make sure the environment variable `CAPP_BUILD` is set. This is done by adding the line
|
||||
4. Make sure the environment variable `CAPP_BUILD` is set. This is done by adding the line
|
||||
```bash
|
||||
export CAPP_BUILD="/path/to/cappuccino/build/directory"
|
||||
```
|
||||
to your `.zshrc` or equivalent config file and of course changing the path to where you want to build Cappuccino.
|
||||
7. Run `jake install` to build and install Cappuccino.
|
||||
|
||||
5. Run `jake build` to build Cappuccino.
|
||||
|
||||
6. Run `jake dist` to install the toolchain, as just compiled from source. This step may require elevated permissions.
|
||||
|
||||
Beware that building and installing Cappuccino from source will overwrite the binaries installed from npm. To undo this,
|
||||
simply run `npm install -g @objj/cappuccino` again.
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
To write you first application, [download the starter package](http://cappuccino.dev/#download).
|
||||
## FAQs
|
||||
|
||||
To try our new Node (alpha) version of the Cappuccino framework, [check the Node installation instructions](https://github.com/cappuccino/cappuccino/wiki/node)
|
||||
**Q: What is meant by desktop-class apps?**
|
||||
**A:** Desktop-class apps refer to web applications that offer the same level of functionality, complexity, and user experience as traditional desktop applications. These apps leverage keyboard navigation, advanced user interface components, rich graphics, and responsive interactions. Cappuccino is ideally suited for developing line-of-business applications, which are essential tools used within a company for its operations. Such applications often require robust data handling, complex workflows, and a high degree of reliability. Cappuccino’s comprehensive framework, modeled after the Cocoa® APIs, ensures that web applications can match the capabilities and performance of native desktop software.
|
||||
|
||||
To contribute to Cappuccino, please read here: [Getting and Building the Source](
|
||||
https://github.com/cappuccino/cappuccino/wiki/Getting-and-building-the-source).
|
||||
**Q: I don't see any support for touch-screen devices like tablets and phones. Is this supported?**
|
||||
**A:** Cappuccino applications can be adapted to support touch-screen devices, including tablets and phones. The framework primarily targets large, information-dense displays typical of desktop environments. Achieving a seamless experience across desktops, tablets, and phones requires additional effort, such as incorporating touch event handling and responsive design. However, with the right adjustments, Cappuccino applications can deliver a consistent user experience on a variety of devices.
|
||||
|
||||
For those looking to extend Cappuccino for touch applications, one option worth exploring is the open source Objective-C framework ["Chameleon"](https://github.com/BigZaphod/Chameleon). This predates Apple's Catalyst efforts and ports many UIKit classes to AppKit, allowing for a seamless integration of touch features. See below for porting Objective-C code to Objective-J, something which is mostly a search-and-replace operation.
|
||||
|
||||
**Q: How easy is it to port Objective-C code to Objective-J?**
|
||||
**A:** Porting Objective-C code to Objective-J is mostly a search-and-replace operation, primarily focusing on adapting pointer syntax and class names to fit the Objective-J framework.
|
||||
|
||||
Here is a summary of the process:
|
||||
|
||||
1. **Replace class prefixes**: Objective-C classes using the 'NS' prefix need to be replaced with 'CP'. Objective-C(J) does not support formal namespaces - class prefixes are used to overcome this ('NS' for Apple/NeXTSTEP, 'CP' for Cappuccino). Third-party code may use something else - or none at all. For example:
|
||||
|
||||
`NSString` becomes `CPString`, `NSArray` becomes `CPArray`, and `NSDictionary` becomes `CPDictionary`
|
||||
|
||||
2. **Remove pointer references:** Objective-C uses pointers, indicated by the * symbol, which are not used in Objective-J. See example below.
|
||||
|
||||
3. **Adapt memory management:** Objective-C's manual memory management and automatic reference counting (ARC) do not apply to Objective-J. Thus, methods like retain, release, and autorelease are removed. Objective-J relies on JavaScript's garbage collection - interaction with it is not supported by any browser.
|
||||
|
||||
4. **Modify code with no direct equivalent in Objective-J:** The most common is the C language `enum` construct. Javascript and Objective-J provide no direct equivalent - replace with Javascript objects or functions.
|
||||
|
||||
**A simple example:**
|
||||
|
||||
*Objective-C:*
|
||||
```objc
|
||||
NSString *greeting = [NSString stringWithFormat:@"Hello, %@!", name];
|
||||
```
|
||||
|
||||
*Objective-J:*
|
||||
```objj
|
||||
let greeting = [CPString stringWithFormat:@"Hello, %@!", name];
|
||||
```
|
||||
|
||||
**Q: Can I use Cappuccino on Windows/Linux?**
|
||||
**A:** Yes - while Cappuccino technology is inspired by Apple's framework, it is inherently platform-independent. As long as you have a modern web browser and a compatible development environment (An LTS version of Node.js, a text editor, and an http server), Cappuccino applications can be developed on and deployed from other operating systems without any issues.
|
||||
|
||||
**Q: Hasn't Apple moved away from Objective-C and AppKit, making them obsolete?**
|
||||
**A:** While Apple has indeed introduced Swift as a modern programming language and shifted its focus to frameworks like SwiftUI, Objective-C and AppKit are still widely used and supported. Apple's most sophisticated user applications are written either entirely or substantially in Objective-C and will continue to be for the foreseeable future.
|
||||
|
||||
**Q: What is with the funny syntax of Objective-J and its brackets? I've never seen a language like this – how can anyone be productive with something so strange?**
|
||||
**A:** Objective-J’s syntax, with its brackets, is inspired by Objective-C, which is a small superset of C. The brackets may seem unusual initially, but provide a powerful way to structure code and manage objects while keeping full compatibility with C. Similarly, Objective-J is a small superset of JavaScript. Developers familiar with Objective-C will find it intuitive, and those new to it can leverage extensive documentation and community resources. The initial learning curve is offset by the productivity gains in building complex, maintainable web applications with the option to mix and match from the vast repository of JavaScript code directly even within Objective-J classes.
|
||||
|
||||
**Q: I have my own HTML, JavaScript, and CSS which I would like to use in a larger app. I don't see any JavaScript, HTML, or CSS in the available sample code. How do I do this?**
|
||||
**A:** Cappuccino abstracts much of the DOM to align with Cocoa®'s model. Existing framework controls can be extended or new ones built from scratch to meet specific requirements. The Cappuccino APIs follow a classic object-oriented programming model – most necessary functionality will be inherited from the Cappuccino base class one is starting with. The [CPWebView](https://www.cappuccino.dev/learn/documentation/interface_c_p_web_view.html) control can also be used to embed either HTML/Javascript/CSS fragments or entire web pages. Javascript can be intermixed with Objective-J code.
|
||||
|
||||
**Q: What are the advantages of Cappuccino over libraries and frameworks like React and Vue?**
|
||||
**A:** Cappuccino offers several advantages:
|
||||
|
||||
* Cocoa®/NeXTSTEP Architecture: Leverages the mature and robust APIs developed originally by NeXTSETP in the 1980s and extended by Apple, providing a time-tested and solid foundation for complex applications.
|
||||
* Message-Passing Object-Oriented Approach: Uses Objective-J, which extends JavaScript with powerful object-oriented capabilities. This is used to provide a loosely-coupled component architecture, allowing better opportunities for keeping functionality tightly grouped - enhancing testability, reliability and large-scale development.
|
||||
* Desktop-Class Usability: Complex controls, coherent keyboard navigation and undo/redo out of the box.
|
||||
* Unified Framework: Integrated UI components, event handling, and data management in one cohesive package, well beyond what React and Vue provide.
|
||||
* Legacy and Stability: Continuously in development since 2008.
|
||||
|
||||
**Q: Does the license permit non-opensource development?**
|
||||
**A:** Yes, Cappuccino is released under the Lesser General Public License (LGPL) version 2. This allows developers to use, modify, and distribute Cappuccino for both open-source and closed-source applications. Commercial and proprietary software can be developed with Cappuccino without the obligation to release source code, provided the terms of the LGPL are adhered to. This means any modifications to the Cappuccino framework itself must be made available under the same LGPL license, but your own application code remains proprietary.
|
||||
|
||||
Cocoa® is a registered trademark of Apple Inc., covering a series of computer APIs for software user interfaces.
|
||||
|
||||
## License
|
||||
|
||||
License
|
||||
-------
|
||||
This library is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
|
||||
@@ -24,9 +24,9 @@ task ("build", function()
|
||||
minorVersion = parseInt(versions[1], 10),
|
||||
buildVersion = parseInt(versions[2], 10);
|
||||
|
||||
if (!((majorVersion == 11) || (majorVersion == 10 && minorVersion >= 12)))
|
||||
if (!((majorVersion >= 11) || (majorVersion == 10 && minorVersion >= 13)))
|
||||
{
|
||||
colorPrint("XcodeCapp requires at least macOS Sierra.", "red");
|
||||
colorPrint("XcodeCapp requires at least macOS High Sierra.", "red");
|
||||
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
|
||||
@@ -444,7 +444,6 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEPLOYMENT_LOCATION = YES;
|
||||
DSTROOT = /;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
@@ -463,7 +462,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INSTALL_PATH = $USER_APPS_DIR;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
@@ -494,7 +493,6 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEPLOYMENT_LOCATION = YES;
|
||||
DSTROOT = /;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
@@ -506,7 +504,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INSTALL_PATH = $USER_APPS_DIR;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
@@ -518,11 +516,12 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DSTROOT = /;
|
||||
INFOPLIST_FILE = XcodeCapp/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = XcodeCapp;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
|
||||
INSTALL_PATH = "$(LOCAL_APPS_DIR)";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cappuccino.xcodecapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
@@ -534,11 +533,12 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DSTROOT = /;
|
||||
INFOPLIST_FILE = XcodeCapp/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = XcodeCapp;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
|
||||
INSTALL_PATH = "$(LOCAL_APPS_DIR)";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cappuccino.xcodecapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
@property IBOutlet XCCMainController *mainWindowController;
|
||||
@property NSOperationQueue *mainOperationQueue;
|
||||
@property NSString *version;
|
||||
@property NSString *copyright;
|
||||
|
||||
- (IBAction)openAbout:(id)aSender;
|
||||
- (IBAction)openPreferences:(id)aSender;
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
|
||||
- (void)_initStatusItem
|
||||
{
|
||||
self->imageStatusInactive = [NSImage imageNamed:@"status-icon-inactive"];
|
||||
self->imageStatusProcessing = [NSImage imageNamed:@"status-icon-working"];
|
||||
self->imageStatusError = [NSImage imageNamed:@"status-icon-error"];
|
||||
|
||||
self->imageStatusInactive = [NSImage imageNamed:@"status-icon-inactive"];
|
||||
self->imageStatusProcessing = [NSImage imageNamed:@"status-icon-working"];
|
||||
self->imageStatusError = [NSImage imageNamed:@"status-icon-error"];
|
||||
|
||||
self->statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
|
||||
self->statusItem.menu = self->statusMenu;
|
||||
self->statusItem.image = self->imageStatusInactive;
|
||||
@@ -98,6 +98,8 @@
|
||||
NSLog(@"\n******************************\n** XcodeCapp started **\n******************************\n");
|
||||
|
||||
self.version = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];
|
||||
NSString *copyrightString = [NSBundle mainBundle].infoDictionary[@"NSHumanReadableCopyright"];
|
||||
self.copyright = [NSString stringWithFormat:@"%@\nAll rights reserved", copyrightString];
|
||||
|
||||
[self _initUserDefaults];
|
||||
[self _initOperationQueue];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.13.2"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -350,6 +350,7 @@
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
<point key="canvasLocation" x="-225" y="-276"/>
|
||||
</menu>
|
||||
<window title="XcodeCapp" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="main-window" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
@@ -375,12 +376,12 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" drawsBackground="NO" id="Zlj-Y5-TaS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="263" height="634"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="72" rowSizeStyle="automatic" viewBased="YES" id="Mss-Tu-7kR">
|
||||
<tableView appearanceType="vibrantLight" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="72" rowSizeStyle="automatic" viewBased="YES" id="Mss-Tu-7kR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="263" height="634"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn identifier="MainCell" editable="NO" width="263" minWidth="40" maxWidth="1000" id="UKo-y4-Q5Q">
|
||||
@@ -409,7 +410,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box autoresizesSubviews="NO" boxType="custom" borderType="line" borderWidth="0.0" cornerRadius="5" title="Box" titlePosition="noTitle" id="kpw-qm-NQG">
|
||||
<box autoresizesSubviews="NO" boxType="custom" borderType="line" borderWidth="0.0" cornerRadius="100" title="Box" titlePosition="noTitle" id="kpw-qm-NQG">
|
||||
<rect key="frame" x="5" y="52" width="10" height="10"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<view key="contentView" id="S9K-TP-K5A">
|
||||
@@ -521,11 +522,11 @@
|
||||
</subviews>
|
||||
<nil key="backgroundColor"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="GIE-ju-XbD">
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="GIE-ju-XbD">
|
||||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="pb5-AF-zGg">
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="pb5-AF-zGg">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
@@ -566,8 +567,8 @@
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="borderColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="borderColor" red="1" green="1" blue="1" alpha="0.41999999999999998" colorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
</subviews>
|
||||
</customView>
|
||||
@@ -595,8 +596,8 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" title="Project Name" id="ylH-C3-MHM">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="923-ke-ovW" name="value" keyPath="self.currentCappuccinoProjectController.cappuccinoProject.nickname" id="Teo-iY-bEl"/>
|
||||
@@ -607,8 +608,8 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Project Path" id="NvI-dv-Vcf">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" red="0.76319916294850176" green="0.76061204714189667" blue="0.76578627875510685" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="923-ke-ovW" name="value" keyPath="self.currentCappuccinoProjectController.cappuccinoProject.projectPath" id="IT9-Ja-icI"/>
|
||||
@@ -616,8 +617,8 @@
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="borderColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="borderColor" red="0.96862745098039216" green="0.50588235294117645" blue="0.16470588235294117" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" red="0.34509803921568627" green="0.34509803921568627" blue="0.34509803921568627" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
<box autoresizesSubviews="NO" boxType="custom" borderType="line" borderWidth="0.0" title="Box" id="ic3-Xg-i5j">
|
||||
<rect key="frame" x="0.0" y="562" width="599" height="26"/>
|
||||
@@ -680,8 +681,8 @@
|
||||
</box>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="borderColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="fillColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="borderColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.93725490196078431" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
<tabView drawsBackground="NO" type="noTabsNoBorder" id="00d-fn-q41">
|
||||
<rect key="frame" x="0.0" y="0.0" width="599" height="562"/>
|
||||
@@ -713,39 +714,30 @@
|
||||
</window>
|
||||
<window title="About" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="EMp-Db-uhU" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="296" height="191"/>
|
||||
<rect key="contentRect" x="196" y="240" width="324" height="200"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="dj4-iP-S2b">
|
||||
<rect key="frame" x="0.0" y="0.0" width="296" height="191"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="324" height="200"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="3j4-r5-Ybe">
|
||||
<rect key="frame" x="74" y="64" width="149" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<rect key="frame" x="88" y="73" width="149" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="XcodeCapp" id="qvL-bN-A9R">
|
||||
<font key="font" metaFont="systemBold" size="15"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" id="IH1-cn-Xc9">
|
||||
<rect key="frame" x="18" y="20" width="260" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Copyright © 2012-2018 Cappuccino Project." id="8lT-Ky-ecV">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView id="Q2t-aL-TDg">
|
||||
<rect key="frame" x="107" y="89" width="82" height="82"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<rect key="frame" x="121" y="98" width="82" height="82"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="logo" id="zF2-py-kAi"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" id="vIx-Hh-v8Z">
|
||||
<rect key="frame" x="108" y="42" width="81" height="14"/>
|
||||
<rect key="frame" x="18" y="51" width="288" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Version 4.0.1" id="WUW-Ut-m7V">
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Value from Info.plist displayed using bindings" id="WUW-Ut-m7V">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -754,9 +746,21 @@
|
||||
<binding destination="Voe-Tx-rLC" name="value" keyPath="self.version" id="Nfs-HY-nea"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" textCompletion="NO" id="IH1-cn-Xc9">
|
||||
<rect key="frame" x="18" y="0.0" width="292" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="center" title="Set in Info.plist, displayed using bindings" id="8lT-Ky-ecV">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="Voe-Tx-rLC" name="value" keyPath="self.copyright" id="cHX-2a-APu"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-218" y="94.5"/>
|
||||
<point key="canvasLocation" x="-304" y="-20"/>
|
||||
</window>
|
||||
<userDefaultsController representsSharedInstance="YES" id="GHK-nR-IEq" userLabel="User Defaults Controller"/>
|
||||
<window title="XcodeCapp Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="xcc-prefs" animationBehavior="default" id="ekp-cc-W2F">
|
||||
@@ -826,7 +830,7 @@
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-156.5" y="-126"/>
|
||||
<point key="canvasLocation" x="136" y="-20"/>
|
||||
</window>
|
||||
<box boxType="custom" borderType="line" borderWidth="0.0" title="Box" titlePosition="noTitle" id="fYW-ua-i1m">
|
||||
<rect key="frame" x="0.0" y="0.0" width="271" height="313"/>
|
||||
@@ -849,8 +853,8 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="XcodeCapp" id="Oar-AW-2i5">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" id="fUL-eL-YkQ">
|
||||
@@ -858,7 +862,7 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Version 4.0" id="unR-NY-aap">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" white="0.31343064259999998" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
@@ -869,9 +873,9 @@
|
||||
</customView>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="borderColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<point key="canvasLocation" x="630" y="-361"/>
|
||||
<color key="borderColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" red="0.98039221759999995" green="0.98039221759999995" blue="0.98039221759999995" alpha="1" colorSpace="deviceRGB"/>
|
||||
<point key="canvasLocation" x="310.5" y="-302.5"/>
|
||||
</box>
|
||||
<box boxType="custom" borderType="line" borderWidth="0.0" title="Box" titlePosition="noTitle" id="stz-Vu-tYo" customClass="XCCWelcomeView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="464" height="401"/>
|
||||
@@ -888,15 +892,15 @@
|
||||
<rect key="frame" x="40" y="116" width="354" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<box autoresizesSubviews="NO" boxType="custom" borderType="line" cornerRadius="28" title="Box" titlePosition="noTitle" id="Tbj-mM-87j">
|
||||
<rect key="frame" x="189" y="28" width="56" height="56"/>
|
||||
<box autoresizesSubviews="NO" boxType="custom" borderType="line" cornerRadius="100" title="Box" titlePosition="noTitle" id="Tbj-mM-87j">
|
||||
<rect key="frame" x="189" y="28" width="57" height="57"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<view key="contentView" id="aoX-nH-ofv">
|
||||
<rect key="frame" x="1" y="1" width="54" height="54"/>
|
||||
<rect key="frame" x="1" y="1" width="55" height="55"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button focusRingType="none" id="wQo-c7-sD7">
|
||||
<rect key="frame" x="14" y="14" width="27" height="26"/>
|
||||
<rect key="frame" x="14" y="15" width="27" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="NSAddTemplate" imagePosition="only" alignment="center" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="o7j-4e-NNJ">
|
||||
<behavior key="behavior" lightByContents="YES"/>
|
||||
@@ -906,15 +910,15 @@
|
||||
<action selector="addProject:" target="923-ke-ovW" id="YGQ-yu-Glg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<progressIndicator wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" id="vPH-Iq-Ray">
|
||||
<rect key="frame" x="11" y="11" width="32" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</progressIndicator>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="borderColor" red="0.97254901959999995" green="0.50196078430000002" blue="0.15686274510000001" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="borderColor" red="0.97254901960784312" green="0.50196078431372548" blue="0.15686274509803921" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
<progressIndicator wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" id="vPH-Iq-Ray">
|
||||
<rect key="frame" x="201" y="40" width="32" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</progressIndicator>
|
||||
<button focusRingType="none" id="wdl-kS-DYD">
|
||||
<rect key="frame" x="124" y="150" width="186" height="186"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
@@ -930,8 +934,8 @@
|
||||
</customView>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="borderColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="fillColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="borderColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="fillColor" red="0.98039221759999995" green="0.98039221759999995" blue="0.98039221759999995" alpha="1" colorSpace="deviceRGB"/>
|
||||
<connections>
|
||||
<outlet property="boxImport" destination="Tbj-mM-87j" id="Nly-uI-l8C"/>
|
||||
<outlet property="loadingIndicator" destination="vPH-Iq-Ray" id="qiU-X4-gPI"/>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Version 4.0.1</string>
|
||||
<string>Version 4.0.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
@@ -44,7 +44,7 @@
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2012-2018 Cappuccino Project. All rights reserved.</string>
|
||||
<string>Copyright © 2012-2024 Cappuccino Project</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
@@ -56,8 +56,6 @@
|
||||
<key>XCCLastCappuccinoMasterBranchURL</key>
|
||||
<string>https://github.com/cappuccino/cappuccino/archive/master.zip</string>
|
||||
<key>XCCLastCappuccinoReleaseURL</key>
|
||||
<string>https://github.com/cappuccino/cappuccino/archive/1.0.0.zip</string>
|
||||
<key>NSRequiresAquaSystemAppearance</key>
|
||||
<false/>
|
||||
<string>https://www.cappuccino.dev/downloads/CappuccinoStarter-1.0.0.zip</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -341,8 +341,15 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
|
||||
- (void)_writeSettings
|
||||
{
|
||||
NSData *data = [NSPropertyListSerialization dataFromPropertyList:self->settings format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];
|
||||
|
||||
# pragma mark -- TODO
|
||||
// Error should be handled with user interaction,
|
||||
// although this hasn't previously been so either.
|
||||
// Immedate concern is with removing noisy deprecation warnings.
|
||||
NSError* error = nil;
|
||||
NSData* data = [NSPropertyListSerialization dataWithPropertyList:self->settings format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];
|
||||
if(data != nil){
|
||||
NSLog(@"error %ld",(long)[error code]);
|
||||
}
|
||||
[data writeToFile:self.settingsPath atomically:YES];
|
||||
}
|
||||
|
||||
@@ -357,7 +364,7 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
self->settings[XCCCappuccinoProcessObjj2ObjcSkeletonKey] = @(self.processObjj2ObjcSkeleton);
|
||||
self->settings[XCCCappuccinoProcessNib2CibKey] = @(self.processNib2Cib);
|
||||
self->settings[XCCCappuccinoProjectPreviousStatusKey] = [NSNumber numberWithInt:self.status];
|
||||
|
||||
|
||||
if ([self.lastEventID boolValue])
|
||||
self->settings[XCCCappuccinoProjectLastEventIDKey] = self.lastEventID;
|
||||
|
||||
@@ -370,8 +377,16 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
|
||||
- (void)_writeXcodeCappIgnoreFile
|
||||
{
|
||||
NSData *data = [NSPropertyListSerialization dataFromPropertyList:self->settings format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];
|
||||
|
||||
# pragma TODO
|
||||
// More verifiable user notification of error?
|
||||
NSError *error = nil;
|
||||
NSData *data = [NSPropertyListSerialization dataWithPropertyList: self->settings
|
||||
format: NSPropertyListXMLFormat_v1_0
|
||||
options: 0
|
||||
error: &error];
|
||||
if(data != nil){
|
||||
NSLog(@"error %ld",(long)[error code]);
|
||||
}
|
||||
[data writeToFile:self.settingsPath atomically:YES];
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
@@ -93,15 +93,17 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
{
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
|
||||
NSRunAlertPanel(
|
||||
self.cappuccinoProject.nickname,
|
||||
@"XcodeCapp was unable to find all necessary executables in your environment:\n\n"
|
||||
@"%@\n\n"
|
||||
@"You certainly need to change the binary paths in the project settings.",
|
||||
@"OK",
|
||||
nil,
|
||||
nil,
|
||||
[self->taskLauncher.executables componentsJoinedByString:@", "]);
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSAlertStyleCritical];
|
||||
NSString *title = self.cappuccinoProject.nickname;
|
||||
[alert setMessageText:title];
|
||||
NSArray *informativeTextArray = @[
|
||||
@"XcodeCapp was unable to find all necessary executables in current environment:",
|
||||
@"Please confirm the following executables are in current $PATH:\n",
|
||||
[self->taskLauncher.executables componentsJoinedByString:@", "]
|
||||
];
|
||||
[alert setInformativeText:[informativeTextArray componentsJoinedByString:@"\n"]];
|
||||
[alert runModal];
|
||||
|
||||
[self _reinitializeProjectController];
|
||||
}
|
||||
@@ -155,7 +157,12 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (![fm fileExistsAtPath:self.cappuccinoProject.projectPath isDirectory:nil])
|
||||
{
|
||||
NSRunAlertPanel(@"The project can’t be located.", @"It seems the project moved while XcodeCapp was not running.", @"Remove Project", nil, nil);
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSAlertStyleCritical];
|
||||
[alert setMessageText:@"The project can’t be located"];
|
||||
NSString *informativeText = [NSString stringWithFormat:@"The project was either moved or deleted outside of the XcodeCapp environment.\nProject will be removed."];
|
||||
[alert setInformativeText:informativeText];
|
||||
[alert runModal];
|
||||
|
||||
[self.mainXcodeCappController unmanageCappuccinoProjectController:self];
|
||||
return NO;
|
||||
@@ -1003,7 +1010,12 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
- (void)_handleProjectPathChange:(NSString *)path
|
||||
{
|
||||
NSRunAlertPanel(self.cappuccinoProject.nickname, @"The project directory changed. This project will be removed", @"OK", nil, nil, nil);
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSAlertStyleCritical];
|
||||
[alert setMessageText:@"The project directory changed"];
|
||||
NSString *informativeText = [NSString stringWithFormat:@"This project will be removed."];
|
||||
[alert setInformativeText:informativeText];
|
||||
[alert runModal];
|
||||
|
||||
[self.mainXcodeCappController unmanageCappuccinoProjectController:self];
|
||||
}
|
||||
@@ -1206,15 +1218,27 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (!exists || !isDirectory || !isOpened)
|
||||
{
|
||||
NSString *text;
|
||||
NSString *projectErrorDescription;
|
||||
|
||||
if (!isOpened)
|
||||
text = @"The project exists, but failed to open.";
|
||||
projectErrorDescription = @"The project exists, but failed to open.";
|
||||
else
|
||||
text = [NSString stringWithFormat:@"%@ %@.", self.cappuccinoProject.XcodeProjectPath, !exists ? @"does not exist" : @"is not an Xcode project"];
|
||||
projectErrorDescription = [NSString stringWithFormat:@"%@ %@.", self.cappuccinoProject.XcodeProjectPath, !exists ? @"does not exist" : @"is not an Xcode project"];
|
||||
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
NSInteger response = NSRunAlertPanel(@"The project could not be opened.", @"%@\n\nWould you like to regenerate the project?", @"Yes", @"No", nil, text);
|
||||
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSAlertStyleCritical];
|
||||
[alert setMessageText:@"The project could not be opened"];
|
||||
NSArray *informativeTextArray = @[
|
||||
projectErrorDescription,
|
||||
@"Should the project be regenerated?"
|
||||
];
|
||||
NSString *informativeText = [informativeTextArray componentsJoinedByString:@"\n"];
|
||||
[alert setInformativeText:informativeText];
|
||||
[alert addButtonWithTitle:@"Yes"];
|
||||
[alert addButtonWithTitle:@"No"];
|
||||
NSInteger response = [alert runModal];
|
||||
|
||||
if (response == NSAlertFirstButtonReturn)
|
||||
[self resetProject:self];
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
- (void)_setTextColor:(NSColor *)color forButton:(NSButton *)button
|
||||
{
|
||||
NSMutableParagraphStyle *paragraphStyle= [NSMutableParagraphStyle new];
|
||||
[paragraphStyle setAlignment:NSCenterTextAlignment];
|
||||
[paragraphStyle setAlignment:NSTextAlignmentCenter];
|
||||
|
||||
NSDictionary *attrs = @{NSFontAttributeName: [NSFont systemFontOfSize:11],
|
||||
NSForegroundColorAttributeName: color,
|
||||
@@ -180,13 +180,12 @@
|
||||
|
||||
if (missingProjects.count)
|
||||
{
|
||||
NSRunAlertPanel(@"Missing Projects",
|
||||
@"Some managed projects could not be found and have been removed:\n\n"
|
||||
@"%@\n\n",
|
||||
@"OK",
|
||||
nil,
|
||||
nil,
|
||||
[missingProjects componentsJoinedByString:@", "]);
|
||||
NSString *informativeText = [NSString stringWithFormat:@"Some managed projects could not be found and have been removed:\n\n%@", [missingProjects componentsJoinedByString:@", "]];
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSAlertStyleCritical];
|
||||
[alert setMessageText:@"Missing Projects"];
|
||||
[alert setInformativeText:informativeText];
|
||||
[alert runModal];
|
||||
}
|
||||
|
||||
[self _saveManagedProjectsToUserDefaults];
|
||||
@@ -238,7 +237,11 @@
|
||||
{
|
||||
if ([[self.cappuccinoProjectControllers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"cappuccinoProject.projectPath == %@", path]] count])
|
||||
{
|
||||
NSRunAlertPanel(@"This project is already managed.", @"Please remove the other project or use the reset button.", @"OK", nil, nil, nil);
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSAlertStyleCritical];
|
||||
[alert setMessageText:@"This project is already managed."];
|
||||
[alert setInformativeText:@"Please remove the other project or use the reset button."];
|
||||
[alert runModal];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -306,16 +309,16 @@
|
||||
|
||||
- (IBAction)addProject:(id)aSender
|
||||
{
|
||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||
openPanel.title = @"Add a new Cappuccino Project to XcodeCapp";
|
||||
openPanel.canCreateDirectories = YES;
|
||||
openPanel.canChooseDirectories = YES;
|
||||
openPanel.canChooseFiles = NO;
|
||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||
openPanel.title = @"Add a new Cappuccino Project to XcodeCapp";
|
||||
openPanel.canCreateDirectories = YES;
|
||||
openPanel.canChooseDirectories = YES;
|
||||
openPanel.canChooseFiles = NO;
|
||||
|
||||
if ([openPanel runModal] != NSFileHandlingPanelOKButton)
|
||||
if ([openPanel runModal] != NSModalResponseOK)
|
||||
return;
|
||||
|
||||
NSString *projectPath = [[openPanel.URLs[0] path] stringByStandardizingPath];
|
||||
NSString *projectPath = [[openPanel.URLs[0] path] stringByStandardizingPath];
|
||||
|
||||
[self manageCappuccinoProjectControllerForPath:projectPath];
|
||||
}
|
||||
@@ -509,4 +512,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
# Note: Python2 must be installed to run this
|
||||
|
||||
from __future__ import with_statement
|
||||
from optparse import OptionParser
|
||||
from string import Template
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
chmod +x capp_lint
|
||||
|
||||
if [[ ! -d /usr/local/narwhal/bin ]]; then
|
||||
mkdir -p /usr/local/narwhal/bin
|
||||
fi
|
||||
|
||||
cp capp_lint /usr/local/narwhal/bin
|
||||
cp capp_lint /usr/local/bin
|
||||
|
||||
if [[ ! -d /usr/local/share/man/man1 ]]; then
|
||||
mkdir -p /usr/local/share/man/man1
|
||||
|
||||
+56
-38
@@ -34,25 +34,23 @@
|
||||
|
||||
@global java
|
||||
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var os = require("os");
|
||||
var child_process = require("child_process");
|
||||
var utilsFile = ObjectiveJ.utils.file;
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { execSync, spawnSync } = require('child_process');
|
||||
const child_process = require("child_process");
|
||||
const utilsFile = ObjectiveJ.utils.file;
|
||||
|
||||
/* var FILE = require("file"),
|
||||
OS = require("os"), */
|
||||
var SharedConverter = nil;
|
||||
|
||||
var SharedConverter = nil;
|
||||
NibFormatUndetermined = 0;
|
||||
NibFormatMac = 1;
|
||||
NibFormatIPhone = 2;
|
||||
|
||||
NibFormatUndetermined = 0;
|
||||
NibFormatMac = 1;
|
||||
NibFormatIPhone = 2;
|
||||
ConverterModeLegacy = 0;
|
||||
ConverterModeNew = 1;
|
||||
|
||||
ConverterModeLegacy = 0;
|
||||
ConverterModeNew = 1;
|
||||
|
||||
ConverterConversionException = @"ConverterConversionException";
|
||||
ConverterConversionException = @"ConverterConversionException";
|
||||
|
||||
@implementation Converter : CPObject
|
||||
{
|
||||
@@ -89,7 +87,7 @@ ConverterConversionException = @"ConverterConversionException";
|
||||
// Some .xibs are iPhone nibs, check the actual contents in this case.
|
||||
if (path.extname(inputPath) !== ".nib" && fs.lstatSync(inputPath).isFile() &&
|
||||
fs.readFileSync(inputPath, { encoding: "utf8" }).indexOf("<archive type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\"") !== -1)
|
||||
//FILE.read(inputPath, { charset:"UTF-8" }).indexOf("<archive type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\"") !== -1)
|
||||
|
||||
inferredFormat = NibFormatIPhone;
|
||||
|
||||
if (inferredFormat === NibFormatMac)
|
||||
@@ -108,7 +106,6 @@ ConverterConversionException = @"ConverterConversionException";
|
||||
|
||||
if ([outputPath length])
|
||||
fs.writeFileSync(outputPath, [convertedData rawString], { encoding: "utf8" });
|
||||
//FILE.write(outputPath, [convertedData rawString], { charset:"UTF-8" });
|
||||
|
||||
CPLog.info("Conversion successful");
|
||||
|
||||
@@ -145,13 +142,45 @@ ConverterConversionException = @"ConverterConversionException";
|
||||
|
||||
if ([outputPath length])
|
||||
{
|
||||
// Compile xib or nib to make sure we have a non-new format nib.
|
||||
// Compile xib or nib to make sure we have a legacy format nib.
|
||||
|
||||
// Use temporary paths for intermediate products.
|
||||
temporaryNibFilePath = path.join(tmpdir, path.basename(aFilePath) + ".tmp.nib");
|
||||
temporaryXibFilePath = path.join(tmpdir, path.basename(aFilePath));
|
||||
|
||||
|
||||
// Ensure that source xib's <deployment /> tag targets deployment version 10.10
|
||||
var xibContent = fs.readFileSync(aFilePath, { encoding: 'utf8' });
|
||||
|
||||
// Perform the in-memory modification of the deployment tag
|
||||
//
|
||||
// Remove existing <deployment /> tag, if present
|
||||
// xib's with Xcode 14 or later do not have a <deployment /> element at all.
|
||||
// It is simpler to ensure no <deployment /> element is present,
|
||||
// then add what we want.
|
||||
//
|
||||
// Add a new <deployment /> element as the first child of the <dependencies /> element.
|
||||
// This is the placement expected when Xcode adds the <deployment /> element.
|
||||
// Target version 10.10 as the deployment version.
|
||||
if (xibContent.includes('<deployment '))
|
||||
{
|
||||
xibContent = xibContent.replace(/<deployment .*\/>/g, '');
|
||||
}
|
||||
// Where will the <deployment /> element be inserted in the string?
|
||||
var deploymentTag = '\n <deployment version="10.10" identifier="macosx"/>';
|
||||
var insertPosition = xibContent.indexOf("<dependencies>") + "<dependencies>".length;
|
||||
|
||||
// Slice the string representing the source xib and insert the new <deployment /> element.
|
||||
var updatedXIBContent = xibContent.slice(0, insertPosition) + deploymentTag + xibContent.slice(insertPosition);
|
||||
|
||||
try {
|
||||
child_process.execSync("/usr/bin/ibtool" + " '" + aFilePath + "' " + "--compile" + " '" + temporaryNibFilePath + "'", {stdio: 'inherit'});
|
||||
} catch(err) {
|
||||
[CPException raise:ConverterConversionException reason:@"Could not compile file: " + aFilePath];
|
||||
fs.writeFileSync(temporaryXibFilePath, updatedXIBContent, 'utf8');
|
||||
try
|
||||
{
|
||||
child_process.execSync("/usr/bin/ibtool" + " '" + temporaryXibFilePath + "' " + "--compile" + " '" + temporaryNibFilePath + "'", {stdio: 'inherit'});
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
[CPException raise:ConverterConversionException reason:@"Could not compile file: " + temporaryXibFilePath];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -169,30 +198,19 @@ ConverterConversionException = @"ConverterConversionException";
|
||||
// Convert from binary plist to XML plist
|
||||
var temporaryPlistFilePath = path.join(tmpdir, path.basename(aFilePath) + ".tmp.plist");
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
child_process.execSync("/usr/bin/plutil" + " " + "-convert" + " " + "xml1" + " '" + (temporaryNibFilePathInDirectoryFile || temporaryNibFilePath) + "' " + "-o" + " '" + temporaryPlistFilePath + "'", {stdio: 'inherit'});
|
||||
} catch(err) {
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
[CPException raise:ConverterConversionException reason:@"Could not convert to xml plist for file: " + aFilePath];
|
||||
}
|
||||
|
||||
/* try
|
||||
{
|
||||
var p = OS.popen(["/usr/bin/plutil", "-convert", "xml1", temporaryNibFilePath, "-o", temporaryPlistFilePath]);
|
||||
if (p.wait() === 1)
|
||||
[CPException raise:ConverterConversionException reason:@"Could not convert to xml plist for file: " + aFilePath];
|
||||
}
|
||||
finally
|
||||
{
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
p.stderr.close();
|
||||
} */
|
||||
|
||||
if (!isReadable(temporaryPlistFilePath))
|
||||
[CPException raise:ConverterConversionException reason:@"Unable to convert nib file."];
|
||||
|
||||
var plistContents = fs.readFileSync(temporaryPlistFilePath, { encoding: "utf8" });
|
||||
//var plistContents = FILE.read(temporaryPlistFilePath, { charset: "UTF-8" });
|
||||
|
||||
// Minor NS keyed archive to CP keyed archive conversion.
|
||||
// Use Java directly because rhino's string.replace is *so slow*. 4 seconds vs. 1 millisecond.
|
||||
|
||||
+15
-1
@@ -381,7 +381,21 @@ if [ `uname` = "Darwin" ]; then
|
||||
check_build_environment
|
||||
|
||||
# The narwhal-jsc package is already installed within the base kit.
|
||||
|
||||
|
||||
# Xcode 15's version of the 'ld' linker no longer supports
|
||||
# the '-force_cpusubtype_ALL' flag.
|
||||
# Although not documented, this may have been included to support PowerPC compilation.
|
||||
# Removing the flag has been successfully tested on High Sierra/Xcode 10.1
|
||||
# Testing on all intermediate operating systems and Xcode versions isn't practical,
|
||||
# or beneficial, given the imminent move to NodeJS.
|
||||
# We apply the patch here for expediency, rather than in the 'cappuccino-base' repository.
|
||||
# If a full final release of the narwhal branch is undertaken,
|
||||
# the change will be applied to cappuccino-base at that time.
|
||||
# Note: Rosetta2 is still available in macOS Sonoma.
|
||||
# Compiling for both Intel and Apple Silicon targets requires a testing program
|
||||
# which is, again, neither practical nor justified at this stage of Narwhal's lifecycle.
|
||||
sed -i .orig 's/-force_cpusubtype_ALL//g' $install_directory/packages/narwhal-jsc/Makefile
|
||||
|
||||
# This autoreconf command improves compatibility with MacPorts, but only works with autoconf 2.65+.
|
||||
needed_autoconf_major=2
|
||||
needed_autoconf_minor=65
|
||||
|
||||
Reference in New Issue
Block a user