diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 346fa292520..a5fec1f101c 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -264,7 +264,24 @@ extern int GHOST_DispatchEvents(GHOST_SystemHandle systemhandle); extern GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle); +/*************************************************************************************** + ** Progress bar functionality + ***************************************************************************************/ +/** + * Sets the progress bar value displayed in the window/application icon + * @param windowhandle The handle to the window + * @param progress The progress % (0.0 to 1.0) + */ +extern GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, float progress); + +/** + * Hides the progress bar in the icon + * @param windowhandle The handle to the window + */ +extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle); + + /*************************************************************************************** ** N-degree of freedom device management functionality ***************************************************************************************/ diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index a024b2b51e5..83757b17e8b 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -234,6 +234,21 @@ public: */ virtual const GHOST_TabletData* GetTabletData() = 0; + /*************************************************************************************** + ** Progress bar functionality + ***************************************************************************************/ + + /** + * Sets the progress bar value displayed in the window/application icon + * @param progress The progress % + */ + virtual GHOST_TSuccess setProgressBar(float progress) = 0; + + /** + * Hides the progress bar in the icon + */ + virtual GHOST_TSuccess endProgressBar() = 0; + /*************************************************************************************** ** Cursor management functionality ***************************************************************************************/ diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 44b361d21e4..9da20200f63 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -248,6 +248,21 @@ GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_Eve return system->addEventConsumer((GHOST_CallbackEventConsumer*)consumerhandle); } +GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle,float progress) +{ + GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; + + return window->setProgressBar(progress); +} + +GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle) +{ + GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; + + return window->endProgressBar(); +} + + int GHOST_OpenNDOF(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle, GHOST_NDOFLibraryInit_fp setNdofLibraryInit, GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown, diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index e1d0d40e225..374b620c348 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -53,6 +53,8 @@ GHOST_Window::GHOST_Window( m_isUnsavedChanges = false; m_canAcceptDragOperation = false; + m_progressBarVisible = false; + m_cursorGrabAccumPos[0] = 0; m_cursorGrabAccumPos[1] = 0; diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index bec9cecc830..d4d53787357 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -191,6 +191,17 @@ public: */ virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds); + /** + * Sets the progress bar value displayed in the window/application icon + * @param progress The progress % (0.0 to 1.0) + */ + virtual GHOST_TSuccess setProgressBar(float progress) {return GHOST_kFailure;}; + + /** + * Hides the progress bar in the icon + */ + virtual GHOST_TSuccess endProgressBar() {return GHOST_kFailure;}; + /** * Tells if the ongoing drag'n'drop object can be accepted upon mouse drop */ @@ -313,6 +324,9 @@ protected: /** The current shape of the cursor */ GHOST_TStandardCursor m_cursorShape; + /** The presence of progress indicator with the application icon */ + bool m_progressBarVisible; + /** The acceptance of the "drop candidate" of the current drag'n'drop operation */ bool m_canAcceptDragOperation; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index cb27ee4e83e..7948e88e1ab 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -226,6 +226,17 @@ public: GHOST_TabletData& GetCocoaTabletData() { return m_tablet; } + + /** + * Sets the progress bar value displayed in the window/application icon + * @param progress The progress % (0.0 to 1.0) + */ + virtual GHOST_TSuccess setProgressBar(float progress); + + /** + * Hides the progress bar icon + */ + virtual GHOST_TSuccess endProgressBar(); protected: /** * Tries to install a rendering context in this window. @@ -291,14 +302,6 @@ protected: NSCursor* m_customCursor; GHOST_TabletData m_tablet; - - /** - * The width/height of the size rectangle in the lower right corner of a - * Mac/Carbon window. This is also the height of the gutter area. - */ -#ifdef GHOST_DRAW_CARBON_GUTTER - static const GHOST_TInt32 s_sizeRectSize; -#endif // GHOST_DRAW_CARBON_GUTTER }; #endif // _GHOST_WINDOW_COCOA_H_ diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 6dc2fa5a745..abcb8bcd5cc 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -1020,6 +1020,66 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate() return GHOST_kSuccess; } +#pragma mark Progress bar + +GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if ((progress >=0.0) && (progress <=1.0)) { + NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; + + [dockIcon lockFocus]; + NSRect progressBox = {{4, 4}, {120, 16}}; + + [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0]; + + // Track & Outline + [[NSColor blackColor] setFill]; + NSRectFill(progressBox); + + [[NSColor whiteColor] set]; + NSFrameRect(progressBox); + + // Progress fill + progressBox = NSInsetRect(progressBox, 1, 1); + [[NSColor knobColor] setFill]; + progressBox.size.width = progressBox.size.width * progress; + NSRectFill(progressBox); + + [dockIcon unlockFocus]; + + [NSApp setApplicationIconImage:dockIcon]; + [dockIcon release]; + + m_progressBarVisible = true; + } + + [pool drain]; + return GHOST_kSuccess; +} + + +GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() +{ + if (!m_progressBarVisible) return GHOST_kFailure; + m_progressBarVisible = false; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; + [dockIcon lockFocus]; + [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0]; + [dockIcon unlockFocus]; + [NSApp setApplicationIconImage:dockIcon]; + [dockIcon release]; + + [pool drain]; + return GHOST_kSuccess; +} + + + #pragma mark Cursor handling void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 40186f40e9d..2b159daf6a1 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -324,5 +324,9 @@ void WM_jobs_stop_all(struct wmWindowManager *wm); char *WM_clipboard_text_get(int selection); void WM_clipboard_text_set(char *buf, int selection); + /* progress */ +void WM_progress_set(struct wmWindow *win, float progress); +void WM_progress_clear(struct wmWindow *win); + #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index a92a3d746ad..e7df703ba79 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -381,6 +381,9 @@ void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt) void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) { wmJob *steve= wm->jobs.first, *stevenext; + float total_progress= 0.f; + float jobs_progress=0; + for(; steve; steve= stevenext) { stevenext= steve->next; @@ -434,6 +437,10 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) BLI_remlink(&wm->jobs, steve); MEM_freeN(steve); } + } else if (steve->flag & WM_JOB_PROGRESS) { + /* accumulate global progress for running jobs */ + jobs_progress++; + total_progress += steve->progress; } } else if(steve->suspended) { @@ -441,5 +448,13 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) } } } + + /* if there are running jobs, set the global progress indicator */ + if (jobs_progress > 0) { + float progress = total_progress / (float)jobs_progress; + WM_progress_set(wm->winactive, progress); + } else { + WM_progress_clear(wm->winactive); + } } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index b4270aa9a94..b730d1a6483 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1018,6 +1018,18 @@ void WM_clipboard_text_set(char *buf, int selection) #endif } +/* ******************* progress bar **************** */ + +void WM_progress_set(wmWindow *win, float progress) +{ + GHOST_SetProgressBar(win->ghostwin, progress); +} + +void WM_progress_clear(wmWindow *win) +{ + GHOST_EndProgressBar(win->ghostwin); +} + /* ************************************ */ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r)