makeFirstResponder won't compile - macos

I have an array of buttons and an array of associated NSTextViews (embedded in NSScrollViews), all created programmatically. All this in a program (a calendar) that compiles and works fine as far as it does.
However, I would like clicking a button to cause the associated text field to behave as if I had clicked directly in it (cursor and focus ring appear and it accepts text). Right now, I have to click the button AND the text box before I begin entering text.
It appears that “makeFirstResponder” should do what I want, but it won’t compile as I am trying to do it.
Here is the relevant code:
(All in a single View Controller)
Global Declarations:
var arrayOfButtons:[NSButton] = []
var arrayOfFields: [NSTextView!] = []
var arrayOfWindows: [NSScrollView!] = []
Creation of array of fields:
var i = 0
var myLocalText: NSTextView! = NSTextView(…
var myLocalWindow: NSScrollView! = NSScrollView(…
for i = 0; i <= 6; i++ {
var myLocalText: NSTextView! = NSTextView(…
var myLocalWindow: NSScrollView! = NSScrollView(…
view.addSubview(myLocalWindow)
myLocalWindow.hasVerticalScroller = false
myLocalWindow.focusRingType = NSFocusRingType(rawValue: UInt(2))! // I didn’t get a focus ring until I did this
myLocalWindow.addSubview(myLocalText)
myLocalWindow.documentView = myLocalText
myLocalText.editable = true
myLocalText.selectable = true
myLocalText.verticallyResizable = true
self.arrayOfFields.append(myLocalText)
}
Routine that responds to clicking a button:
…
view.makeFirstResponder(arrayOfFields[tag]) // THIS IS THE SUBJECT OF MY QUESTION
// IT GIVES A COMPILER ERROR AS FOLLOWS: “Cannot invoke ‘makeFirstResponder’ with an argument list of type ’NSTextView’”
// as far as I can tell from the documentation, makeFirstResponder should accept an argument type of NSResponder, and NSTextView should inherit from that

In Mac OS X, makeFirstResponder is an NSWindow method, not an NSView method.

Related

Why some string in SwiftUI app are not localized

I use Export/Import localization functionality in Xcode 13.2.1 and it works more or less fine but some strings are not exported in xcloc file, for example texts from function below
func createInitialStepTypes(inContext context: NSManagedObjectContext) {
let names = ["NVA", "NEC", "VA"]
let nvaDesc = "Step with not added value (typically preparing of equipment, exception handling, etc.)."
let necDesc = "Necessary steps but still not adding value (typically system actions like login, manual data entry, etc.)."
let vaDesc = "Step with added value (typically material handling)."
let descs = [nvaDesc, necDesc, vaDesc]
let colors: [Color] = [Color.red, Color.orange, Color.green]
for (i, _) in names.enumerated() {
name = names[i]
desc = descs[i]
color = colors[i]
save(stepTypeID: nil, inContext: context)
}
}
Strings from other functions in the same class like e.g. this one
errMsg = "Step type \(stepType.name!) can't be deleted because it's being used."
are captured correctly. Any idea why?
Thanks.

Change cell color based on selection from dropdown menu

This is a script I am writing to help me figure out how to write a more complex script.
In my spreadsheet, I have one column that contains a list of values ("testRange","testRangeValues"). I also have a dropdown list ("testCell","testCellValue"). The dropdown list contains some values that are in the "testRange" list and some that are not.
I would like my script to function in such a way that when I select a value from the dropdown list that matches value from the testRange list, the background color of the corresponding value in the testRange list changes to red.
function onEdit3(e) {
var testRange = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A4:A8");
var testRangeValues = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A4:A8").getValues();
var testCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("C4");
var testCellValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("C4").getValue();
for(var i = 0;i<testRange.length;i++){
if(testCellValue==testRangeValues[i]){
testRange[i].setBackground("Red");
}
}
}
Currently no color change is happening. I guess I'm not quite sure how to correctly write my for loop/if statement to achieve the intended effect. Is there perhaps a way to do this using just some sort of conditional formatting formula in my spreadsheet?
You want to change the background color of cell in the range of "A4:A8" that the value of dropdown list of "C4" is the same.
You want to achieve this using Google Apps Script.
From your script, you don't want to use the event object.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
The sheet object can be written by var sheet = SpreadsheetApp.getActiveSheet();. By this, you can use sheet for retrieving the range.
sheet.getRange("A4:A8") and sheet.getRange("C4") can be used one time.
In this case, the range object cannot be used in the loop, because testRange.length returns null.
When above points are reflected to your script, it becomes as follows.
Pattern 1:
In this pattern, only background color of the selected value is changed to the red color. So for example, when "A" is selected, the background color of "A" is changed to the red color. And when "C" is selected, the background color of "C" is changed to the red color. In this case, the background color of "A" is reset.
Modified script:
function onEdit3(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var testRange = sheet.getRange("A4:A8");
var testRangeValues = testRange.getValues();
var testCell = sheet.getRange("C4");
var testCellValue = testCell.getValue();
var backgroundColors = testRangeValues.map(function([a]) {return [a == testCellValue ? "Red" : ""]});
testRange.setBackgrounds(backgroundColors);
}
Pattern 2:
In this pattern, the background color of the selected value is saved. So for example, when "A" is selected, the background color of "A" is changed to the red color. And when "C" is selected, the background color of "C" is changed to the red color. In this case, the background color of "A" is kept the red color.
Modified script:
function onEdit3(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var testRange = sheet.getRange("A4:A8");
var testRangeValues = testRange.getValues();
var testCell = sheet.getRange("C4");
var testCellValue = testCell.getValue();
for (var i = 0; i < testRangeValues.length; i++) {
if (testRangeValues[i] == testCellValue) {
sheet.getRange("A" + (4 + i)).setBackground("Red");
break;
}
}
}
Modern javascript:
You can use modern javascript syntax. For this you need to enable V8 runtime. After this you can
/**
*
* #param {GoogleAppsScript.Events.SheetsOnEdit} e
*/
const onEdit = e => {
const sheet = e.range.getSheet();
const value = e.range.getValue();
if (sheet.getName() == 'Sheet1' && e.range.getA1Notation() === 'C2') {
const range = sheet.getRange(2, 1, sheet.getLastRow() - 1, 1);
range.setBackgrounds(
range.getValues().map(row => [row[0] === value ? 'red' : ''])
);
}
};
References:
setBackground(color)
setBackgrounds(color)
If I misunderstood your question and this was not the direction you want, I apologize.

InDesign CC 2017 ExtendScript - Can't overwrite text in TextArea

At this point, I'm sure this is something simple that I'm missing but I can't for the life of me figure it out.
Working on an InDesign script that takes text passed into the script and writes it into the currently selected text area.
insertButton.onClick = function(){
var postIndex = postList.selection.index;
var postContent = posts[postIndex].content.rendered;
$.writeln(app.selection[0].parentStory.contents);
app.selection[0].parentStory.contents = postContent;
$.writeln(app.selection[0].parentStory.contents);
myWindow.close();
}
I've confirmed that the function is getting called correctly, that postContent exists and is what I expect it to be and that the first writeln call dumps out the current value of the TextArea. The second $.writeln never fires, so I know the error is on
app.selection[0].parentStory.contents = postContent;
Is there an updated way to set TextArea contents that I haven't found in documentation?
Thanks in advance!
I think your problem is that your window is modal thus preventing any interaction with inDesign objects.
You have to quit the dialog first in order to modify objects:
var w = new Window('dialog');
var btn = w.add('button');
btn.onClick = function() {
w.close(1);
}
if ( w.show()==1){
//"InDesign is no longer in modal state. So you can modify objects…")
}
...postContent exists and is what I expect it to be...
Indesign expects a string here --> is it what you expect as well?
What is an input selection? text? textFrame?
You could
alert(postContent.construction.name)
to ensure what you've got
Jarek
When debugging was enabled in ExtendScript Toolkit, I was able to find the error being thrown:
"cannot handle the request because a modal dialog or alert is active"
This was referring to the dialog I opened when I initiated the script.
Delaying the text insertion until the dialog has actually been closed fixed the issue.
insertButton.onClick = function(){
var postIndex = postList.selection.index;
postContent = posts[postIndex].content.rendered;
postContent = sanitizePostContent(postContent);
// The 1 here is the result that tells our code down below that
// the window has been closed by clicking the 'Insert' button
myWindow.close(1);
}
var result = myWindow.show();
// If the window has been closed by the insert button, insert the content
if (result == 1) {
app.selection[0].parentStory.contents = postContent;
}

How do I put this into code?

I'm struggling on how I can put this into code.
int a=500;
By default x = a-100
I am trying to find a way where when one button is clicked, it sets the x-coordinate to x=a-100 , and then when the same button is pressed again, it sets x=0.
How would i logically put this into code?
Thanks a lot!
Somewhere, have a variable keep track of whether or not the button has been previously pressed. Since you haven't indicated what language you're using, I'll have to make this very generic, and assume the typical interface that's used to handle button press events.
var button = (some GUI button object);
var a = 500;
var x = 2;
var buttonHasBeenPressed = false;
button.onPress = function() {
if (buttonHasBeenPressed) {
x = 0;
} else {
x = a - 100;
}
buttonHasBeenPressed = true;
};
Where you store the flag (buttonHasBeenPressed) depends on your skill level, the size of your program and many other factors. This is just a rough example using pseudo-javascript.

How do I store and retrieve a variable from an array using the Firefox Add-on SDK?

I am attempting to develop a Firefox extension.
I have a simple need. At this time in testing, I simply wish to define an array. When the button is pushed, the Current Window goes to the first URL in the array. When the button is pushed again, it goes to the next URL in the array.
I am of the impression that I need to store the present sequence in the array using simple-storage (ss.storage) yet I cannot make it work. I thought perhaps I could store the sequence information using a Cookie but the Add-on SDK appears to be very stringent. Perhaps there is a far simpler method but I cannot seem to identify what that would be.
Current Status - when the button is pushed, the code opens three separate windows for each URL in the array. If you could please help me to modify this code so that opens one URL from the array each time the button is pushed - as described above.
require("widget").Widget({
id: "view-source-widget",
label: "View Source",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
var arr = new Array("one.com","two.com","three.com");
for(var i=0; i<arr.length; i++) {
var value = arr[i];
var ss = require("simple-storage");
ss.storage.myURL= value;
var windows = require("windows").browserWindows;
windows.open(ss.storage.myURL);
}
}
});
If I understand correctly what you are trying to do - you don't need persistent storage, a normal global variable will do. The global variable indicates the array index at which you are right now. Something like this:
var urls = ["one.com","two.com","three.com"];
var urlIndex = 0;
...
onClick: function() {
var windows = require("windows").browserWindows;
windows.open(urls[urlIndex]);
// Increase index for the next click
urlIndex++;
if (urlIndex >= urls.length)
urlIndex = 0;
}
...

Resources