Commits

Virgil Dupras committed 37d9b42

Added View.accessibilityDescription and Segment.accessibilityDescription.

Comments (0)

Files changed (6)

docs/api/segment.rst

     .. attribute:: image
         
         String. Name of the image resource to display in the segment.
+    
+    .. attribute:: accessibilityDescription
+        
+        *String*. The string that is spoken out by Voice Over when the segment is selected. There's
+        no equivalent for this feature in XCode. To set a segment's accessibility description in a
+        normal project, you have to resort to manual code. Well, not with xibless!

docs/api/view.rst

         :ref:`Cocoa constant <literal-consts>`. Type of border glow that shows up when the view has
         focus. Use ``NSFocusRingType`` constants.
     
+    .. attribute:: accessibilityDescription
+        
+        *String*. The string that is spoken out by Voice Over when the view is selected. Equivalent
+        to the "Description" field in "Accessibility Identity" in XCode's IB.
+    
     .. method:: bind(name, target, keyPath[, valueTransformer])
     
         :param name: *String*

xibless/data/XiblessSupport.h

 @end
 
 NSString* stringFromChar(unichar c);
+void setAccessibilityDescription(id obj, NSString *description);
+void setAccessibilityDescriptionOfChild(id obj, NSInteger childIndex, NSString *description);

xibless/data/XiblessSupport.m

 {
     return [NSString stringWithCharacters:&c length:1];
 }
+
+void setAccessibilityDescription(id obj, NSString *description)
+{
+    id accessibilityObject = NSAccessibilityUnignoredDescendant(obj);
+    [accessibilityObject accessibilitySetOverrideValue:description forAttribute:NSAccessibilityDescriptionAttribute];
+}
+
+void setAccessibilityDescriptionOfChild(id obj, NSInteger childIndex, NSString *description)
+{
+    id accessibilityObject = NSAccessibilityUnignoredDescendant(obj);
+    NSArray *children = [accessibilityObject accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
+    
+    if (childIndex >= [children count]) {
+        NSLog(@"childIndex out of bounds in setAccessibilityDescriptionOfChild");
+        return;
+    }
+    
+    id child = [children objectAtIndex:childIndex];
+    [child accessibilitySetOverrideValue:description forAttribute:NSAccessibilityDescriptionAttribute];
+}

xibless/segment.py

         self.label = label
         self.width = width
         self.image = None
+        self.accessibilityDescription = None
     
 
 class SegmentedControl(Control):
         tmpl = Control.generateInit(self)
         tmpl.setup += self.accessor._callMethod('setSegmentCount', len(self.segments))
         for index, segment in enumerate(self.segments):
-            tmpl.setup += '[$varname$ setLabel:{} forSegment:{}];'.format(
+            tmpl.setup += '[$varname$ setLabel:{} forSegment:{}];\n'.format(
                 convertValueToObjc(segment.label), convertValueToObjc(index))
-            tmpl.setup += '[$varname$ setWidth:{} forSegment:{}];'.format(
+            tmpl.setup += '[$varname$ setWidth:{} forSegment:{}];\n'.format(
                 convertValueToObjc(segment.width), convertValueToObjc(index))
             if segment.image:
-                tmpl.setup += '[$varname$ setImage:[NSImage imageNamed:{}] forSegment:{}];'.format(
+                tmpl.setup += '[$varname$ setImage:[NSImage imageNamed:{}] forSegment:{}];\n'.format(
                 convertValueToObjc(segment.image), convertValueToObjc(index))
+            if segment.accessibilityDescription:
+                tmpl.setup += 'setAccessibilityDescriptionOfChild($varname$, {}, {});\n'.format(
+                    convertValueToObjc(index), convertValueToObjc(segment.accessibilityDescription))
         return tmpl
 from collections import namedtuple, defaultdict
 
 from .base import GeneratedItem, const
-from .types import Flags
+from .types import Flags, convertValueToObjc
 
 class Pack(object):
     # Corners
         self.x = 0
         self.y = 0
         self.anchor = Anchor(Pack.UpperLeft, False, False)
+        self.accessibilityDescription = None
         # a mapping PackingSide: {views} which is used in fill() to know how much we can fill
         self.neighbors = defaultdict(set)
         
     #--- Generate
     def generateInit(self):
         tmpl = GeneratedItem.generateInit(self)
-        tmpl.setup = "$viewsetup$\n$addtoparent$\n"
+        tmpl.setup = "$viewsetup$\n$accessibility$\n$addtoparent$\n"
         tmpl.initmethod = "initWithFrame:$rect$"
         x, y, w, h = self.frameRect()
         tmpl.rect = Rect(x, y, w, h).objcValue()
             if anchor.corner in {Pack.UpperLeft, Pack.UpperRight, Pack.Above, Pack.Left, Pack.Right, Pack.Middle}:
                 resizeMask |= const.NSViewMinYMargin
         self.properties['autoresizingMask'] = resizeMask
+        if self.accessibilityDescription:
+            tmpl.accessibility = "setAccessibilityDescription($varname$, {});\n".format(
+                convertValueToObjc(self.accessibilityDescription))
         if self.parent is not None:
             tmpl.addtoparent = self.generateAddToParent()
         return tmpl