| @@ -427,6 +427,22 @@ attributes directly to these creation functions, rather than adding them later. | |||||
| plist if `APP_SANDBOX_ENABLED` is `TRUE`. Each key should be in the form `com.apple.security.*` | plist if `APP_SANDBOX_ENABLED` is `TRUE`. Each key should be in the form `com.apple.security.*` | ||||
| where `*` is a specific entitlement. | where `*` is a specific entitlement. | ||||
| `APP_SANDBOX_FILE_ACCESS_HOME_RO` | |||||
| - A set of space-separated paths that will be added to this target's entitlements plist for | |||||
| accessing read-only paths relative to the home directory if `APP_SANDBOX_ENABLED` is `TRUE`. | |||||
| `APP_SANDBOX_FILE_ACCESS_HOME_RW` | |||||
| - A set of space-separated paths that will be added to this target's entitlements plist for | |||||
| accessing read/write paths relative to the home directory if `APP_SANDBOX_ENABLED` is `TRUE`. | |||||
| `APP_SANDBOX_FILE_ACCESS_ABS_RO` | |||||
| - A set of space-separated paths that will be added to this target's entitlements plist for | |||||
| accessing read-only absolute paths if `APP_SANDBOX_ENABLED` is `TRUE`. | |||||
| `APP_SANDBOX_FILE_ACCESS_ABS_RW` | |||||
| - A set of space-separated paths that will be added to this target's entitlements plist for | |||||
| accessing read/write absolute paths if `APP_SANDBOX_ENABLED` is `TRUE`. | |||||
| `PLIST_TO_MERGE` | `PLIST_TO_MERGE` | ||||
| - A string to insert into an app/plugin's Info.plist. | - A string to insert into an app/plugin's Info.plist. | ||||
| @@ -318,6 +318,10 @@ function(_juce_write_configure_time_info target) | |||||
| _juce_append_target_property(file_content APP_SANDBOX_INHERIT ${target} JUCE_APP_SANDBOX_INHERIT) | _juce_append_target_property(file_content APP_SANDBOX_INHERIT ${target} JUCE_APP_SANDBOX_INHERIT) | ||||
| _juce_append_target_property(file_content HARDENED_RUNTIME_OPTIONS ${target} JUCE_HARDENED_RUNTIME_OPTIONS) | _juce_append_target_property(file_content HARDENED_RUNTIME_OPTIONS ${target} JUCE_HARDENED_RUNTIME_OPTIONS) | ||||
| _juce_append_target_property(file_content APP_SANDBOX_OPTIONS ${target} JUCE_APP_SANDBOX_OPTIONS) | _juce_append_target_property(file_content APP_SANDBOX_OPTIONS ${target} JUCE_APP_SANDBOX_OPTIONS) | ||||
| _juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_HOME_RO ${target} JUCE_APP_SANDBOX_FILE_ACCESS_HOME_RO) | |||||
| _juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_HOME_RW ${target} JUCE_APP_SANDBOX_FILE_ACCESS_HOME_RW) | |||||
| _juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_ABS_RO ${target} JUCE_APP_SANDBOX_FILE_ACCESS_ABS_RO) | |||||
| _juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_ABS_RW ${target} JUCE_APP_SANDBOX_FILE_ACCESS_ABS_RW) | |||||
| _juce_append_target_property(file_content APP_GROUPS_ENABLED ${target} JUCE_APP_GROUPS_ENABLED) | _juce_append_target_property(file_content APP_GROUPS_ENABLED ${target} JUCE_APP_GROUPS_ENABLED) | ||||
| _juce_append_target_property(file_content APP_GROUP_IDS ${target} JUCE_APP_GROUP_IDS) | _juce_append_target_property(file_content APP_GROUP_IDS ${target} JUCE_APP_GROUP_IDS) | ||||
| _juce_append_target_property(file_content IS_PLUGIN ${target} JUCE_IS_PLUGIN) | _juce_append_target_property(file_content IS_PLUGIN ${target} JUCE_IS_PLUGIN) | ||||
| @@ -1546,6 +1550,10 @@ function(_juce_initialise_target target) | |||||
| VST3_CATEGORIES | VST3_CATEGORIES | ||||
| HARDENED_RUNTIME_OPTIONS | HARDENED_RUNTIME_OPTIONS | ||||
| APP_SANDBOX_OPTIONS | APP_SANDBOX_OPTIONS | ||||
| APP_SANDBOX_FILE_ACCESS_HOME_RO | |||||
| APP_SANDBOX_FILE_ACCESS_HOME_RW | |||||
| APP_SANDBOX_FILE_ACCESS_ABS_RO | |||||
| APP_SANDBOX_FILE_ACCESS_ABS_RW | |||||
| DOCUMENT_EXTENSIONS | DOCUMENT_EXTENSIONS | ||||
| AAX_CATEGORY | AAX_CATEGORY | ||||
| IPHONE_SCREEN_ORIENTATIONS # iOS only | IPHONE_SCREEN_ORIENTATIONS # iOS only | ||||
| @@ -79,7 +79,7 @@ namespace build_tools | |||||
| if (isAppGroupsEnabled) | if (isAppGroupsEnabled) | ||||
| { | { | ||||
| auto appGroups = StringArray::fromTokens (appGroupIdString, ";", {}); | auto appGroups = StringArray::fromTokens (appGroupIdString, ";", {}); | ||||
| auto groups = String ("<array>"); | |||||
| String groups = "<array>"; | |||||
| for (auto group : appGroups) | for (auto group : appGroups) | ||||
| groups += "\n\t\t<string>" + group.trim() + "</string>"; | groups += "\n\t\t<string>" + group.trim() + "</string>"; | ||||
| @@ -101,13 +101,27 @@ namespace build_tools | |||||
| { | { | ||||
| // no other sandbox options can be specified if sandbox inheritance is enabled! | // no other sandbox options can be specified if sandbox inheritance is enabled! | ||||
| jassert (appSandboxOptions.isEmpty()); | jassert (appSandboxOptions.isEmpty()); | ||||
| jassert (appSandboxTemporaryPaths.empty()); | |||||
| entitlements.set ("com.apple.security.inherit", "<true/>"); | entitlements.set ("com.apple.security.inherit", "<true/>"); | ||||
| } | } | ||||
| if (isAppSandboxEnabled) | if (isAppSandboxEnabled) | ||||
| { | |||||
| for (auto& option : appSandboxOptions) | for (auto& option : appSandboxOptions) | ||||
| entitlements.set (option, "<true/>"); | entitlements.set (option, "<true/>"); | ||||
| for (auto& option : appSandboxTemporaryPaths) | |||||
| { | |||||
| String paths = "<array>"; | |||||
| for (const auto& path : option.values) | |||||
| paths += "\n\t\t<string>" + path + "</string>"; | |||||
| paths += "\n\t</array>"; | |||||
| entitlements.set (option.key, paths); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| if (isNetworkingMulticastEnabled) | if (isNetworkingMulticastEnabled) | ||||
| @@ -49,6 +49,14 @@ namespace build_tools | |||||
| StringArray hardenedRuntimeOptions; | StringArray hardenedRuntimeOptions; | ||||
| StringArray appSandboxOptions; | StringArray appSandboxOptions; | ||||
| struct KeyAndStringArray | |||||
| { | |||||
| String key; | |||||
| StringArray values; | |||||
| }; | |||||
| std::vector<KeyAndStringArray> appSandboxTemporaryPaths; | |||||
| private: | private: | ||||
| StringPairArray getEntitlements() const; | StringPairArray getEntitlements() const; | ||||
| }; | }; | ||||
| @@ -343,6 +343,29 @@ juce::build_tools::EntitlementOptions parseEntitlementsOptions (const juce::File | |||||
| updateField ("APP_SANDBOX_OPTIONS", result.appSandboxOptions); | updateField ("APP_SANDBOX_OPTIONS", result.appSandboxOptions); | ||||
| updateField ("NETWORK_MULTICAST_ENABLED", result.isNetworkingMulticastEnabled); | updateField ("NETWORK_MULTICAST_ENABLED", result.isNetworkingMulticastEnabled); | ||||
| struct SandboxTemporaryAccessKey | |||||
| { | |||||
| juce::String cMakeVar, key; | |||||
| }; | |||||
| SandboxTemporaryAccessKey sandboxTemporaryAccessKeys[] | |||||
| { | |||||
| { "APP_SANDBOX_FILE_ACCESS_HOME_RO", "home-relative-path.read-only" }, | |||||
| { "APP_SANDBOX_FILE_ACCESS_HOME_RW", "home-relative-path.read-write" }, | |||||
| { "APP_SANDBOX_FILE_ACCESS_ABS_RO", "absolute-path.read-only" }, | |||||
| { "APP_SANDBOX_FILE_ACCESS_ABS_RW", "absolute-path.read-write" } | |||||
| }; | |||||
| for (const auto& entry : sandboxTemporaryAccessKeys) | |||||
| { | |||||
| juce::StringArray values; | |||||
| updateField (entry.cMakeVar, values); | |||||
| if (! values.isEmpty()) | |||||
| result.appSandboxTemporaryPaths.push_back ({ "com.apple.security.temporary-exception.files." + entry.key, | |||||
| std::move (values) }); | |||||
| } | |||||
| result.type = type; | result.type = type; | ||||
| return result; | return result; | ||||
| @@ -302,8 +302,7 @@ public: | |||||
| for (auto& pp : properties) | for (auto& pp : properties) | ||||
| { | { | ||||
| const auto propertyHeight = pp->getPreferredHeight() | |||||
| + (getHeightMultiplier (pp.get()) * pp->getPreferredHeight()); | |||||
| const auto propertyHeight = jmax (pp->getPreferredHeight(), getApproximateLabelHeight (*pp)); | |||||
| auto iter = std::find_if (propertyComponentsWithInfo.begin(), propertyComponentsWithInfo.end(), | auto iter = std::find_if (propertyComponentsWithInfo.begin(), propertyComponentsWithInfo.end(), | ||||
| [&pp] (const std::unique_ptr<PropertyAndInfoWrapper>& w) { return &w->propertyComponent == pp.get(); }); | [&pp] (const std::unique_ptr<PropertyAndInfoWrapper>& w) { return &w->propertyComponent == pp.get(); }); | ||||
| @@ -418,17 +417,17 @@ private: | |||||
| } | } | ||||
| } | } | ||||
| int getHeightMultiplier (PropertyComponent* pp) | |||||
| static int getApproximateLabelHeight (const PropertyComponent& pp) | |||||
| { | { | ||||
| auto availableTextWidth = ProjucerLookAndFeel::getTextWidthForPropertyComponent (pp); | auto availableTextWidth = ProjucerLookAndFeel::getTextWidthForPropertyComponent (pp); | ||||
| auto font = ProjucerLookAndFeel::getPropertyComponentFont(); | |||||
| auto nameWidth = font.getStringWidthFloat (pp->getName()); | |||||
| if (availableTextWidth == 0) | if (availableTextWidth == 0) | ||||
| return 0; | return 0; | ||||
| return static_cast<int> (nameWidth / (float) availableTextWidth); | |||||
| const auto font = ProjucerLookAndFeel::getPropertyComponentFont(); | |||||
| const auto labelWidth = font.getStringWidthFloat (pp.getName()); | |||||
| const auto numLines = (int) (labelWidth / (float) availableTextWidth) + 1; | |||||
| return (int) std::round ((float) numLines * font.getHeight() * 1.1f); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -74,6 +74,10 @@ public: | |||||
| appSandboxValue (settings, Ids::appSandbox, getUndoManager()), | appSandboxValue (settings, Ids::appSandbox, getUndoManager()), | ||||
| appSandboxInheritanceValue (settings, Ids::appSandboxInheritance, getUndoManager()), | appSandboxInheritanceValue (settings, Ids::appSandboxInheritance, getUndoManager()), | ||||
| appSandboxOptionsValue (settings, Ids::appSandboxOptions, getUndoManager(), Array<var>(), ","), | appSandboxOptionsValue (settings, Ids::appSandboxOptions, getUndoManager(), Array<var>(), ","), | ||||
| appSandboxHomeDirROValue (settings, Ids::appSandboxHomeDirRO, getUndoManager()), | |||||
| appSandboxHomeDirRWValue (settings, Ids::appSandboxHomeDirRW, getUndoManager()), | |||||
| appSandboxAbsDirROValue (settings, Ids::appSandboxAbsDirRO, getUndoManager()), | |||||
| appSandboxAbsDirRWValue (settings, Ids::appSandboxAbsDirRW, getUndoManager()), | |||||
| hardenedRuntimeValue (settings, Ids::hardenedRuntime, getUndoManager()), | hardenedRuntimeValue (settings, Ids::hardenedRuntime, getUndoManager()), | ||||
| hardenedRuntimeOptionsValue (settings, Ids::hardenedRuntimeOptions, getUndoManager(), Array<var>(), ","), | hardenedRuntimeOptionsValue (settings, Ids::hardenedRuntimeOptions, getUndoManager(), Array<var>(), ","), | ||||
| microphonePermissionNeededValue (settings, Ids::microphonePermissionNeeded, getUndoManager()), | microphonePermissionNeededValue (settings, Ids::microphonePermissionNeeded, getUndoManager()), | ||||
| @@ -173,6 +177,21 @@ public: | |||||
| bool isAppSandboxInhertianceEnabled() const { return appSandboxInheritanceValue.get(); } | bool isAppSandboxInhertianceEnabled() const { return appSandboxInheritanceValue.get(); } | ||||
| Array<var> getAppSandboxOptions() const { return *appSandboxOptionsValue.get().getArray(); } | Array<var> getAppSandboxOptions() const { return *appSandboxOptionsValue.get().getArray(); } | ||||
| auto getAppSandboxTemporaryPaths() const | |||||
| { | |||||
| std::vector<build_tools::EntitlementOptions::KeyAndStringArray> result; | |||||
| for (const auto& entry : sandboxFileAccessProperties) | |||||
| { | |||||
| auto paths = getCommaOrWhitespaceSeparatedItems (entry.property.get()); | |||||
| if (! paths.isEmpty()) | |||||
| result.push_back ({ "com.apple.security.temporary-exception.files." + entry.key, std::move (paths) }); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| Array<var> getValidArchs() const { return *validArchsValue.get().getArray(); } | Array<var> getValidArchs() const { return *validArchsValue.get().getArray(); } | ||||
| bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); } | bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); } | ||||
| @@ -457,29 +476,36 @@ public: | |||||
| { "Temporary Exception: Audio Unit Hosting", "temporary-exception.audio-unit-host" }, | { "Temporary Exception: Audio Unit Hosting", "temporary-exception.audio-unit-host" }, | ||||
| { "Temporary Exception: Global Mach Service", "temporary-exception.mach-lookup.global-name" }, | { "Temporary Exception: Global Mach Service", "temporary-exception.mach-lookup.global-name" }, | ||||
| { "Temporary Exception: Global Mach Service Dynamic Registration", "temporary-exception.mach-register.global-name" }, | { "Temporary Exception: Global Mach Service Dynamic Registration", "temporary-exception.mach-register.global-name" }, | ||||
| { "Temporary Exception: Home Directory File Access (Read Only)", "temporary-exception.files.home-relative-path.read-only" }, | |||||
| { "Temporary Exception: Home Directory File Access (Read/Write)", "temporary-exception.files.home-relative-path.read-write" }, | |||||
| { "Temporary Exception: Absolute Path File Access (Read Only)", "temporary-exception.files.absolute-path.read-only" }, | |||||
| { "Temporary Exception: Absolute Path File Access (Read/Write)", "temporary-exception.files.absolute-path.read-write" }, | |||||
| { "Temporary Exception: IOKit User Client Class", "temporary-exception.iokit-user-client-class" }, | { "Temporary Exception: IOKit User Client Class", "temporary-exception.iokit-user-client-class" }, | ||||
| { "Temporary Exception: Shared Preference Domain (Read Only)", "temporary-exception.shared-preference.read-only" }, | { "Temporary Exception: Shared Preference Domain (Read Only)", "temporary-exception.shared-preference.read-only" }, | ||||
| { "Temporary Exception: Shared Preference Domain (Read/Write)", "temporary-exception.shared-preference.read-write" } | { "Temporary Exception: Shared Preference Domain (Read/Write)", "temporary-exception.shared-preference.read-write" } | ||||
| }; | }; | ||||
| StringArray sandboxKeys; | StringArray sandboxKeys; | ||||
| Array<var> sanboxValues; | |||||
| Array<var> sandboxValues; | |||||
| for (auto& opt : sandboxOptions) | for (auto& opt : sandboxOptions) | ||||
| { | { | ||||
| sandboxKeys.add (opt.first); | sandboxKeys.add (opt.first); | ||||
| sanboxValues.add ("com.apple.security." + opt.second); | |||||
| sandboxValues.add ("com.apple.security." + opt.second); | |||||
| } | } | ||||
| props.add (new MultiChoicePropertyComponentWithEnablement (appSandboxOptionsValue, | props.add (new MultiChoicePropertyComponentWithEnablement (appSandboxOptionsValue, | ||||
| appSandboxValue, | appSandboxValue, | ||||
| "App Sandbox Options", | "App Sandbox Options", | ||||
| sandboxKeys, | sandboxKeys, | ||||
| sanboxValues)); | |||||
| sandboxValues)); | |||||
| for (const auto& entry : sandboxFileAccessProperties) | |||||
| { | |||||
| props.add (new TextPropertyComponentWithEnablement (entry.property, | |||||
| appSandboxValue, | |||||
| entry.label, | |||||
| 8192, | |||||
| true), | |||||
| "A list of the corresponding paths (separated by newlines or whitespace). " | |||||
| "See Apple's File Access Temporary Exceptions documentation."); | |||||
| } | |||||
| props.add (new ChoicePropertyComponent (hardenedRuntimeValue, "Use Hardened Runtime"), | props.add (new ChoicePropertyComponent (hardenedRuntimeValue, "Use Hardened Runtime"), | ||||
| "Enable this to use the hardened runtime required for app notarization."); | "Enable this to use the hardened runtime required for app notarization."); | ||||
| @@ -3085,6 +3111,7 @@ private: | |||||
| options.appGroupIdString = getAppGroupIdString(); | options.appGroupIdString = getAppGroupIdString(); | ||||
| options.hardenedRuntimeOptions = getHardenedRuntimeOptions(); | options.hardenedRuntimeOptions = getHardenedRuntimeOptions(); | ||||
| options.appSandboxOptions = getAppSandboxOptions(); | options.appSandboxOptions = getAppSandboxOptions(); | ||||
| options.appSandboxTemporaryPaths = getAppSandboxTemporaryPaths(); | |||||
| const auto entitlementsFile = getTargetFolder().getChildFile (target.getEntitlementsFilename()); | const auto entitlementsFile = getTargetFolder().getChildFile (target.getEntitlementsFilename()); | ||||
| build_tools::overwriteFileIfDifferentOrThrow (entitlementsFile, options.getEntitlementsFileContent()); | build_tools::overwriteFileIfDifferentOrThrow (entitlementsFile, options.getEntitlementsFileContent()); | ||||
| @@ -3566,6 +3593,7 @@ private: | |||||
| duplicateAppExResourcesFolderValue, iosDeviceFamilyValue, iPhoneScreenOrientationValue, | duplicateAppExResourcesFolderValue, iosDeviceFamilyValue, iPhoneScreenOrientationValue, | ||||
| iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue, | iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue, | ||||
| appSandboxValue, appSandboxInheritanceValue, appSandboxOptionsValue, | appSandboxValue, appSandboxInheritanceValue, appSandboxOptionsValue, | ||||
| appSandboxHomeDirROValue, appSandboxHomeDirRWValue, appSandboxAbsDirROValue, appSandboxAbsDirRWValue, | |||||
| hardenedRuntimeValue, hardenedRuntimeOptionsValue, | hardenedRuntimeValue, hardenedRuntimeOptionsValue, | ||||
| microphonePermissionNeededValue, microphonePermissionsTextValue, | microphonePermissionNeededValue, microphonePermissionsTextValue, | ||||
| cameraPermissionNeededValue, cameraPermissionTextValue, | cameraPermissionNeededValue, cameraPermissionTextValue, | ||||
| @@ -3576,5 +3604,19 @@ private: | |||||
| networkingMulticastValue, iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue, customLaunchStoryboardValue, | networkingMulticastValue, iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue, customLaunchStoryboardValue, | ||||
| exporterBundleIdentifierValue, suppressPlistResourceUsageValue, useLegacyBuildSystemValue, buildNumber; | exporterBundleIdentifierValue, suppressPlistResourceUsageValue, useLegacyBuildSystemValue, buildNumber; | ||||
| struct SandboxFileAccessProperty | |||||
| { | |||||
| const ValueTreePropertyWithDefault& property; | |||||
| const String label, key; | |||||
| }; | |||||
| const std::vector<SandboxFileAccessProperty> sandboxFileAccessProperties | |||||
| { | |||||
| { appSandboxHomeDirROValue, "App sandbox temporary exception: home directory read only file access", "home-relative-path.read-only" }, | |||||
| { appSandboxHomeDirRWValue, "App sandbox temporary exception: home directory read/write file access", "home-relative-path.read-write" }, | |||||
| { appSandboxAbsDirROValue, "App sandbox temporary exception: absolute path read only file access", "absolute-path.read-only" }, | |||||
| { appSandboxAbsDirRWValue, "App sandbox temporary exception: absolute path read/write file access", "absolute-path.read-write" } | |||||
| }; | |||||
| JUCE_DECLARE_NON_COPYABLE (XcodeProjectExporter) | JUCE_DECLARE_NON_COPYABLE (XcodeProjectExporter) | ||||
| }; | }; | ||||
| @@ -196,6 +196,10 @@ namespace Ids | |||||
| DECLARE_ID (appSandbox); | DECLARE_ID (appSandbox); | ||||
| DECLARE_ID (appSandboxInheritance); | DECLARE_ID (appSandboxInheritance); | ||||
| DECLARE_ID (appSandboxOptions); | DECLARE_ID (appSandboxOptions); | ||||
| DECLARE_ID (appSandboxHomeDirRO); | |||||
| DECLARE_ID (appSandboxHomeDirRW); | |||||
| DECLARE_ID (appSandboxAbsDirRO); | |||||
| DECLARE_ID (appSandboxAbsDirRW); | |||||
| DECLARE_ID (hardenedRuntime); | DECLARE_ID (hardenedRuntime); | ||||
| DECLARE_ID (hardenedRuntimeOptions); | DECLARE_ID (hardenedRuntimeOptions); | ||||
| DECLARE_ID (microphonePermissionNeeded); | DECLARE_ID (microphonePermissionNeeded); | ||||
| @@ -94,23 +94,21 @@ int ProjucerLookAndFeel::getTabButtonBestWidth (TabBarButton& button, int) | |||||
| return 120; | return 120; | ||||
| } | } | ||||
| void ProjucerLookAndFeel::drawPropertyComponentLabel (Graphics& g, int width, int height, PropertyComponent& component) | |||||
| void ProjucerLookAndFeel::drawPropertyComponentLabel (Graphics& g, int, int height, PropertyComponent& component) | |||||
| { | { | ||||
| ignoreUnused (width); | |||||
| g.setColour (component.findColour (defaultTextColourId) | g.setColour (component.findColour (defaultTextColourId) | ||||
| .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f)); | .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f)); | ||||
| auto textWidth = getTextWidthForPropertyComponent (&component); | |||||
| auto textWidth = getTextWidthForPropertyComponent (component); | |||||
| g.setFont (getPropertyComponentFont()); | g.setFont (getPropertyComponentFont()); | ||||
| g.drawFittedText (component.getName(), 0, 0, textWidth - 5, height, Justification::centredLeft, 5, 1.0f); | |||||
| g.drawFittedText (component.getName(), 0, 0, textWidth, height, Justification::centredLeft, 5, 1.0f); | |||||
| } | } | ||||
| Rectangle<int> ProjucerLookAndFeel::getPropertyComponentContentPosition (PropertyComponent& component) | Rectangle<int> ProjucerLookAndFeel::getPropertyComponentContentPosition (PropertyComponent& component) | ||||
| { | { | ||||
| const auto textW = getTextWidthForPropertyComponent (&component); | |||||
| return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 }; | |||||
| const auto paddedTextW = getTextWidthForPropertyComponent (component) + 5; | |||||
| return { paddedTextW , 0, component.getWidth() - paddedTextW, component.getHeight() - 1 }; | |||||
| } | } | ||||
| void ProjucerLookAndFeel::drawButtonBackground (Graphics& g, | void ProjucerLookAndFeel::drawButtonBackground (Graphics& g, | ||||
| @@ -81,8 +81,8 @@ public: | |||||
| const bool filled, const Justification justification); | const bool filled, const Justification justification); | ||||
| static Path getChoiceComponentArrowPath (Rectangle<float> arrowZone); | static Path getChoiceComponentArrowPath (Rectangle<float> arrowZone); | ||||
| static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; } | |||||
| static int getTextWidthForPropertyComponent (PropertyComponent* pp) { return jmin (200, pp->getWidth() / 2); } | |||||
| static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; } | |||||
| static int getTextWidthForPropertyComponent (const PropertyComponent& pc) { return jmin (200, pc.getWidth() / 2); } | |||||
| static ColourScheme getProjucerDarkColourScheme() | static ColourScheme getProjucerDarkColourScheme() | ||||
| { | { | ||||