[Scummvm-cvs-logs] scummvm master -> 6d7fcdd2b544fa4eb29988bd627af94aa8238d6c

criezy criezy at scummvm.org
Sun Feb 23 23:01:39 CET 2014


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6d7fcdd2b5 OSX: Implement TaskbarManager for Mac OS X


Commit: 6d7fcdd2b544fa4eb29988bd627af94aa8238d6c
    https://github.com/scummvm/scummvm/commit/6d7fcdd2b544fa4eb29988bd627af94aa8238d6c
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2014-02-23T13:54:47-08:00

Commit Message:
OSX: Implement TaskbarManager for Mac OS X

This implements count badge, progress bar, and icon overlay.
It uses the NSDockTile API which is available since OS X 10.5.
The code compiles and run on older system but without doing
anything.

Changed paths:
  A backends/taskbar/macosx/macosx-taskbar.h
  A backends/taskbar/macosx/macosx-taskbar.mm
    backends/module.mk
    backends/platform/sdl/macosx/macosx.cpp
    backends/platform/sdl/macosx/macosx.h
    configure



diff --git a/backends/module.mk b/backends/module.mk
index 1222d9a..34e2928 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -97,7 +97,8 @@ ifdef MACOSX
 MODULE_OBJS += \
 	midi/coreaudio.o \
 	midi/coremidi.o \
-	updates/macosx/macosx-updates.o
+	updates/macosx/macosx-updates.o \
+	taskbar/macosx/macosx-taskbar.o
 endif
 
 ifdef WIN32
diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp
index 301dc44..924e33b 100644
--- a/backends/platform/sdl/macosx/macosx.cpp
+++ b/backends/platform/sdl/macosx/macosx.cpp
@@ -31,6 +31,7 @@
 #include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h"
 #include "backends/platform/sdl/macosx/appmenu_osx.h"
 #include "backends/updates/macosx/macosx-updates.h"
+#include "backends/taskbar/macosx/macosx-taskbar.h"
 
 #include "common/archive.h"
 #include "common/config-manager.h"
@@ -45,6 +46,16 @@ OSystem_MacOSX::OSystem_MacOSX()
 	OSystem_POSIX("Library/Preferences/ScummVM Preferences") {
 }
 
