Realtime status bar view - xcode

I have a status bar application and when I'm opening it, it shows me informations but if these informations are changing (percentage here), I don't see it directly. I must reopen it to make it shows new informations.
Here I open the app one time it's 90% :
Then I wait some time and reopen it, it's already 100% :
Is there a way to show "in real time" labels and stuff in a status bar application ?

Having come across it before:
https://github.com/adamhartford/PopStatusItem
Does quite well, appears to be thread friendly (having tested with async threads) on the popup item..
Edit
addition as the user needs the actual status bar Image/text updated as opposed to the popup...
let sysStatusBar = NSStatusBar.systemStatusBar()
dispatch_async(dispatch_main(){
let dele = NSApp.delegate as? AppDelegate
dele.statusBarValue = 100.0
// from the delegate or a singleton method, have statusbarValue observed
// and update the App.delegate.statusBarItem.image accordingly.
// make sure it happens on the main thread... then the image / text
// will update...
}
What you're doing is updating the delegate where you've added the NSStatusBarItem and updating the image there. IN my example, I update the "statusBarValue" but if you just add a binding or an observer to the value, you can just as easily update the image.
ONCE AGAIN Make sure this happens on the main thread, or the UI is just going to ignore your updates. So updates from background threads etc... need to call out on the main thread.

Related

Continuous calls of the <Configure> event in tkinter

I am trying to write a function to dynamically resize an image displayed in a tkinter window.
Therefore I bound this function to the Configure event:
connroot.bind( "<Configure>", connresiz)
My problems are:
That the connresiz() function gets called 3 times (why 3?) at program start, and
More troublesome, that dynamically resizing the window calls the function continuously as I drag the mouse! How can avoid this?
I thought about checking at the simultaneous presence of a <Configure> and <ButtonRelease-1> events, but I don't know how to code it.
1) We don't know that, since we can't see your code...
2) Short answer is: you can't, because that's exactly what <Configure> event does! Long answer, you can, with a little trick/hack. Since anytime the window is changing, it will call all the binded functions to <Configure>, and the same happens anytime as the mouse button released (right after the last <Configure> call) we can create a flag/switch which will tell us, if the window was "configured" then we can check that switch anytime the mouse button is released, and switch it back to the default value after we ran some actions.
So if you want the image to resized only, when the mouse was released and the window was changed this is the code you need:
from tkinter import *
class Run:
def __init__(self):
self.root = Tk()
self.clicked = False
self.root.bind('<ButtonRelease-1>', self.image_resize)
self.root.bind('<Configure>', lambda e: self.click(True))
def image_resize(self, event):
if self.clicked:
print("I'm printed after <Configure>.") # the action goes here!
self.click(False)
def click(self, value):
self.clicked = value
app = Run()
app.root.mainloop()
According to the official tk documentation, <Configure> events fire "whenever its size, position, or border width changes, and sometimes when it has changed position in the stacking order." This can happen several times during startup.
It is called continuously while you resize the window because the size of the widget is changing. That's what it's defined to do. You can't prevent it from being called, though you can certainly modify what you do in the callback. For example, you could delay resizing the image until you've not received another <Configure> event for a second or two -- which likely means the user has stopped interactive resizing.

Applescript and Microsoft Word

I'm working on a applescript to update the content of a document in Microsoft Word. The updating process is quite long (might take more than 5s). So I want to prevent users to change anything during the updating. Do you know whether Microsoft or Applescript a function like that?
In Windows, I can just display a User Form (which is a dialog telling that "we are updating... ") and close that form when it's done. However, I don't know whether I can do the same in Mac (with Applescript alone).
When you say "applescript", I don't know if you mean "plain" applescript or the AppleScriptObjC version. If you mean the latter, then I know ways to do it.
One way I've used during slow processes is to put an overlay view over the whole content view of the window. I make it translucent white to partially obscure the window, and put some kind of message (and maybe a progress indicator) on it. You can just use an NSBox (of the custom type) in IB to make this, and then make a subclass of NSBox to color the view and override mouseDown:. MouseDown:, doesn't need to have any code in it, just by overriding it, you capture any key and mouse events so they don't accumulate on the event queue, and get used by the view below after your overlay goes away. Here's code I've used:
script Overlay
property parent : class "NSBox"
on awakeFromNib()
set overlayColor to current application's NSColor's colorWithCalibratedWhite_alpha_(1,.8)
setFillColor_(overlayColor)
end
on mouseDown_(theEvent)
--log "mouseDown"
end
end script
I have this view as the top most view in the view hierarchy, and set its hidden property to true until I want to show it.

Updating windows forms panel with progress message during execution

