NSSearchField with menu not being updated - objective-c

I haev a Document Based Application, and In the document view, I have a NSSearchField. In the search field, I have enabled the menu, which I get to show up, and I have associated actions with the menu item. One of the menu items is called "Match Case". I want to be able to put (and remove) a check next this menu item. When I attempt to do so, the menu does not show the check.
-(IBAction)searchMenuMatchCase:(id)sender {
NSMenuItem *smi = [searchMenu itemWithTitle:#"Match Case"];
if (searchCaseSensitive) {
searchCaseSensitive = false;
[[searchMenu itemWithTitle:#"Match Case"] setState:NSOffState];
} else {
searchCaseSensitive = true;
[[searchMenu itemWithTitle:#"Match Case"] setState:NSOnState];
}
[searchMenu update];
NSLog(#"SM State %ld",[smi state]);
}
The code gets executed, and I get a log message showing the state going from 0 to 1 to 0 to 1. But there is never a check next to the menu item. When I look at the menu item object while debugging, I do see the "state" value set to 0 and 1 before I toggle it.
Any suggestions as to what I am missing?

To get around this issue, I had to use the NSMenuDelegate and use the method validateMenuItem. This way the validateMenuItem method was called before the menu was drawn, and I could make sure the state was set correctly before the menu was drawn. I believe what was happening was that the menu item I was getting in the original code was not the actual menu that was being drawn, but just a template.
/**
This is called when the user selectes the "Match Case" menu item found in the Search field
*/
-(IBAction)searchMenuMatchCase:(id)sender {
if (searchCaseSensitive) {
searchCaseSensitive = false;
} else {
searchCaseSensitive = true;
}
}
/**
This is called Each time a menu is shown.
*/
-(BOOL) validateMenuItem:(NSMenuItem *)menuItem {
if ([[menuItem title] compare:#"Match Case"] == 0) {
if (searchCaseSensitive) {
[menuItem setState:NSOnState];
} else {
[menuItem setState:NSOffState];
}
}
return YES;
}

Related

Optimise Kotlin code for button clicked state

I want to change the button background when the button clicked, the function is work by using this code
bank1.setOnClickListener {
bank1.setBackgroundResource(R.drawable.selected_btn_border_blue_bg);
bank2.setBackgroundResource(R.drawable.default_option_border_bg);
bank3.setBackgroundResource(R.drawable.default_option_border_bg);
bank4.setBackgroundResource(R.drawable.default_option_border_bg);
}
bank2.setOnClickListener {
bank2.setBackgroundResource(R.drawable.selected_btn_border_blue_bg);
bank1.setBackgroundResource(R.drawable.default_option_border_bg);
bank3.setBackgroundResource(R.drawable.default_option_border_bg);
bank4.setBackgroundResource(R.drawable.default_option_border_bg);
}
bank3.setOnClickListener {
bank3.setBackgroundResource(R.drawable.selected_btn_border_blue_bg);
bank2.setBackgroundResource(R.drawable.default_option_border_bg);
bank1.setBackgroundResource(R.drawable.default_option_border_bg);
bank4.setBackgroundResource(R.drawable.default_option_border_bg);
}
bank4.setOnClickListener {
bank4.setBackgroundResource(R.drawable.selected_btn_border_blue_bg);
bank2.setBackgroundResource(R.drawable.default_option_border_bg);
bank3.setBackgroundResource(R.drawable.default_option_border_bg);
bank1.setBackgroundResource(R.drawable.default_option_border_bg);
}
But it kinda hardcoded, and make it to so many lines, any way to make the code shorter?
I would keep a variable that keeps track of the selected one like
private var selectedBank: View? = null
And then do
arrayOf(bank1, bank2, bank3, bank4).forEach {
it.setOnClickListener {
selectedBank?.setBackgroundResource(R.drawable.default_option_border_bg)
selectedBank = it
it.setBackgroundResource(R.drawable.selected_btn_border_blue_bg)
}
}
you only need to deselected the previous selected one

FLEX Button event handling

I have a scenario where i have 5 buttons which call the same method when clicked. These buttons are clicked in various conditions, but now i want to know how we determine that which particular button has been clicked, from the called method.
For example, i have been calling chocolate() method when i click the buttons, eclairs, dailrymilk, cadbury, snickers and kitkat. Now i will click anyof these buttons from the UI and i want to know which one is clicked. this event has to be handled in the chocolate() method only.
Please suggest me how can i implement this. I am using Adobe Flex 3
If you are not using the addEventListeners but are setting the click property in your buttons you could do something like that:
<s:Button id="snickers"
click="{chocolate('snickers')}"
label="snickers"/>
<s:Button id="kitkat"
click="{chocolate('kitkat')}"
label="kitkat"/>
private function chocolate(type:String):void
{
trace("button", type, "was clicked");
if(type == "snickers")
{
// do stuff
}
else if(type == "kitkat")
{
// do something else
}
}
if you are working with event listeners you could determine the buttons from their ids, for example:
<s:Button id="snickers"
label="snickers"/>
<s:Button id="kitkat"
label="kitkat"/>
// add your event listeners somewhere like in onCreationComplete
snickers.addEventListener(MouseEvent.CLICK, chocolate);
kitkat.addEventListener(MouseEvent.CLICK, chocolate);
private function chocolate(e:MouseEvent):void
{
// e.target is the component that has dispatched the event (a button in this case)
var type:String = e.target.id;
trace("button", type, "was clicked");
if(type == "snickers")
{
// do stuff
}
else if(type == "kitkat")
{
// do something else
}
}

Position of child of instance variable not updating

Hopefully this is a fairly simple question. I create an instance variable named tutorialBox1 from my main game scene Grid.m. Inside my class TutorialBox.m, I create a sprite named textBox1, and as I tap on the main game scene, I want the position of that sprite, textBox1 to be updated. I've been trying to figure out for hours why the position of the sprite will not update after adding the child once. Here is my attempt, and all the necessary code.
Grid.m
# implementation Grid {
TutorialBox *tutorialBox1;
}
-(void)checkTutorials {
//This method is called upon loading of the scene
tutorialBox1 = (TutorialBox*)[CCBReader load:#"TutorialBox"] //creates instance of variable using Spritebuilder (don't worry if you don't use SB, this part works)
[tutorialBox1 updateBoxDisplay:1] //used to add text box child to textBox1
[self addChild:tutorialBox1];
}
-(void)gridTapped {
//When game scene is tapped, this is called to update position of textBox1 in tutorialBox1
[tutorialBox1 updateBoxDisplay:2]; //updates position of textBox1 in tutorialBox1
}
TutorialBox.m
# implementation Grid {
CCSprite9Slice *textBox1;
}
-(void)didLoadFromCCB {
//Called upon initialization of tutorialBox1
textBox1 = [CCSprite9Slice spriteWithImageNamed:#"RetroSprites/tutorialtextBox1.png"];
}
-(void)updateBoxDisplay:(int)newTutorialLevelNumber {
if (newTutorialLevelNumber == 1) {
textBox1.position = ccp(0,0);
[self addChild:textBox1];
}
else if (newTutorialLevelNumber == 2) {
textBox1.position = ccp(100,100)
}
}
TutorialBox.h
#interface TutorialBox : CCNode
- (void)updateBoxDisplay:(int)newTutorialLevelNumber
#end
I have checked to make sure everything is running properly with print statements, so it isn't an issue with anything else. It is simply being called, but the position in my main game scene, Grid.m is not being updated.
Thanks for the help!
I am not sure about this, but I guess its issue with the threading. Give a try with this code:
-(void)updateBoxDisplay:(int)newTutorialLevelNumber {
dispatch_async(dispatch_get_main_queue(), ^{
if (newTutorialLevelNumber == 1) {
textBox1.position = ccp(0,0);
[self addChild:textBox1];
}
else if (newTutorialLevelNumber == 2) {
textBox1.position = ccp(100,100)
}
});
}

How do I display invalid form Dijits inside closed TitlePanes?

I have a large Dijit-based form with many Dijits in collapsible TitlePanes.
When the form validates, any invalid items hidden inside closed TitlePanes (obviously) cannot be seen. So it appears as though the form is just dead and won't submit, though, unbeknownst to the user, there's actually an error hidden in a closed TitlePane which is preventing the form processing.
What's the solution here? Is there an easy way to simply open all TitlePanes containing Dijits that are in an error state?
If validation is done by following, it will work:-
function validateForm() {
var myform = dijit.byId("myform");
myform.connectChildren();
var isValid = myform.validate();
var errorFields = dojo.query(".dijitError");
errorFields.forEach(fieldnode){
var titlePane = getParentTitlePane(fieldnode);
//write a method getParentTitlePane to find the pane to which this field belongs
if(titlePane) {
titlePane.set('open',true);
}
}
return isValid;
}
function getParentTitlePane(fieldnode) {
var titlePane;
//dijitTitlePane is the class of TitlePane widget
while(fieldnode && fieldnode.className!="dijitTitlePane") {
fieldnode= fieldnode.parentNode;
}
if(fieldnode) {
mynode = dijit.getEnclosingWidget(fieldnode);
}
return titlePane;
}
Lets say if the following is the HTML and we call the above validateForm on submit of form.
<form id="myform" data-dojo-type="dijit/form/Form" onSubmit="validateForm();">
......
</form>
Here's what I ended up doing (I'm not great with Javascript, so this might sucked, but it works -- suggestions for improvement are appreciated):
function openTitlePanes(form) {
// Iterate through the child widgets of the form
dijit.registry.findWidgets(document.getElementById(form.id)).forEach(function(item) {
// Is this a title pane?
if (item.baseClass == 'dijitTitlePane') {
// Iterate the children of this title pane
dijit.registry.findWidgets(document.getElementById(item.id)).forEach(function(child) {
// Does this child have a validator, and -- if so -- is it valid?
if (!(typeof child.isValid === 'undefined') && !child.isValid()) {
// It's not valid, make sure the title pane is open
item.set('open', true);
}
});
}
});
}

Sencha Touch 2 How to Detect Top Level on Nestedlist

I would like to create an event listener to detect when my nestedlist is at the top level, and then hide a component on the page. For example:
onNestedlistActiveItemChange: function(container, value, oldValue, options) {
if (this.getMyNestedList().atLevel(0)) <-- seudo code, does not work
{
Ext.getCmp('myButton').hide();
}
}
Thanks in advance for your help
The _backButton._hidden property of the nested list will return true when the default back button is hidden and false when the button is displayed. The button is hidden only when the nested list is at the top level.
The trick is to use the nested list's "back" event, which returns the state of the toolbar after the back event has occurred:
onMynestedlistBack: function(nestedlist, node, lastActiveList, detailCardActive, options){
if(nestedlist._backButton._hidden) {
Ext.ComponentQuery.query('#myButton')[0].hide();
}
}
That is, if the nested list's back button is hidden, then the list is at the top level, so hide myButton.
There are certainly more rigorous ways to do it, but most of them would involve overriding the toolbar's default button handling.
You can get the list level by checking the index of the list
var idx = nestedlist.getInnerItems().indexOf(list);
if (idx === 0) {
// top level...
}
[UPDATE]
You can also check the depth level of the record
var depth = record.getData().depth;
if (depth === 1) {
// top level...
}