+void OSystem_MacOSX::init() {
+#if defined(USE_TASKBAR)
+	// Initialize taskbar manager
+	_taskbarManager = new MacOSXTaskbarManager();
+#endif
+	
+	// Invoke parent implementation of this method
+	OSystem_POSIX::init();
+}
+
 void OSystem_MacOSX::initBackend() {
 	// Create the mixer manager
 	if (_mixer == 0) {
diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h
index e5a72bf..50cef60 100644
--- a/backends/platform/sdl/macosx/macosx.h
+++ b/backends/platform/sdl/macosx/macosx.h
@@ -35,6 +35,7 @@ public:
 
 	virtual Common::String getSystemLanguage() const;
 
+	virtual void init();
 	virtual void initBackend();
 	virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
 	virtual void setupIcon();
diff --git a/backends/taskbar/macosx/macosx-taskbar.h b/backends/taskbar/macosx/macosx-taskbar.h
new file mode 100644
index 0000000..5d5b9d0
--- /dev/null
+++ b/backends/taskbar/macosx/macosx-taskbar.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKEND_MACOSX_TASKBAR_H
+#define BACKEND_MACOSX_TASKBAR_H
+
+#if defined(MACOSX) && defined(USE_TASKBAR)
+
+#include "common/str.h"
+#include "common/taskbar.h"
+
+class MacOSXTaskbarManager : public Common::TaskbarManager {
+public:
+	MacOSXTaskbarManager();
+	virtual ~MacOSXTaskbarManager();
+
+	virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
+	virtual void setProgressValue(int completed, int total);
+	virtual void setProgressState(TaskbarProgressState state);
+	virtual void setCount(int count);
+	virtual void notifyError();
+	virtual void clearError();
+	
+private:
+	Common::String getIconPath(const Common::String&);
+
+	void initApplicationIconView();
+	void clearApplicationIconView();
+	
+	void initOverlayIconView();
+	void clearOverlayIconView();
+	
+	double _progress;
+};
+
+#endif
+
+#endif // BACKEND_MACOSX_TASKBAR_H
diff --git a/backends/taskbar/macosx/macosx-taskbar.mm b/backends/taskbar/macosx/macosx-taskbar.mm
new file mode 100644
index 0000000..ae087df
--- /dev/null
+++ b/backends/taskbar/macosx/macosx-taskbar.mm
@@ -0,0 +1,238 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
+
+#if defined(MACOSX) && defined(USE_TASKBAR)
+
+// NSDockTile was introduced with Mac OS X 10.5.
+// Try provide backward compatibility by avoiding NSDockTile symbols.
+
+// TODO: Implement recent list, maybe as a custom menu on dock tile when app is not running
+// See Dock Tile plug-in at https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/CreatingaDockTilePlug-in/CreatingaDockTilePlug-in.html
+
+#include "backends/taskbar/macosx/macosx-taskbar.h"
+#include "common/config-manager.h"
+#include "common/file.h"
+
+#include <AppKit/NSApplication.h>
+#include <AppKit/NSImage.h>
+#include <Foundation/NSString.h>
+#include <AppKit/NSImageView.h>
+#include <AppKit/NSColor.h>
+#include <AppKit/NSBezierPath.h>
+#include <CoreFoundation/CFString.h>
+
+id _dockTile;
+NSImageView *_applicationIconView;
+NSImageView *_overlayIconView;
+
+// Using a NSProgressIndicator as a sub-view of the NSDockTile view does not work properly.
+// The progress indicator is grayed out and display no progress. So instead the bar is drawn
+// manually, which is a bit more work :(
+
+MacOSXTaskbarManager::MacOSXTaskbarManager() : _progress(-1.0) {
+	if ([NSApp respondsToSelector:@selector(dockTile)])
+		_dockTile = [NSApp dockTile];
+	_applicationIconView = nil;
+	_overlayIconView = nil;
+}
+
+MacOSXTaskbarManager::~MacOSXTaskbarManager() {
+	clearApplicationIconView();
+}
+
+void MacOSXTaskbarManager::initApplicationIconView() {
+	if (_dockTile == nil)
+		return;
+	if (_applicationIconView == nil) {
+		_applicationIconView = [[NSImageView alloc] init];
+		[_applicationIconView setImage:[NSApp applicationIconImage]];
+		[_dockTile performSelector:@selector(setContentView:) withObject:_applicationIconView];
+	}
+}
+
+void MacOSXTaskbarManager::clearApplicationIconView() {
+	if (_dockTile == nil)
+		return;
+	[_dockTile performSelector:@selector(setContentView:) withObject:nil];
+	[_applicationIconView release];
+	_applicationIconView = nil;
+}
+
+void MacOSXTaskbarManager::initOverlayIconView() {
+	if (_dockTile == nil)
+		return;
+	if (_overlayIconView == nil) {
+		const double overlaySize = 0.75;
+		initApplicationIconView();
+		NSSize size = [_applicationIconView frame].size;
+		_overlayIconView = [[NSImageView alloc] initWithFrame:NSMakeRect(size.width * (1.0-overlaySize), 0.0f, size.width * overlaySize, size.height * overlaySize)];
+		[_overlayIconView setImageAlignment:NSImageAlignBottomRight];
+		[_applicationIconView addSubview:_overlayIconView];
+		[_overlayIconView release];
+	}
+}
+
+void MacOSXTaskbarManager::clearOverlayIconView() {
+	if (_progress < 0.0)
+		clearApplicationIconView();
+	else
+		[_overlayIconView removeFromSuperview];
+	_overlayIconView = nil;
+}
+
+void MacOSXTaskbarManager::setOverlayIcon(const Common::String &name, const Common::String &description) {
+	if (_dockTile == nil)
+		return;
+
+    if (name.empty()) {
+		clearOverlayIconView();
+		[_dockTile performSelector:@selector(display)];
+		return;
+	}
+	
+	Common::String path = getIconPath(name);
+	if (path.empty())
+		return;
+	
+	initOverlayIconView();
+
+	CFStringRef imageFile = CFStringCreateWithCString(0, path.c_str(), kCFStringEncodingASCII);
+	NSImage* image = [[NSImage alloc] initWithContentsOfFile:(NSString *)imageFile];
+	[_overlayIconView setImage:image];
+	[image release];
+	CFRelease(imageFile);
+
+	[_dockTile performSelector:@selector(display)];
+}
+
+void MacOSXTaskbarManager::setProgressValue(int completed, int total) {
+	if (_dockTile == nil)
+		return;
+
+	if (total > 0)
+		_progress = (double)completed / (double)total;
+	else if (_progress < 0)
+		_progress = 0.0;
+	
+	 NSImage *mainIcon = [[NSApp applicationIconImage] copy];
+	double barSize = [mainIcon size].width;
+	double progressSize = barSize * _progress;
+	[mainIcon lockFocus];
+	[[NSColor colorWithDeviceRed:(40.0/255.0) green:(120.0/255.0) blue:(255.0/255.0) alpha:0.78] set];
+	[NSBezierPath fillRect:NSMakeRect(0, 0, progressSize, 11)];
+	[[NSColor colorWithDeviceRed:(241.0/255.0) green:(241.0/255.0) blue:(241.0/255.0) alpha:0.78] set];
+	[NSBezierPath fillRect:NSMakeRect(progressSize, 0, barSize-progressSize, 11)];
+	[mainIcon unlockFocus];
+
+	initApplicationIconView();
+	[_applicationIconView setImage:mainIcon];
+	[mainIcon release];
+	
+	[_dockTile performSelector:@selector(display)];
+}
+
+void MacOSXTaskbarManager::setProgressState(TaskbarProgressState state) {
+	if (_dockTile == nil)
+		return;
+
+	// Only support two states: visible and not visible.
+	if (state == kTaskbarNoProgress) {
+		_progress = -1.0;
+		if (_overlayIconView == nil)
+			clearApplicationIconView();
+		else if (_applicationIconView != nil)
+			[_applicationIconView setImage:[NSApp applicationIconImage]];
+		return;
+	}
+
+	setProgressValue(-1, -1);
+}
+
+void MacOSXTaskbarManager::setCount(int count) {
+	if (_dockTile == nil)
+		return;
+
+	if (count > 0)
+		[_dockTile performSelector:@selector(setBadgeLabel:) withObject:[NSString stringWithFormat:@"%d", count]];
+	else
+		[_dockTile performSelector:@selector(setBadgeLabel:) withObject:nil];
+}
+
+void MacOSXTaskbarManager::notifyError() {
+	if (_dockTile == nil)
+		return;
+
+	// NSImageNameCaution was introduced in 10.6.
+	// For compatibility with older systems we should use something else (e.g. overlay label
+	// or our own icon).
+	//initOverlayIconView();
+	//[_overlayIconView setImage:[NSImage imageNamed:NSImageNameCaution]];
+	//[_dockTile performSelector:@selector(display)];
+}
+
+void MacOSXTaskbarManager::clearError() {
+	if (_dockTile == nil)
+		return;
+
+    clearOverlayIconView();
+	[_dockTile performSelector:@selector(display)];
+	return;
+}
+
+Common::String MacOSXTaskbarManager::getIconPath(const Common::String& target) {
+	// We first try to look for a iconspath configuration variable then
+	// fallback to the extra path
+	//
+	// Icons can be either in a subfolder named "icons" or directly in the path
+	
+	Common::String iconsPath = ConfMan.get("iconspath");
+	Common::String extraPath = ConfMan.get("extrapath");
+	
+#define TRY_ICON_PATH(path) { \
+Common::FSNode node((path)); \
+if (node.exists()) \
+return (path); \
+}
+	
+	if (!iconsPath.empty()) {
+		TRY_ICON_PATH(iconsPath + "/" + target + ".png");
+		TRY_ICON_PATH(iconsPath + "/" + ConfMan.get("gameid") + ".png");
+		TRY_ICON_PATH(iconsPath + "/icons/" + target + ".png");
+		TRY_ICON_PATH(iconsPath + "/icons/" + ConfMan.get("gameid") + ".png");
+	}
+	
+	if (!extraPath.empty()) {
+		TRY_ICON_PATH(extraPath + "/" + target + ".png");
+		TRY_ICON_PATH(extraPath + "/" + ConfMan.get("gameid") + ".png");
+		TRY_ICON_PATH(extraPath + "/icons/" + target + ".png");
+		TRY_ICON_PATH(extraPath + "/icons/" + ConfMan.get("gameid") + ".png");
+	}
+	
+	return "";
+}
+
+
+#endif
diff --git a/configure b/configure
index 567cb09..5499cec 100755
--- a/configure
+++ b/configure
@@ -4001,6 +4001,10 @@ else
 		echo "win32"
 		_taskbar=yes
 		;;
+	darwin*)
+		echo "osx"
+		_taskbar=yes
+		;;
 	*)
 		if test "$_libunity" = yes; then
 			echo "unity"






More information about the Scummvm-git-logs mailing list