I am trying to show the progress of my windows form application in a panel within the form. However, all the messages show together at the end of when the application completes executing. Is there a way to display the messages as the code - execution "progress" through these messages - just the way it would in an interpreted language?
PS: I am adding the message as a label control to the panel at different points within the code.
Thank you.
You have to invalidate the label every time you change the message:
label1.Text = "Initializing...";
label1.Refresh();
// Do Stuff
label1.Text = "Working...";
label1.Refresh();
// Do Stuff
label1.Text = "Completed.";
label1.Refresh();
Or, it may be worth using a backgroundWorker (or another thread). Whats happening now is that the main thread (the one that also draws the UI) is too busy doing the processing to update the UI.
I'm not sure what language you're using, but Ill assume C#. In that case, create a BackgroundWorker that reports progress. Call the Background worker asynchronously so that it does the processing and use the Reports_Progress event to set the label. You cant set the label in the main Backgroundworker do_work procedure since the label was created by another thread. See this example, it may help (admittedly he sets a progress-bar value but you can just as easily set label text - http://www.dotnetperls.com/progressbar)
If you dont have the Backgroundworker class, you can implement the same logic, just using a different thread.
If you need some more info, let me know.

Updating the progress indicator while downloading firmware to the device

I am developing a cocoa application which downloads firmware to the device. The progress of downloading is showed using NSProgressIndicator. I call the -incrementBy: method of NSProgressIndicator after DeviceRequestTO method in a while loop. But the progress indicator gets updated only after the entire firmware is written to the device. It shows 100% completion at one go itself. So I added the -displayIfNeeded method of NSView class. Now it shows progress smoothly but this too occurs after the firmware download is complete. How can I achieve the progress indication and write operation simultaneously?
Following is the code:
while(1)
{
int result = (*dev)->DeviceRequestTO(dev, &request);
printf("\nBlocks Written Successfully: %d",DfuBlockCnt);
[refToSelf performSelectorOnMainThread:#selector(notifyContent)
withObject:nil
waitUntilDone:NO];
}
//In main thread
- (void)notifyContent{
[dnldIndicator incrementBy:1];
[self displayIfNeeded];
}
The method you need to call is setNeedsDisplay:, not displayIfNeeded. The latter means “send yourself display if somebody has sent you setNeedsDisplay:YES”. If you don't do that last part, the view doesn't know it should display, and displayIfNeeded will do nothing.
And once you add the setNeedsDisplay: message, you may be able to cut out the displayIfNeeded message, as the framework sends that message to the window (and, hence, to all its views) periodically anyway.
Your code looks exactly like some that I use for updating UIProgressIndicators and NSProgressIndicators on the Mac and iPhone, code that works perfectly for me. I'm assuming, like menumachine, that your while loop exists on a background thread (created using performSelectorInBackground:withObject: or NSThread's detachNewThreadSelector:toTarget:withObject:).
Are the minValue and maxValue of the progress indicator set correctly (0 and 100 or whatever your scale is)?
How frequently do updates occur? Maybe you're sending too many events too quickly and the UI is not having a chance to update properly.
This code should work, as far as I can tell.

RBSplitView has delayed reload of autosaved view positions

I really enjoy using RBSplitView, an open source replacement for NSSplitView, but I have a problem in my shipping app and am experiencing it again in a new project.
The problem is I'm telling the RBSplitView to autosave its position state by giving it an autosave name. When my app launches the RBSplitView doesn't seem to honor the saved state till a second after the window is drawn.
I've spent the night trying to debug the behavior but have had little success. Anyone out there use this lib and have some advice?
You can scrub this quicktime movie to the issue at work:
http://media.clickablebliss.com/billable/interface_experiments/rbsplitview_delayed_autosave_reload2.mov
I've still been unable to figure out why this is happening but I do have a workaround.
First, make sure your main window is not visible at launch and then at the end of applicationDidFinishLaunching in your app delegate add something like:
[mainWindow performSelector:#selector(makeKeyAndOrderFront:) withObject:self afterDelay: 0.1];
The delay is the key. If you just tell the window to makeKeyAndOrderFront: I still see the issue. However as long as it has a beat of time it looks good.
This likely is happening because the RBSplitView instance needs to wait until it's first moment to get to set its frame to the autosaved value, which happens to be after the user can see it. This 0.0-delay trick simply delays showing the window until the very next runloop, which gives the split view a chance to do its magic (and other views) so that when the user sees the window, it's already nice and sexy. So just do the delay at 0.0 and you'll be fine.
I have a similar, but slightly different workaround in my app that uses RBSplitView. In applicationDidFinishLaunching:, I call adjustSubviews on the split view before calling makeKeyAndOrderFront: on the window that contains it. This seems to knock the split view in to order before it gets displayed on the screen.

Resources