├── .gitignore ├── example ├── Makefile ├── Project.xcconfig ├── bin │ └── data │ │ └── .gitkeep ├── config.make ├── example.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── Debug.xcscheme │ │ └── Release.xcscheme ├── openFrameworks-Info.plist └── src │ └── ofApp.cpp ├── ofxaddons_thumbnail.png ├── readme.md └── src ├── ofxDisplayLayout.h └── ofxDisplayLayout.mm /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | display.txt 3 | 4 | # Some general ignore patterns 5 | build/ 6 | obj/ 7 | *.o 8 | Debug*/ 9 | Release*/ 10 | *.mode* 11 | *.app/ 12 | *.pyc 13 | .svn/ 14 | 15 | 16 | #XCode 17 | *.pbxuser 18 | *.perspective 19 | *.perspectivev3 20 | *.mode1v3 21 | *.mode2v3 22 | #XCode 4 23 | xcuserdata 24 | *.xcworkspace 25 | 26 | #Code::Blocks 27 | *.depend 28 | *.layout 29 | 30 | #Visual Studio 31 | *.sdf 32 | *.opensdf 33 | *.suo 34 | ipch/ 35 | 36 | #Eclipse 37 | .metadata 38 | local.properties 39 | .externalToolBuilders 40 | 41 | 42 | # OS-specific ignore patterns 43 | 44 | #Linux 45 | *~ 46 | # KDE 47 | .directory 48 | 49 | #OSX 50 | .DS_Store 51 | *.swp 52 | *~.nib 53 | # Thumbnails 54 | ._* 55 | 56 | #Windows 57 | # Windows image file caches 58 | Thumbs.db 59 | # Folder config file 60 | Desktop.ini 61 | 62 | #Android 63 | .csettings 64 | /libs/openFrameworksCompiled/project/android/paths.make 65 | 66 | # Miscellaneous 67 | .mailmap -------------------------------------------------------------------------------- /example/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=../../.. 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example/Project.xcconfig: -------------------------------------------------------------------------------- 1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT. 2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED 3 | OF_PATH = ../../.. 4 | 5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE 6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig" 7 | 8 | //ICONS - NEW IN 0072 9 | ICON_NAME_DEBUG = icon-debug.icns 10 | ICON_NAME_RELEASE = icon.icns 11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/ 12 | 13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to: 14 | //ICON_FILE_PATH = bin/data/ 15 | 16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS) 17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) 18 | -------------------------------------------------------------------------------- /example/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/motoishmz/ofxDisplayLayout/721b282e72ec27409b7c1aa3eead00eb7a727cfd/example/bin/data/.gitkeep -------------------------------------------------------------------------------- /example/config.make: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # CONFIGURE PROJECT MAKEFILE (optional) 3 | # This file is where we make project specific configurations. 4 | ################################################################################ 5 | 6 | ################################################################################ 7 | # OF ROOT 8 | # The location of your root openFrameworks installation 9 | # (default) OF_ROOT = ../../.. 10 | ################################################################################ 11 | # OF_ROOT = ../../.. 12 | 13 | ################################################################################ 14 | # PROJECT ROOT 15 | # The location of the project - a starting place for searching for files 16 | # (default) PROJECT_ROOT = . (this directory) 17 | # 18 | ################################################################################ 19 | # PROJECT_ROOT = . 20 | 21 | ################################################################################ 22 | # PROJECT SPECIFIC CHECKS 23 | # This is a project defined section to create internal makefile flags to 24 | # conditionally enable or disable the addition of various features within 25 | # this makefile. For instance, if you want to make changes based on whether 26 | # GTK is installed, one might test that here and create a variable to check. 27 | ################################################################################ 28 | # None 29 | 30 | ################################################################################ 31 | # PROJECT EXTERNAL SOURCE PATHS 32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder. 33 | # Like source folders in the PROJECT_ROOT, these paths are subject to 34 | # exlclusion via the PROJECT_EXLCUSIONS list. 35 | # 36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) 37 | # 38 | # Note: Leave a leading space when adding list items with the += operator 39 | ################################################################################ 40 | # PROJECT_EXTERNAL_SOURCE_PATHS = 41 | 42 | ################################################################################ 43 | # PROJECT EXCLUSIONS 44 | # These makefiles assume that all folders in your current project directory 45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations 46 | # to look for source code. The any folders or files that match any of the 47 | # items in the PROJECT_EXCLUSIONS list below will be ignored. 48 | # 49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete 50 | # string unless teh user adds a wildcard (%) operator to match subdirectories. 51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is 52 | # treated literally. 53 | # 54 | # (default) PROJECT_EXCLUSIONS = (blank) 55 | # 56 | # Will automatically exclude the following: 57 | # 58 | # $(PROJECT_ROOT)/bin% 59 | # $(PROJECT_ROOT)/obj% 60 | # $(PROJECT_ROOT)/%.xcodeproj 61 | # 62 | # Note: Leave a leading space when adding list items with the += operator 63 | ################################################################################ 64 | # PROJECT_EXCLUSIONS = 65 | 66 | ################################################################################ 67 | # PROJECT LINKER FLAGS 68 | # These flags will be sent to the linker when compiling the executable. 69 | # 70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs 71 | # 72 | # Note: Leave a leading space when adding list items with the += operator 73 | ################################################################################ 74 | 75 | # Currently, shared libraries that are needed are copied to the 76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to 77 | # add a runtime path to search for those shared libraries, since they aren't 78 | # incorporated directly into the final executable application binary. 79 | # TODO: should this be a default setting? 80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs 81 | 82 | ################################################################################ 83 | # PROJECT DEFINES 84 | # Create a space-delimited list of DEFINES. The list will be converted into 85 | # CFLAGS with the "-D" flag later in the makefile. 86 | # 87 | # (default) PROJECT_DEFINES = (blank) 88 | # 89 | # Note: Leave a leading space when adding list items with the += operator 90 | ################################################################################ 91 | # PROJECT_DEFINES = 92 | 93 | ################################################################################ 94 | # PROJECT CFLAGS 95 | # This is a list of fully qualified CFLAGS required when compiling for this 96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS 97 | # defined in your platform specific core configuration files. These flags are 98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. 99 | # 100 | # (default) PROJECT_CFLAGS = (blank) 101 | # 102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in 103 | # your platform specific configuration file will be applied by default and 104 | # further flags here may not be needed. 105 | # 106 | # Note: Leave a leading space when adding list items with the += operator 107 | ################################################################################ 108 | # PROJECT_CFLAGS = 109 | 110 | ################################################################################ 111 | # PROJECT OPTIMIZATION CFLAGS 112 | # These are lists of CFLAGS that are target-specific. While any flags could 113 | # be conditionally added, they are usually limited to optimization flags. 114 | # These flags are added BEFORE the PROJECT_CFLAGS. 115 | # 116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. 117 | # 118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) 119 | # 120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. 121 | # 122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) 123 | # 124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the 125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration 126 | # file will be applied by default and further optimization flags here may not 127 | # be needed. 128 | # 129 | # Note: Leave a leading space when adding list items with the += operator 130 | ################################################################################ 131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE = 132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG = 133 | 134 | ################################################################################ 135 | # PROJECT COMPILERS 136 | # Custom compilers can be set for CC and CXX 137 | # (default) PROJECT_CXX = (blank) 138 | # (default) PROJECT_CC = (blank) 139 | # Note: Leave a leading space when adding list items with the += operator 140 | ################################################################################ 141 | # PROJECT_CXX = 142 | # PROJECT_CC = 143 | -------------------------------------------------------------------------------- /example/example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9AB63D361B33FC50008CA372 /* ofxDisplayLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9AB63D351B33FC50008CA372 /* ofxDisplayLayout.mm */; }; 11 | E4328149138ABC9F0047C5CB /* openFrameworksDebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4328148138ABC890047C5CB /* openFrameworksDebug.a */; }; 12 | E4B69E210A3A1BDC003C02F2 /* ofApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXContainerItemProxy section */ 16 | E4328147138ABC890047C5CB /* PBXContainerItemProxy */ = { 17 | isa = PBXContainerItemProxy; 18 | containerPortal = E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */; 19 | proxyType = 2; 20 | remoteGlobalIDString = E4B27C1510CBEB8E00536013; 21 | remoteInfo = openFrameworks; 22 | }; 23 | E4EEB9AB138B136A00A80321 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */; 26 | proxyType = 1; 27 | remoteGlobalIDString = E4B27C1410CBEB8E00536013; 28 | remoteInfo = openFrameworks; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXCopyFilesBuildPhase section */ 33 | E4C2427710CC5ABF004149E2 /* CopyFiles */ = { 34 | isa = PBXCopyFilesBuildPhase; 35 | buildActionMask = 2147483647; 36 | dstPath = ""; 37 | dstSubfolderSpec = 10; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXCopyFilesBuildPhase section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 9AB63D341B33FC50008CA372 /* ofxDisplayLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxDisplayLayout.h; sourceTree = ""; }; 46 | 9AB63D351B33FC50008CA372 /* ofxDisplayLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ofxDisplayLayout.mm; sourceTree = ""; }; 47 | E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = openFrameworksLib.xcodeproj; path = ../../../libs/openFrameworksCompiled/project/osx/openFrameworksLib.xcodeproj; sourceTree = SOURCE_ROOT; }; 48 | E4B69B5B0A3A1756003C02F2 /* exampleDebug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = exampleDebug.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ofApp.cpp; path = src/ofApp.cpp; sourceTree = SOURCE_ROOT; }; 50 | E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "openFrameworks-Info.plist"; sourceTree = ""; }; 51 | E4EB691F138AFCF100A09F29 /* CoreOF.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CoreOF.xcconfig; path = ../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig; sourceTree = SOURCE_ROOT; }; 52 | E4EB6923138AFD0F00A09F29 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Project.xcconfig; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | E4B69B590A3A1756003C02F2 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | E4328149138ABC9F0047C5CB /* openFrameworksDebug.a in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 9AB63D1B1B33FBC3008CA372 /* ofxDisplayLayout */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 9AB63D331B33FC50008CA372 /* src */, 71 | ); 72 | name = ofxDisplayLayout; 73 | path = ..; 74 | sourceTree = ""; 75 | }; 76 | 9AB63D331B33FC50008CA372 /* src */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 9AB63D341B33FC50008CA372 /* ofxDisplayLayout.h */, 80 | 9AB63D351B33FC50008CA372 /* ofxDisplayLayout.mm */, 81 | ); 82 | path = src; 83 | sourceTree = ""; 84 | }; 85 | BB4B014C10F69532006C3DED /* addons */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 9AB63D1B1B33FBC3008CA372 /* ofxDisplayLayout */, 89 | ); 90 | name = addons; 91 | sourceTree = ""; 92 | }; 93 | E4328144138ABC890047C5CB /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | E4328148138ABC890047C5CB /* openFrameworksDebug.a */, 97 | ); 98 | name = Products; 99 | sourceTree = ""; 100 | }; 101 | E4B69B4A0A3A1720003C02F2 = { 102 | isa = PBXGroup; 103 | children = ( 104 | E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */, 105 | E4EB6923138AFD0F00A09F29 /* Project.xcconfig */, 106 | E4B69E1C0A3A1BDC003C02F2 /* src */, 107 | E4EEC9E9138DF44700A80321 /* openFrameworks */, 108 | BB4B014C10F69532006C3DED /* addons */, 109 | E4B69B5B0A3A1756003C02F2 /* exampleDebug.app */, 110 | ); 111 | sourceTree = ""; 112 | }; 113 | E4B69E1C0A3A1BDC003C02F2 /* src */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */, 117 | ); 118 | path = src; 119 | sourceTree = SOURCE_ROOT; 120 | }; 121 | E4EEC9E9138DF44700A80321 /* openFrameworks */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | E4EB691F138AFCF100A09F29 /* CoreOF.xcconfig */, 125 | E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */, 126 | ); 127 | name = openFrameworks; 128 | sourceTree = ""; 129 | }; 130 | /* End PBXGroup section */ 131 | 132 | /* Begin PBXNativeTarget section */ 133 | E4B69B5A0A3A1756003C02F2 /* example */ = { 134 | isa = PBXNativeTarget; 135 | buildConfigurationList = E4B69B5F0A3A1757003C02F2 /* Build configuration list for PBXNativeTarget "example" */; 136 | buildPhases = ( 137 | E4B69B580A3A1756003C02F2 /* Sources */, 138 | E4B69B590A3A1756003C02F2 /* Frameworks */, 139 | E4B6FFFD0C3F9AB9008CF71C /* ShellScript */, 140 | E4C2427710CC5ABF004149E2 /* CopyFiles */, 141 | ); 142 | buildRules = ( 143 | ); 144 | dependencies = ( 145 | E4EEB9AC138B136A00A80321 /* PBXTargetDependency */, 146 | ); 147 | name = example; 148 | productName = myOFApp; 149 | productReference = E4B69B5B0A3A1756003C02F2 /* exampleDebug.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | E4B69B4C0A3A1720003C02F2 /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 0600; 159 | }; 160 | buildConfigurationList = E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "example" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = English; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | English, 166 | Japanese, 167 | French, 168 | German, 169 | ); 170 | mainGroup = E4B69B4A0A3A1720003C02F2; 171 | productRefGroup = E4B69B4A0A3A1720003C02F2; 172 | projectDirPath = ""; 173 | projectReferences = ( 174 | { 175 | ProductGroup = E4328144138ABC890047C5CB /* Products */; 176 | ProjectRef = E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */; 177 | }, 178 | ); 179 | projectRoot = ""; 180 | targets = ( 181 | E4B69B5A0A3A1756003C02F2 /* example */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXReferenceProxy section */ 187 | E4328148138ABC890047C5CB /* openFrameworksDebug.a */ = { 188 | isa = PBXReferenceProxy; 189 | fileType = archive.ar; 190 | path = openFrameworksDebug.a; 191 | remoteRef = E4328147138ABC890047C5CB /* PBXContainerItemProxy */; 192 | sourceTree = BUILT_PRODUCTS_DIR; 193 | }; 194 | /* End PBXReferenceProxy section */ 195 | 196 | /* Begin PBXShellScriptBuildPhase section */ 197 | E4B6FFFD0C3F9AB9008CF71C /* ShellScript */ = { 198 | isa = PBXShellScriptBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | inputPaths = ( 203 | ); 204 | outputPaths = ( 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | shellPath = /bin/sh; 208 | shellScript = "cp -f ../../../libs/fmodex/lib/osx/libfmodex.dylib \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/libfmodex.dylib\"; install_name_tool -change ./libfmodex.dylib @executable_path/libfmodex.dylib \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME\";\nmkdir -p \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/\"\ncp -f \"$ICON_FILE\" \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/\"\n"; 209 | }; 210 | /* End PBXShellScriptBuildPhase section */ 211 | 212 | /* Begin PBXSourcesBuildPhase section */ 213 | E4B69B580A3A1756003C02F2 /* Sources */ = { 214 | isa = PBXSourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 9AB63D361B33FC50008CA372 /* ofxDisplayLayout.mm in Sources */, 218 | E4B69E210A3A1BDC003C02F2 /* ofApp.cpp in Sources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXSourcesBuildPhase section */ 223 | 224 | /* Begin PBXTargetDependency section */ 225 | E4EEB9AC138B136A00A80321 /* PBXTargetDependency */ = { 226 | isa = PBXTargetDependency; 227 | name = openFrameworks; 228 | targetProxy = E4EEB9AB138B136A00A80321 /* PBXContainerItemProxy */; 229 | }; 230 | /* End PBXTargetDependency section */ 231 | 232 | /* Begin XCBuildConfiguration section */ 233 | E4B69B4E0A3A1720003C02F2 /* Debug */ = { 234 | isa = XCBuildConfiguration; 235 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */; 236 | buildSettings = { 237 | CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/"; 238 | COPY_PHASE_STRIP = NO; 239 | DEAD_CODE_STRIPPING = YES; 240 | GCC_AUTO_VECTORIZATION = YES; 241 | GCC_ENABLE_SSE3_EXTENSIONS = YES; 242 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; 243 | GCC_INLINES_ARE_PRIVATE_EXTERN = NO; 244 | GCC_OPTIMIZATION_LEVEL = 0; 245 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 246 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; 247 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO; 248 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO; 249 | GCC_WARN_UNINITIALIZED_AUTOS = NO; 250 | GCC_WARN_UNUSED_VALUE = NO; 251 | GCC_WARN_UNUSED_VARIABLE = NO; 252 | MACOSX_DEPLOYMENT_TARGET = 10.8; 253 | ONLY_ACTIVE_ARCH = YES; 254 | OTHER_CPLUSPLUSFLAGS = ( 255 | "-D__MACOSX_CORE__", 256 | "-lpthread", 257 | "-mtune=native", 258 | ); 259 | SDKROOT = macosx; 260 | }; 261 | name = Debug; 262 | }; 263 | E4B69B4F0A3A1720003C02F2 /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */; 266 | buildSettings = { 267 | CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/"; 268 | COPY_PHASE_STRIP = YES; 269 | DEAD_CODE_STRIPPING = YES; 270 | GCC_AUTO_VECTORIZATION = YES; 271 | GCC_ENABLE_SSE3_EXTENSIONS = YES; 272 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; 273 | GCC_INLINES_ARE_PRIVATE_EXTERN = NO; 274 | GCC_OPTIMIZATION_LEVEL = 3; 275 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 276 | GCC_UNROLL_LOOPS = YES; 277 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; 278 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO; 279 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO; 280 | GCC_WARN_UNINITIALIZED_AUTOS = NO; 281 | GCC_WARN_UNUSED_VALUE = NO; 282 | GCC_WARN_UNUSED_VARIABLE = NO; 283 | MACOSX_DEPLOYMENT_TARGET = 10.8; 284 | OTHER_CPLUSPLUSFLAGS = ( 285 | "-D__MACOSX_CORE__", 286 | "-lpthread", 287 | "-mtune=native", 288 | ); 289 | SDKROOT = macosx; 290 | }; 291 | name = Release; 292 | }; 293 | E4B69B600A3A1757003C02F2 /* Debug */ = { 294 | isa = XCBuildConfiguration; 295 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */; 296 | buildSettings = { 297 | ARCHS = "$(ARCHS_STANDARD)"; 298 | COMBINE_HIDPI_IMAGES = YES; 299 | COPY_PHASE_STRIP = NO; 300 | FRAMEWORK_SEARCH_PATHS = ( 301 | "$(inherited)", 302 | "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", 303 | ); 304 | FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../libs/glut/lib/osx\""; 305 | GCC_DYNAMIC_NO_PIC = NO; 306 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 307 | GCC_MODEL_TUNING = NONE; 308 | ICON = "$(ICON_NAME_DEBUG)"; 309 | ICON_FILE = "$(ICON_FILE_PATH)$(ICON)"; 310 | INFOPLIST_FILE = "openFrameworks-Info.plist"; 311 | INSTALL_PATH = "$(HOME)/Applications"; 312 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 313 | PRODUCT_NAME = exampleDebug; 314 | WRAPPER_EXTENSION = app; 315 | }; 316 | name = Debug; 317 | }; 318 | E4B69B610A3A1757003C02F2 /* Release */ = { 319 | isa = XCBuildConfiguration; 320 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */; 321 | buildSettings = { 322 | ARCHS = "$(ARCHS_STANDARD)"; 323 | COMBINE_HIDPI_IMAGES = YES; 324 | COPY_PHASE_STRIP = YES; 325 | FRAMEWORK_SEARCH_PATHS = ( 326 | "$(inherited)", 327 | "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", 328 | ); 329 | FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../libs/glut/lib/osx\""; 330 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 331 | GCC_MODEL_TUNING = NONE; 332 | ICON = "$(ICON_NAME_RELEASE)"; 333 | ICON_FILE = "$(ICON_FILE_PATH)$(ICON)"; 334 | INFOPLIST_FILE = "openFrameworks-Info.plist"; 335 | INSTALL_PATH = "$(HOME)/Applications"; 336 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 337 | PRODUCT_NAME = example; 338 | WRAPPER_EXTENSION = app; 339 | baseConfigurationReference = E4EB6923138AFD0F00A09F29; 340 | }; 341 | name = Release; 342 | }; 343 | /* End XCBuildConfiguration section */ 344 | 345 | /* Begin XCConfigurationList section */ 346 | E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "example" */ = { 347 | isa = XCConfigurationList; 348 | buildConfigurations = ( 349 | E4B69B4E0A3A1720003C02F2 /* Debug */, 350 | E4B69B4F0A3A1720003C02F2 /* Release */, 351 | ); 352 | defaultConfigurationIsVisible = 0; 353 | defaultConfigurationName = Release; 354 | }; 355 | E4B69B5F0A3A1757003C02F2 /* Build configuration list for PBXNativeTarget "example" */ = { 356 | isa = XCConfigurationList; 357 | buildConfigurations = ( 358 | E4B69B600A3A1757003C02F2 /* Debug */, 359 | E4B69B610A3A1757003C02F2 /* Release */, 360 | ); 361 | defaultConfigurationIsVisible = 0; 362 | defaultConfigurationName = Release; 363 | }; 364 | /* End XCConfigurationList section */ 365 | }; 366 | rootObject = E4B69B4C0A3A1720003C02F2 /* Project object */; 367 | } 368 | -------------------------------------------------------------------------------- /example/example.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /example/example.xcodeproj/xcshareddata/xcschemes/Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /example/openFrameworks-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | cc.openFrameworks.ofapp 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | CFBundleIconFile 20 | ${ICON} 21 | 22 | 23 | -------------------------------------------------------------------------------- /example/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | 3 | #include "ofxDisplayLayout.h" 4 | 5 | class ofApp : public ofBaseApp 6 | { 7 | 8 | ofxDisplayLayout manager; 9 | 10 | public: 11 | 12 | void setup() { 13 | ofSetLogLevel(OF_LOG_VERBOSE); 14 | } 15 | 16 | void draw() { 17 | 18 | stringstream report; 19 | report << "Press [s] to save current display order" << endl; 20 | report << "Press [l] to load settings, align displays" << endl; 21 | ofDrawBitmapString(report.str(), 20, 20); 22 | 23 | manager.debugDraw(300, 300); 24 | } 25 | 26 | void keyPressed(int key) { 27 | 28 | // use ofxDisplayLayout::ALIGN_HORIZONTAL or ofxDisplayLayout::ALIGN_VERTICAL 29 | 30 | if (key == 's') { 31 | if (!manager.save("display.txt", ofxDisplayLayout::ALIGN_HORIZONTAL)) { 32 | ofSystemAlertDialog("save failed."); 33 | }; 34 | } 35 | if (key == 'l') { 36 | if (!manager.load("display.txt", ofxDisplayLayout::ALIGN_HORIZONTAL)) { 37 | ofSystemAlertDialog("load failed."); 38 | }; 39 | } 40 | } 41 | }; 42 | 43 | 44 | 45 | #pragma mark - 46 | #pragma mark main 47 | int main(){ 48 | ofSetupOpenGL(1024, 780, OF_WINDOW); 49 | ofRunApp(new ofApp()); 50 | } 51 | -------------------------------------------------------------------------------- /ofxaddons_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/motoishmz/ofxDisplayLayout/721b282e72ec27409b7c1aa3eead00eb7a727cfd/ofxaddons_thumbnail.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## ofxDisplayLayout grabs the display unique ID, and aligns your displays vertically/horizontally 2 | 3 | !!!: This addon supports only Mac OS. 4 | !!!: Less than OF 0.9.0 is not supported since this addon uses C++11 features. 5 | 6 | (before alignment...) 7 | 8 | ![](https://41.media.tumblr.com/ab739141c067b09596b15f1c4231bb29/tumblr_nq6mdiK2lC1s2up8jo1_540.png) 9 | 10 | ofxDisplayLayout::*ALIGN_HORIZONTAL* 11 | 12 | ![](https://41.media.tumblr.com/55d5d0a387c0335654baca85365d6a2f/tumblr_nq6mdiK2lC1s2up8jo3_400.png) 13 | 14 | ofxDisplayLayout::*ALIGN_VERTICAL* 15 | 16 | ![](https://36.media.tumblr.com/0489db34974f70d866b67c9b0f44c3ce/tumblr_nq6mdiK2lC1s2up8jo2_400.png) 17 | 18 | 19 | ## Use case 20 | - When you want to make sure the order of displays connected to your Mac - for an installation which wakes up/shuts down automatically. 21 | 22 | 23 | ## Example 24 | - Arrange the display layout from SystemPreference by hand 25 | - Launch the example in this repo 26 | - Press [s] to save the order of the displays. `displas.txt` will be saved to the `bin/data` dir. It keeps the display order 27 | - Rearrange the display layout from SystemPreference by hand 28 | - Press [l] to load 29 | 30 | 31 | ## Demo movie 32 | - [https://instagram.com/p/4GhGW0LMyA/](https://instagram.com/p/4GhGW0LMyA/) 33 | - [https://instagram.com/p/4GhVAjrMyL/](https://instagram.com/p/4GhVAjrMyL/) 34 | - [https://instagram.com/p/4GhyxgrMyw/](https://instagram.com/p/4GhyxgrMyw/) 35 | 36 | 37 | ## Testers needed! 38 | 39 | ofxDisplayLayout is tested under the environment: 40 | 41 | MacBook Pro (Retina, 15-inch, Mid 2014) 42 | OS X 10.10.3 Yosemite 43 | + 44 | External monitor * 2 45 | 46 | Please send me a report if this addon works fine on... 47 | 48 | - MacPro + more than 3 monitors + wakes up/shut down automatically 49 | - Matrox TripleHead -------------------------------------------------------------------------------- /src/ofxDisplayLayout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ofRectangle.h" 6 | 7 | class ofxDisplayLayout{ 8 | 9 | public: 10 | 11 | typedef enum { 12 | UNKNOWN_DIRECTION = -1, 13 | ALIGN_HORIZONTAL = 0, 14 | ALIGN_VERTICAL, 15 | NUM_DIRECTIONS 16 | } Direction; 17 | 18 | ofxDisplayLayout(); 19 | bool save(std::string filepath = "display.txt", ofxDisplayLayout::Direction direction = ALIGN_HORIZONTAL) const; 20 | bool load(std::string filepath = "display.txt", ofxDisplayLayout::Direction direction = ALIGN_HORIZONTAL) const; 21 | void debugDraw(int x, int y, float scale = 0.1); 22 | 23 | private: 24 | 25 | std::vector getDisplayIds() const; 26 | bool arrange(std::vector display_ids, ofxDisplayLayout::Direction direction) const; 27 | 28 | bool isValidDirection(ofxDisplayLayout::Direction direction) const; 29 | bool isMainDisplay(unsigned int display_id) const; 30 | bool hasDisplay(unsigned int display_id) const; 31 | ofRectangle getDisplayBounds(unsigned int display_id) const; 32 | size_t getNumDisplay() const; 33 | }; 34 | 35 | 36 | inline ofxDisplayLayout::ofxDisplayLayout() { 37 | #ifndef TARGET_OSX 38 | ofSystemAlertDialog("Sorry! ofxDisplayLayout supports only MacOS."); 39 | #endif 40 | } 41 | 42 | inline bool ofxDisplayLayout::isValidDirection(ofxDisplayLayout::Direction direction) const { 43 | return UNKNOWN_DIRECTION < direction || direction < NUM_DIRECTIONS; 44 | } 45 | 46 | inline bool ofxDisplayLayout::isMainDisplay(unsigned int display_id) const { 47 | return CGMainDisplayID() == display_id; 48 | } 49 | 50 | inline bool ofxDisplayLayout::hasDisplay(unsigned int display_id) const { 51 | const vector display_ids = getDisplayIds(); 52 | return std::find(begin(display_ids), 53 | end(display_ids), 54 | display_id) != end(display_ids); 55 | } 56 | 57 | inline ofRectangle ofxDisplayLayout::getDisplayBounds(unsigned int display_id) const { 58 | const CGRect bounds = CGDisplayBounds(display_id); 59 | return ofRectangle(bounds.origin.x, 60 | bounds.origin.y, 61 | bounds.size.width, 62 | bounds.size.height); 63 | } 64 | 65 | inline size_t ofxDisplayLayout::getNumDisplay() const { 66 | return getDisplayIds().size(); 67 | } -------------------------------------------------------------------------------- /src/ofxDisplayLayout.mm: -------------------------------------------------------------------------------- 1 | #include "ofxDisplayLayout.h" 2 | #include "ofLog.h" 3 | #include "ofAppRunner.h" 4 | #include "ofGraphics.h" 5 | #include "ofSystemUtils.h" 6 | 7 | #import 8 | 9 | #pragma mark - 10 | #pragma mark public 11 | 12 | 13 | bool ofxDisplayLayout::save(std::string filepath, 14 | ofxDisplayLayout::Direction direction) const { 15 | 16 | const std::vector display_ids = getDisplayIds(); 17 | 18 | ofLogVerbose() << "ofxDisplayLayout found " << display_ids.size() << " displays." << endl; 19 | 20 | if (display_ids.size() < 2) { 21 | ofLogError() << "you don't need to arange display layout. aborted" << endl; 22 | return false; 23 | } 24 | 25 | //! sorting display order by alignment direction 26 | if (!isValidDirection(direction)) { 27 | ofLogError() << __PRETTY_FUNCTION__ << " invalid direction " << direction << "is passed. aborted"; 28 | return false; 29 | } 30 | 31 | struct Display { unsigned int id; ofRectangle bounds; }; 32 | std::vector displays; 33 | for (const auto & display_id: display_ids) { 34 | Display display; 35 | display.id = display_id; 36 | display.bounds = getDisplayBounds(display_id); 37 | displays.emplace_back(display); 38 | } 39 | 40 | std::sort(begin(displays), 41 | end(displays), 42 | [&](Display & lhs, Display & rhs){ 43 | assert(direction == ALIGN_VERTICAL || direction == ALIGN_HORIZONTAL); 44 | return (direction == ALIGN_HORIZONTAL) 45 | ? (lhs.bounds.x < rhs.bounds.x) 46 | : (lhs.bounds.y < rhs.bounds.y); 47 | }); 48 | 49 | 50 | //! creating reports 51 | std::ostringstream stream; 52 | std::for_each(begin(displays), 53 | end(displays), 54 | [this, &stream](Display & display){ 55 | std::ostringstream report; 56 | report << "[" << (isMainDisplay(display.id) ? "Main" : "Sub") << " Display]" << endl; 57 | report << "display id: " << display.id << endl; 58 | report << "display bounds: {" 59 | << "x:" << display.bounds.x 60 | << ", y:" << display.bounds.y 61 | << ", w:" << display.bounds.width 62 | << ", h:" << display.bounds.height 63 | << "}" << endl; 64 | 65 | ofLogVerbose() << report.str(); 66 | 67 | stream << display.id << endl; // storing only display id 68 | }); 69 | 70 | //! writing to tile 71 | ofLogVerbose() << "start saving current monitor order..."; 72 | 73 | ofBuffer buf(stream.str()); 74 | 75 | if (ofBufferToFile(filepath, buf)) { 76 | ofLogVerbose() << "succeeded!"; 77 | ofLogVerbose() << "the display order is saved to: " << filepath << endl; 78 | } 79 | 80 | return true; 81 | } 82 | 83 | bool ofxDisplayLayout::load(std::string filepath, 84 | ofxDisplayLayout::Direction direction) const { 85 | 86 | //! file check 87 | if (!ofFile::doesFileExist(filepath)) { 88 | ofLogVerbose() << filepath << " doesn't exist. aborted" << endl; 89 | return false; 90 | } 91 | 92 | //! direction check 93 | if (!isValidDirection(direction)) { 94 | ofLogError() << __PRETTY_FUNCTION__ << " invalid direction " << direction << "is passed. aborted"; 95 | return false; 96 | } 97 | 98 | //! reading valid display id 99 | std::vector display_ids; 100 | 101 | ofBuffer buf = ofBufferFromFile(filepath); 102 | ofBuffer::Lines lines = buf.getLines(); 103 | 104 | for (ofBuffer::Line l = lines.begin(); l != lines.end(); ++l) { 105 | 106 | const std::string linestr = ofTrim(l.asString()); 107 | 108 | if (linestr.empty()) continue; 109 | 110 | const unsigned int display_id = std::stoul(linestr); 111 | 112 | if (hasDisplay(display_id) == false) { 113 | ofLogVerbose() << "Aborted. couldn't found the display : " << display_id; 114 | return false; 115 | } 116 | 117 | display_ids.emplace_back(display_id); 118 | } 119 | 120 | return arrange(display_ids, direction); 121 | } 122 | 123 | 124 | void ofxDisplayLayout::debugDraw(int x, int y, float scale) { 125 | 126 | auto draw = [this, &scale](unsigned int display_id) { 127 | ofRectangle rect = getDisplayBounds(display_id); 128 | 129 | ofPushMatrix(); 130 | { 131 | ofScale(scale, scale); 132 | 133 | ofFill(); 134 | ofSetColor(255, 0, 0, 100); 135 | ofDrawRectangle(rect); 136 | 137 | ofNoFill(); 138 | ofSetColor(255, 0, 0); 139 | ofSetLineWidth(2); 140 | ofDrawRectangle(rect); 141 | } 142 | ofPopMatrix(); 143 | 144 | const ofPoint pos = rect.getPosition() * scale; 145 | 146 | if (isMainDisplay(display_id)) { 147 | ofDrawBitmapStringHighlight("Main", 148 | pos, 149 | ofColor::red, 150 | ofColor::white); 151 | } 152 | 153 | ofSetColor(255); 154 | ofDrawBitmapString(ofToString(display_id), pos.x+20, pos.y+20); 155 | ofDrawBitmapString(ofToString(pos), pos.x+20, pos.y+20); 156 | }; 157 | 158 | const std::vector display_ids = getDisplayIds(); 159 | 160 | ofPushStyle(); 161 | ofTranslate(x, y); 162 | for_each(begin(display_ids), 163 | end(display_ids), 164 | draw); 165 | ofPopStyle(); 166 | } 167 | 168 | 169 | #pragma mark - private 170 | 171 | vector ofxDisplayLayout::getDisplayIds() const { 172 | 173 | const unsigned int num_max_displays = 50; 174 | 175 | NSRect frame; 176 | CGDirectDisplayID displays[num_max_displays]; 177 | CGDisplayCount num_displays; 178 | 179 | CGError err = CGGetOnlineDisplayList(num_max_displays, displays, &num_displays); 180 | std::vector ids(num_displays); 181 | 182 | if (err != kCGErrorSuccess) { 183 | ofLogError() << "faild to get display ids."; 184 | return ids; 185 | } 186 | 187 | for (int i=0; i display_ids, 194 | ofxDisplayLayout::Direction direction) const { 195 | 196 | // see also: Quartz Display Services Reference 197 | // https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/Quartz_Services_Ref/index.html 198 | 199 | if (!isValidDirection(direction)) { 200 | ofLogError() << __PRETTY_FUNCTION__ << " invalid direction " << direction << "is passed. aborted"; 201 | return false; 202 | } 203 | 204 | struct Display { 205 | Display(unsigned int _id, ofRectangle _bounds, ofPoint _origin) 206 | : id(_id) 207 | , old_bounds(_bounds) 208 | , new_origin(_origin) 209 | {} 210 | unsigned int id; 211 | ofRectangle old_bounds; 212 | ofPoint new_origin; 213 | }; 214 | 215 | std::vector displays; 216 | 217 | for (int i=0; i(display.id), 253 | display.new_origin.x, 254 | display.new_origin.y); 255 | 256 | if (err != kCGErrorSuccess) { 257 | CGCancelDisplayConfiguration(configRef); 258 | ofLogError() << "display order arrangement falild on display: " << display.id; 259 | ofLogError() << "reason: " << err << endl; 260 | return false; 261 | } 262 | else { 263 | CGCompleteDisplayConfiguration(configRef, kCGConfigureForSession); 264 | ofLogVerbose() 265 | << "Succeeded! Display " << display.id << " is set to the origin " 266 | << "{x:" << display.new_origin.x << ", y:" << display.new_origin.y << "}"; 267 | } 268 | }; 269 | 270 | try { 271 | for_each(begin(displays), 272 | end(displays), 273 | change_display_order); 274 | } 275 | catch (const exception& e) { 276 | ofLogError() << "Error: " << e.what(); 277 | return false; 278 | } 279 | 280 | ofLogVerbose() << "display alignment done!"; 281 | 282 | return true; 283 | } --------------------------------------------------------------------------------