Viewing file: mag.py (59.68 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Orca # # Copyright 2005-2008 Sun Microsystems Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., Franklin Street, Fifth Floor, # Boston MA 02110-1301 USA.
"""Manages the magnifier for orca. [[[TODO: WDW - this is very very early in development. One might even say it is pre-prototype.]]]"""
__id__ = "$Id$" __version__ = "$Revision$" __date__ = "$Date$" __copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." __license__ = "LGPL"
import bonobo try: # This can fail due to gtk not being available. We want to # be able to recover from that if possible. The main driver # for this is to allow "orca --text-setup" to work even if # the desktop is not running. # import gtk except: pass import time
import pyatspi import debug import eventsynthesizer import settings import speech import orca_state
from orca_i18n import _ # for gettext support
_magnifierAvailable = False
try: import ORBit ORBit.load_typelib('GNOME_Magnifier') import GNOME.Magnifier _magnifierAvailable = True except: pass
# If True, this module has been initialized. # _initialized = False
# The Magnifier and its property bag # _magnifier = None _magnifierPBag = None
# The width and height, in unzoomed system coordinates of the rectangle that, # when magnified, will fill the viewport of the magnifier - this needs to be # sync'd with the magnification factors of the zoom area. # _roiWidth = 0 _roiHeight = 0
# Minimum/maximum values for the center of the ROI # in source screen coordinates. # _minROIX = 0 _maxROIX = 0 _minROIY = 0 _maxROIY = 0
# The current region of interest. # # A GNOME.Magnifier.RectBounds object which consists of x1, y1, x2, y2 values # that are in source screen coordinates. # _roi = None
# The area of the source display that is not covered by the magnifier. # # A GNOME.Magnifier.RectBounds object which consists of x1, y1, x2, y2 values # that are in source screen coordinates. If the COMPOSITE support is enabled # in gnome-mag, then this typically becomes the entire source screen. If it # it not enabled, however, and the target and source displays are the same, # this ends up becoming the portion of the screen that is not covered by the # magnifier. # _sourceDisplayBounds = None
# The area on the target display where we are placing the magnifier. # # A GNOME.Magnifier.RectBounds object which consists of x1, y1, x2, y2 values # that are in target screen coordinates. # _targetDisplayBounds = None
# The ZoomRegion we care about and its property bag. We only use one # ZoomRegion and we make it occupy the whole magnifier. # _zoomer = None _zoomerPBag = None
# The time of the last mouse event. # _lastMouseEventTime = time.time()
# Whether or not the last mouse event was the result of our routing the # pointer. # _lastMouseEventWasRoute = False
# If True, we're using gnome-mag >= 0.13.1 that allows us to control # where to draw the cursor and crosswires. # _pollMouseDisabled = False
# Whether or not composite is being used. # _fullScreenCapable = True
# Whether or not we're in the process of making "live update" changes # to the location of the magnifier. # _liveUpdatingMagnifier = False
# The original source display bounds. # _originalSourceDisplayBounds = None
# The current modes of tracking, for use with "live update" changes. # _mouseTracking = None _controlTracking = None _textTracking = None _edgeMargin = None _pointerFollowsZoomer = None _pointerFollowsFocus = None
def __setROI(rect): """Sets the region of interest.
Arguments: - rect: A GNOME.Magnifier.RectBounds object. """
global _roi
debug.println(debug.LEVEL_ALL, "mag.py:__setROI: (%d, %d), (%d, %d)" \ % (rect.x1, rect.y1, rect.x2, rect.y2))
_roi = rect
_zoomer.setROI(_roi) _zoomer.markDirty(_roi) # [[[TODO: WDW - for some reason, this seems # necessary.]]] def __setROICenter(x, y): """Centers the region of interest around the given point.
Arguments: - x: integer in unzoomed system coordinates representing x component - y: integer in unzoomed system coordinates representing y component """
if not _initialized: return
if x < _minROIX: x = _minROIX elif x > _maxROIX: x = _maxROIX
if y < _minROIY: y = _minROIY elif y > _maxROIY: y = _maxROIY
x1 = x - (_roiWidth / 2) y1 = y - (_roiHeight / 2)
x2 = x1 + _roiWidth y2 = y1 + _roiHeight
__setROI(GNOME.Magnifier.RectBounds(x1, y1, x2, y2))
def __setROIPush(x, y): """Nudges the ROI if the pointer bumps into the edge of it. The point given is assumed to be the point where the mouse pointer is.
Arguments: - x: integer in unzoomed system coordinates representing x component - y: integer in unzoomed system coordinates representing y component """
#needNewROI = False newROI = GNOME.Magnifier.RectBounds(_roi.x1, _roi.y1, _roi.x2, _roi.y2) if x < _roi.x1: #needNewROI = True newROI.x1 = x newROI.x2 = x + _roiWidth elif x > _roi.x2: #needNewROI = True newROI.x2 = x newROI.x1 = x - _roiWidth if y < _roi.y1: #needNewROI = True newROI.y1 = y newROI.y2 = y + _roiHeight elif y > _roi.y2: #needNewROI = True newROI.y2 = y newROI.y1 = y - _roiHeight
# Well...we'll always update the ROI so the new gnome-mag API # will redraw the crosswires for us. # #if needNewROI: if True: __setROI(newROI)
def __setROICursorPush(x, y, width, height, edgeMargin = 0): """Nudges the ROI if the caret or control is not visible.
Arguments: - x: integer in unzoomed system coordinates representing x component - y: integer in unzoomed system coordinates representing y component - width: integer in unzoomed system coordinates representing the width - height: integer in unzoomed system coordinates representing the height - edgeMargin: a percentage representing how close to the edge we can get before we need to push """
# The edge margin should not exceed 50%. (50% is a centered alignment). # edgeMargin = min(edgeMargin, 50)/100.00 edgeMarginX = edgeMargin * _sourceDisplayBounds.x2/settings.magZoomFactor edgeMarginY = edgeMargin * _sourceDisplayBounds.y2/settings.magZoomFactor
# Determine if the accessible is partially to the left, right, # above, or below the current region of interest (ROI). # leftOfROI = (x - edgeMarginX) <= _roi.x1 rightOfROI = (x + width + edgeMarginX) >= _roi.x2 aboveROI = (y - edgeMarginY) <= _roi.y1 belowROI = (y + height + edgeMarginY) >= _roi.y2
# If it is already completely showing, do nothing. # visibleX = not(leftOfROI or rightOfROI) visibleY = not(aboveROI or belowROI) if visibleX and visibleY: _zoomer.markDirty(_roi)
# The algorithm is devised to move the ROI as little as possible, yet # favor the top left side of the object [[[TODO: WDW - the left/right # top/bottom favoring should probably depend upon the locale. Also, # I had the notion of including a floating point snap factor between # 0.0 and 1.0 that would determine how to position the object in the # window relative to the ROI edges. A snap factor of -1 would mean to # snap to the closest edge. A snap factor of 0.0 would snap to the # left most or top most edge, a snap factor of 1.0 would snap to the # right most or bottom most edge. Any number in between would divide # the two.]]] # x1 = _roi.x1 x2 = _roi.x2 y1 = _roi.y1 y2 = _roi.y2
if leftOfROI: x1 = max(_sourceDisplayBounds.x1, x - edgeMarginX) x2 = x1 + _roiWidth elif rightOfROI: x = min(_sourceDisplayBounds.x2, x + edgeMarginX) if width > _roiWidth: x1 = x x2 = x1 + _roiWidth else: x2 = x + width x1 = x2 - _roiWidth
if aboveROI: y1 = max(_sourceDisplayBounds.y1, y - edgeMarginY) y2 = y1 + _roiHeight elif belowROI: y = min(_sourceDisplayBounds.y2, y + edgeMarginY) if height > _roiHeight: y1 = y y2 = y1 + _roiHeight else: y2 = y + height y1 = y2 - _roiHeight
__setROI(GNOME.Magnifier.RectBounds(x1, y1, x2, y2))
def __setROIProportional(x, y): """Positions the ROI proportionally to where the pointer is on the screen.
Arguments: - x: integer in unzoomed system coordinates representing x component - y: integer in unzoomed system coordinates representing y component """
if not _initialized: return
if not _sourceDisplayBounds: __setROICenter(x, y) else: halfScreenWidth = (_sourceDisplayBounds.x2 \ - _sourceDisplayBounds.x1) / 2.0 halfScreenHeight = (_sourceDisplayBounds.y2 \ - _sourceDisplayBounds.y1) / 2.0
proportionX = (halfScreenWidth - x) / halfScreenWidth proportionY = (halfScreenHeight - y) / halfScreenHeight
centerX = x + int(proportionX * _roiWidth / 2.0) centerY = y + int(proportionY * _roiHeight / 2.0)
__setROICenter(centerX, centerY)
# Used for tracking the pointer. # def __onMouseEvent(e): """ Arguments: - e: at-spi event from the at-api registry """
global _lastMouseEventTime global _lastMouseEventWasRoute
isNewMouseMovement = (time.time() - _lastMouseEventTime > 1) _lastMouseEventTime = time.time()
[x, y] = [e.detail1, e.detail2]
if _pointerFollowsZoomer and isNewMouseMovement \ and not _lastMouseEventWasRoute: mouseIsVisible = (_roi.x1 < x < _roi.x2) and (_roi.y1 < y < _roi.y2) if not mouseIsVisible and orca_state.locusOfFocus: if _mouseTracking == settings.MAG_TRACKING_MODE_CENTERED: x = (_roi.x1 + _roi.x2) / 2 y = (_roi.y1 + _roi.y2) / 2 elif _mouseTracking != settings.MAG_TRACKING_MODE_NONE: try: extents = \ orca_state.locusOfFocus.queryComponent().getExtents(0) except: extents = None if extents: x = extents.x y = extents.y + extents.height - 1
eventsynthesizer.generateMouseEvent(x, y, "abs") _lastMouseEventWasRoute = True
# If True, we're using gnome-mag >= 0.13.1 that allows us to # control where to draw the cursor and crosswires. # if _pollMouseDisabled: _zoomer.setPointerPos(x, y)
if _lastMouseEventWasRoute: # If we just moved the mouse pointer to the menu item or control # with focus, we don't want to do anything. # _lastMouseEventWasRoute = False _zoomer.markDirty(_roi) return
if _mouseTracking == settings.MAG_TRACKING_MODE_PUSH: __setROIPush(x, y) elif _mouseTracking == settings.MAG_TRACKING_MODE_PROPORTIONAL: __setROIProportional(x, y) elif _mouseTracking == settings.MAG_TRACKING_MODE_CENTERED: __setROICenter(x, y)
def __getValueText(slot, value): valueText = "" if slot == "cursor-hotspot": valueText = "(%d, %d)" % (value.x, value.y) elif slot == "source-display-bounds": valueText = "(%d, %d),(%d, %d)" \ % (value.x1, value.y1, value.x2, value.y2) elif slot == "target-display-bounds": valueText = "(%d, %d),(%d, %d)" \ % (value.x1, value.y1, value.x2, value.y2) elif slot == "viewport": valueText = "(%d, %d),(%d, %d)" \ % (value.x1, value.y1, value.x2, value.y2) return valueText
def __dumpPropertyBag(obj): pbag = obj.getProperties() slots = pbag.getKeys("") print " Available slots: ", pbag.getKeys("") for slot in slots: # These crash the magnifier since it doesn't know how to marshall # them to us. # if slot in ["cursor-set", "smoothing-type"]: continue print " About '%s':" % slot print " Doc Title:", pbag.getDocTitle(slot) print " Type:", pbag.getType(slot) value = pbag.getDefault(slot).value() print " Default value:", value, __getValueText(slot, value) value = pbag.getValue(slot).value() print " Current value:", value, __getValueText(slot, value) print
def __setupMagnifier(position, left=None, top=None, right=None, bottom=None, restore=None): """Creates the magnifier in the position specified.
Arguments: - position: the position/type of zoomer (full, left half, etc.) - left: the left edge of the zoomer (only applicable for custom) - top: the top edge of the zoomer (only applicable for custom) - right: the right edge of the zoomer (only applicable for custom) - bottom: the top edge of the zoomer (only applicable for custom) - restore: a dictionary of all of the settings which should be restored """
global _fullScreenCapable global _magnifierPBag global _originalSourceDisplayBounds
_magnifier.clearAllZoomRegions()
if not restore: restore = {}
# Define where the magnifier will live. # try: _magnifier.TargetDisplay = settings.magTargetDisplay except: pass
# Define what will be magnified. # try: _magnifier.SourceDisplay = settings.magSourceDisplay except: pass
# Find out if we're using composite. # try: _fullScreenCapable = _magnifier.fullScreenCapable() except: debug.printException(debug.LEVEL_WARNING)
# If we are running in full screen mode, try to hide the original cursor # (assuming the user wants to). See bug #533095 for more details. # Depends upon new functionality in gnome-mag, so just catch the # exception if this functionality isn't there. # hideCursor = restore.get('magHideCursor', settings.magHideCursor) if hideCursor \ and _fullScreenCapable \ and _magnifier.SourceDisplay == _magnifier.TargetDisplay \ and position == settings.MAG_ZOOMER_TYPE_FULL_SCREEN: hideSystemPointer(True) else: hideSystemPointer(False)
_magnifierPBag = _magnifier.getProperties() sdb = _magnifierPBag.getValue("source-display-bounds").value() if not _originalSourceDisplayBounds: _originalSourceDisplayBounds = sdb elif _liveUpdatingMagnifier: sdb = _originalSourceDisplayBounds
# Find out where the user wants to place the target display. # if _fullScreenCapable and \ position == settings.MAG_ZOOMER_TYPE_FULL_SCREEN: prefLeft = 0 prefTop = 0 prefRight = sdb.x2 prefBottom = sdb.y2 elif position == settings.MAG_ZOOMER_TYPE_TOP_HALF: prefLeft = 0 prefTop = 0 prefRight = sdb.x2 prefBottom = sdb.y2 / 2 elif position == settings.MAG_ZOOMER_TYPE_BOTTOM_HALF: prefLeft = 0 prefTop = sdb.y2 / 2 prefRight = sdb.x2 prefBottom = sdb.y2 elif position == settings.MAG_ZOOMER_TYPE_LEFT_HALF: prefLeft = 0 prefTop = 0 prefRight = sdb.x2 / 2 prefBottom = sdb.y2 elif position == settings.MAG_ZOOMER_TYPE_RIGHT_HALF: prefLeft = sdb.x2 / 2 prefTop = 0 prefRight = sdb.x2 prefBottom = sdb.y2 else: prefLeft = left or settings.magZoomerLeft prefTop = top or settings.magZoomerTop prefRight = right or settings.magZoomerRight prefBottom = bottom or settings.magZoomerBottom orca_state.zoomerType = position updateTarget = True
# If we're not using composite, bad things will happen if we allow the # target display to occupy more than 50% of the full screen. Also, if # it occupies the same space as something that should be magnified (e.g. # the Applications menu), that item will not be magnified. Therefore, # we're going to prefer the right half of the screen for the target # display -- unless gnome-mag is already running and not in "full screen" # mode. # if not _fullScreenCapable \ and _magnifier.SourceDisplay == _magnifier.TargetDisplay: # At this point, the target display bounds have not been set. if they # are all 0, then we know that gnome-mag isn't already running. # magAlreadyRunning = False tdb = _magnifierPBag.getValue("target-display-bounds").value() if tdb.x1 or tdb.x2 or tdb.y1 or tdb.y2: magAlreadyRunning = True
# At this point, because we haven't set the target display bounds, # gnome-mag has not modified the source display bounds. Therefore, # we can use the current source display bounds to get the # dimensions of the full screen -- assuming gnome-mag has not # already been launched with a split screen. Comparing the values # of the source and target display bounds lets us know if gnome-mag # has been started in "full screen" mode. # magFullScreen = magAlreadyRunning \ and (tdb.x1 == sdb.x1) and (tdb.x2 == sdb.x2) \ and (tdb.y1 == sdb.y1) and (tdb.y2 == sdb.y2)
sourceArea = (sdb.x2 - sdb.x1) * (sdb.y2 - sdb.y1) prefArea = (prefRight - prefLeft) * (prefBottom - prefTop) if prefArea > sourceArea/2: debug.println( debug.LEVEL_WARNING, "Composite is not being used. The preferred target area is\n"\ "greater than 50% of the source area. These settings can\n"\ "render the contents of the screen inaccessible.") if not magAlreadyRunning or magFullScreen: debug.println( debug.LEVEL_WARNING, "Setting the target display to the screen's right half.") prefRight = sdb.x2 prefLeft = sdb.x2/2 prefTop = sdb.y1 prefBottom = sdb.y2 elif sdb.y2 > 0: updateTarget = False debug.println( debug.LEVEL_WARNING, "Gnome-mag is already running. Using those settings.")
# Now, tell the magnifier where we want it to live on the target display. # The coordinates are in screen coordinates of the target display. # This will have the side effect of setting up other stuff for us, such # as source-display-bouinds. # if updateTarget: tdb = _magnifierPBag.getValue("target-display-bounds").value() _magnifierPBag.setValue( "target-display-bounds", ORBit.CORBA.Any( ORBit.CORBA.TypeCode( tdb.__typecode__.repo_id), GNOME.Magnifier.RectBounds(prefLeft, prefTop, prefRight, prefBottom)))
bonobo.pbclient_set_string(_magnifierPBag, "cursor-set", "default")
enableCursor = restore.get('enableMagCursor', settings.enableMagCursor) explicitSize = restore.get('enableMagCursorExplicitSize', settings.enableMagCursorExplicitSize) size = restore.get('magCursorSize', settings.magCursorSize) setMagnifierCursor(enableCursor, explicitSize, size, False)
value = restore.get('magCursorColor', settings.magCursorColor) setMagnifierObjectColor("cursor-color", value, False)
value = restore.get('magCrossHairColor', settings.magCrossHairColor) setMagnifierObjectColor("crosswire-color", value, False)
enableCrossHair = restore.get('enableMagCrossHair', settings.enableMagCrossHair) setMagnifierCrossHair(enableCrossHair, False)
value = restore.get('enableMagCrossHairClip', settings.enableMagCrossHairClip) setMagnifierCrossHairClip(value, False)
orca_state.mouseEnhancementsEnabled = enableCursor or enableCrossHair
def __setupZoomer(restore=None): """Creates a zoomer in the magnifier Arguments: - restore: a dictionary of all of the settings which should be restored """
global _sourceDisplayBounds global _targetDisplayBounds global _zoomer global _roiWidth global _roiHeight global _pollMouseDisabled global _zoomerPBag global _fullScreenCapable
if not restore: restore = {}
_targetDisplayBounds = _magnifierPBag.getValue( "target-display-bounds").value()
debug.println(debug.LEVEL_ALL, "Magnifier target bounds preferences: (%d, %d), (%d, %d)" \ % (settings.magZoomerLeft, settings.magZoomerTop, \ settings.magZoomerRight, settings.magZoomerBottom))
debug.println(debug.LEVEL_ALL, "Magnifier target bounds actual: (%d, %d), (%d, %d)" \ % (_targetDisplayBounds.x1, _targetDisplayBounds.y1, \ _targetDisplayBounds.x2, _targetDisplayBounds.y2))
# If the COMPOSITE support is not enabled in gnome-mag, then the # source-display-bounds will be adjusted to accomodate portion of the # display not being covered by the magnifier (assuming there is only # one display). Otherwise, the source-display-bounds will be the # entire source screen. # _sourceDisplayBounds = _magnifierPBag.getValue( "source-display-bounds").value()
debug.println(debug.LEVEL_ALL, "Magnifier source bounds actual: (%d, %d), (%d, %d)" \ % (_sourceDisplayBounds.x1, _sourceDisplayBounds.y1, \ _sourceDisplayBounds.x2, _sourceDisplayBounds.y2))
# If there is nothing we can possibly magnify, switch to the right half. # if ((_sourceDisplayBounds.x2 - _sourceDisplayBounds.x1) == 0) \ or ((_sourceDisplayBounds.y2 - _sourceDisplayBounds.y1) == 0): debug.println( debug.LEVEL_SEVERE, "There is nothing to magnify. This is usually caused\n" \ "by a preferences setting that tries to take up the\n" \ "full screen for magnification, but the underlying\n" "system does not support full screen magnification.\n" "The causes of that are generally that COMPOSITE\n" \ "support has not been enabled in gnome-mag or the\n" \ "X Window System Server. As a result of this issue,\n" \ "defaulting to the right half of the screen.\n") _fullScreenCapable = False __setupMagnifier(settings.MAG_ZOOMER_TYPE_CUSTOM, _targetDisplayBounds.x1/2, _targetDisplayBounds.y1, _targetDisplayBounds.x2, _targetDisplayBounds.y2) _sourceDisplayBounds = _magnifierPBag.getValue( "source-display-bounds").value() _targetDisplayBounds = _magnifierPBag.getValue( "target-display-bounds").value()
# Now, we create a zoom region to occupy the whole magnifier (i.e., # the viewport is in target region coordinates and we make the # viewport be the whole target region). Note, since we're starting # at (0, 0), the viewportWidth and viewportHeight are the same as # the x2, y2 values for a rectangular region. # viewportWidth = _targetDisplayBounds.x2 - _targetDisplayBounds.x1 viewportHeight = _targetDisplayBounds.y2 - _targetDisplayBounds.y1
debug.println(debug.LEVEL_ALL, "Magnifier zoomer viewport desired: (0, 0), (%d, %d)" \ % (viewportWidth, viewportHeight))
# Now, let's see what the ROI looks like. # debug.println(debug.LEVEL_ALL, "Magnifier source width: %d (viewport can show %d)" \ % (_sourceDisplayBounds.x2 - _sourceDisplayBounds.x1, viewportWidth / settings.magZoomFactor)) debug.println(debug.LEVEL_ALL, "Magnifier source height: %d (viewport can show %d)" \ % (_sourceDisplayBounds.y2 - _sourceDisplayBounds.y1, viewportHeight / settings.magZoomFactor))
# Adjust the ROI in the event the source window is too small for the # target window. This usually happens when someone expects COMPOSITE # to be enabled, but it isn't. As a result, they usually have a very # big grey magnifier on their screen. # _roiWidth = min(_sourceDisplayBounds.x2 - _sourceDisplayBounds.x1, viewportWidth / settings.magZoomFactor) _roiHeight = min(_sourceDisplayBounds.y2 - _sourceDisplayBounds.y1, viewportHeight / settings.magZoomFactor)
debug.println(debug.LEVEL_ALL, "Magnifier zoomer ROI size desired: width=%d, height=%d)" \ % (_roiWidth, _roiHeight))
# Create the zoomer with a magnification factor, an initial ROI, and # where in magnifier we want it to be (we want it to be in the whole # magnifier). Initially set the viewport so that it does not appear. # After we set all of the color properties, reset the viewport to # the correct position. This will prevent the user from seeing the # individual property changes (e.g. brightness, contrast) upon load. # _zoomer = _magnifier.createZoomRegion( settings.magZoomFactor, settings.magZoomFactor, GNOME.Magnifier.RectBounds(0, 0, _roiWidth, _roiHeight), GNOME.Magnifier.RectBounds(0, 0, 1, 1))
_zoomerPBag = _zoomer.getProperties() bonobo.pbclient_set_boolean(_zoomerPBag, "is-managed", True)
value = restore.get('magZoomFactor', settings.magZoomFactor) setZoomerMagFactor(value, value, False)
value = restore.get('enableMagZoomerColorInversion', settings.enableMagZoomerColorInversion) setZoomerColorInversion(value, False)
brightness = restore.get('magBrightnessLevel', settings.magBrightnessLevel) r = brightness + \ restore.get('magBrightnessLevelRed', settings.magBrightnessLevelRed) g = brightness + \ restore.get('magBrightnessLevelGreen', settings.magBrightnessLevelGreen) b = brightness + \ restore.get('magBrightnessLevelBlue', settings.magBrightnessLevelBlue) setZoomerBrightness(r, g, b, False)
contrast = restore.get('magContrastLevel', settings.magContrastLevel) r = contrast + \ restore.get('magContrastLevelRed', settings.magContrastLevelRed) g = contrast + \ restore.get('magContrastLevelGreen', settings.magContrastLevelGreen) b = contrast + \ restore.get('magContrastLevelBlue', settings.magContrastLevelBlue) setZoomerContrast(r, g, b, False)
value = restore.get('magColorFilteringMode', settings.magColorFilteringMode) setZoomerColorFilter(value, False)
value = restore.get('magZoomerType', settings.magZoomerType) if value == settings.MAG_ZOOMER_TYPE_FULL_SCREEN: size = 0 else: size = restore.get('magZoomerBorderSize', settings.magZoomerBorderSize) color = restore.get('magZoomerBorderColor', settings.magZoomerBorderColor) setZoomerObjectSize("border-size", size, False) setZoomerObjectColor("border-color", color, False)
value = restore.get('magSmoothingMode', settings.magSmoothingMode) setZoomerSmoothingType(value, False)
# Now it's safe to display the viewport. # bounds = GNOME.Magnifier.RectBounds(0, 0, viewportWidth, viewportHeight) _zoomer.moveResize(bounds)
# Try to use gnome-mag >= 0.13.1 to allow us to control where to # draw the cursor and crosswires. # try: bonobo.pbclient_set_boolean(_zoomerPBag, "poll-mouse", False) _pollMouseDisabled = True except: _pollMouseDisabled = False
__updateROIDimensions() _magnifier.addZoomRegion(_zoomer)
def __updateROIDimensions(): """Updates the ROI width, height, and maximum and minimum values. """
global _roiWidth global _roiHeight global _minROIX global _minROIY global _maxROIX global _maxROIY
viewport = _zoomerPBag.getValue("viewport").value()
debug.println(debug.LEVEL_ALL, "Magnifier viewport actual: (%d, %d), (%d, %d)" \ % (viewport.x1, viewport.y1, viewport.x2, viewport.y2))
magx = _zoomerPBag.getValue("mag-factor-x").value() magy = _zoomerPBag.getValue("mag-factor-y").value()
_roiWidth = min(_sourceDisplayBounds.x2 - _sourceDisplayBounds.x1, (viewport.x2 - viewport.x1) / magx) _roiHeight = min(_sourceDisplayBounds.y2 - _sourceDisplayBounds.y1, (viewport.y2 - viewport.y1) / magy)
debug.println(debug.LEVEL_ALL, "Magnifier zoomer ROI size actual: width=%d, height=%d)" \ % (_roiWidth, _roiHeight))
_minROIX = _sourceDisplayBounds.x1 + (_roiWidth / 2) _minROIY = _sourceDisplayBounds.y1 + (_roiHeight / 2)
_maxROIX = _sourceDisplayBounds.x2 - (_roiWidth / 2) _maxROIY = _sourceDisplayBounds.y2 - (_roiHeight / 2)
debug.println(debug.LEVEL_ALL, "Magnifier ROI min/max center: (%d, %d), (%d, %d)" \ % (_minROIX, _minROIY, _maxROIX, _maxROIY))
def applySettings(): """Looks at the user settings and applies them to the magnifier."""
global _mouseTracking global _controlTracking global _textTracking global _edgeMargin global _pointerFollowsZoomer global _pointerFollowsFocus
__setupMagnifier(settings.magZoomerType) __setupZoomer() _mouseTracking = settings.magMouseTrackingMode _controlTracking = settings.magControlTrackingMode _textTracking = settings.magTextTrackingMode _edgeMargin = settings.magEdgeMargin _pointerFollowsZoomer = settings.magPointerFollowsZoomer _pointerFollowsFocus = settings.magPointerFollowsFocus
#print "MAGNIFIER PROPERTIES:", _magnifier #__dumpPropertyBag(_magnifier) #print "ZOOMER PROPERTIES:", _zoomer #__dumpPropertyBag(_zoomer)
def magnifyAccessible(event, obj, extents=None): """Sets the region of interest to the upper left of the given accessible, if it implements the Component interface. Otherwise, does nothing.
Arguments: - event: the Event that caused this to be called - obj: the accessible """
global _lastMouseEventWasRoute
if not _initialized: return
# Avoid jerking the display around if the mouse is what ended up causing # this event. We guess this by seeing if this request has come in within # a close period of time. [[[TODO: WDW - this is a hack and really # doesn't belong here. Plus, the delta probably should be adjustable.]]] # currentTime = time.time() if (currentTime - _lastMouseEventTime) < 0.2: # 200 milliseconds return
haveSomethingToMagnify = False
if extents: [x, y, width, height] = extents haveSomethingToMagnify = True elif event and event.type.startswith("object:text-caret-moved"): try: text = obj.queryText() if text and (text.caretOffset >= 0): offset = text.caretOffset if offset == text.characterCount: offset -= 1 [x, y, width, height] = \ text.getCharacterExtents(offset, 0) haveSomethingToMagnify = (width + height > 0) except: haveSomethingToMagnify = False
if haveSomethingToMagnify: if _textTracking == settings.MAG_TRACKING_MODE_CENTERED: __setROICenter(x, y) elif _textTracking == settings.MAG_TRACKING_MODE_PUSH: __setROICursorPush(x, y, width, height, _edgeMargin) return
if not haveSomethingToMagnify: try: extents = obj.queryComponent().getExtents(0) [x, y, width, height] = \ [extents.x, extents.y, extents.width, extents.height] haveSomethingToMagnify = True except: haveSomethingToMagnify = False
if haveSomethingToMagnify: if _pointerFollowsFocus: _lastMouseEventWasRoute = True eventsynthesizer.generateMouseEvent(x, y + height - 1, "abs")
if _controlTracking == settings.MAG_TRACKING_MODE_CENTERED: centerX = x + width/2 centerY = y + height/2
# Be sure that the upper-left corner of the object will still # be visible on the screen. # if width > _roiWidth: centerX = x if height > _roiHeight: centerY = y
__setROICenter(centerX, centerY) elif _controlTracking == settings.MAG_TRACKING_MODE_PUSH: __setROICursorPush(x, y, width, height)
def init(): """Initializes the magnifier, bringing the magnifier up on the display.
Returns True if the initialization procedure was run or False if this module has already been initialized. """
global _initialized global _magnifier
if not _magnifierAvailable: return False
if _initialized: return False
_magnifier = bonobo.get_object("OAFIID:GNOME_Magnifier_Magnifier:0.9", "GNOME/Magnifier/Magnifier")
try: _initialized = True applySettings() pyatspi.Registry.registerEventListener(__onMouseEvent, "mouse:abs")
# Zoom to the upper left corner of the display for now. # __setROICenter(0, 0)
return True except: _initialized = False _magnifier.dispose() raise
def shutdown(): """Shuts down the magnifier module. Returns True if the shutdown procedure was run or False if this module has not been initialized. """
global _initialized global _magnifier
if not _magnifierAvailable: return False
if not _initialized: return False
pyatspi.Registry.deregisterEventListener(__onMouseEvent,"mouse:abs")
# Someone might have killed the magnifier on us. They shouldn't # have done so, but we need to be able to recover if they did. # See http://bugzilla.gnome.org/show_bug.cgi?id=375396. # try: hideSystemPointer(False) _magnifier.clearAllZoomRegions() _magnifier.dispose() except: debug.printException(debug.LEVEL_WARNING)
_magnifier = None
_initialized = False
return True
###################################################################### # # # Convenience functions for "live" changes # # # ######################################################################
def setupMagnifier(position, left=None, top=None, right=None, bottom=None, restore=None): """Creates the magnifier in the position specified.
Arguments: - position: the position/type of zoomer (full, left half, etc.) - left: the left edge of the zoomer (only applicable for custom) - top: the top edge of the zoomer (only applicable for custom) - right: the right edge of the zoomer (only applicable for custom) - bottom: the top edge of the zoomer (only applicable for custom) - restore: a dictionary of all of the settings that should be restored """
if not _initialized: return
global _liveUpdatingMagnifier
_liveUpdatingMagnifier = True __setupMagnifier(position, left, top, right, bottom, restore) __setupZoomer(restore)
def setMagnifierCursor(enabled, customEnabled, size, updateScreen=True): """Sets the cursor.
Arguments: - enabled: Whether or not the cursor should be enabled - customEnabled: Whether or not a custom size has been enabled - size: The size it should be set to - updateScreen: Whether or not to update the screen """
if not _initialized: return try: mag = _zoomerPBag.getValue("mag-factor-x").value() except: mag = settings.magZoomFactor
if enabled: scale = 1.0 * mag else: scale = 0.0
if not (enabled and customEnabled): size = 0
bonobo.pbclient_set_float(_magnifierPBag, "cursor-scale-factor", scale) bonobo.pbclient_set_long(_magnifierPBag, "cursor-size", size)
if updateScreen: _zoomer.markDirty(_roi)
def setMagnifierCrossHair(enabled, updateScreen=True): """Sets the cross-hair.
Arguments: - enabled: Whether or not the cross-hair should be enabled - updateScreen: Whether or not to update the screen """
if not _initialized: return
size = 0 if enabled: size = settings.magCrossHairSize
bonobo.pbclient_set_long(_magnifierPBag, "crosswire-size", size)
if updateScreen: _zoomer.markDirty(_roi)
def setMagnifierCrossHairClip(enabled, updateScreen=True): """Sets the cross-hair clip.
Arguments: - enabled: Whether or not the cross-hair clip should be enabled - updateScreen: Whether or not to update the screen """
if not _initialized: return
bonobo.pbclient_set_boolean(_magnifierPBag, "crosswire-clip", enabled)
if updateScreen: _zoomer.markDirty(_roi)
def setZoomerColorInversion(enabled, updateScreen=True): """Sets the color inversion.
Arguments: - enabled: Whether or not color inversion should be enabled - updateScreen: Whether or not to update the screen """
if not _initialized: return
bonobo.pbclient_set_boolean(_zoomerPBag, "inverse-video", enabled)
if updateScreen: _zoomer.markDirty(_roi)
def setZoomerBrightness(red=0, green=0, blue=0, updateScreen=True): """Increases/Decreases the brightness level by the specified increments. Increments are floats ranging from -1 (black/no brightenss) to 1 (white/100% brightness). 0 means no change.
Arguments: - red: The amount to alter the red brightness level - green: The amount to alter the green brightness level - blue: The amount to alter the blue brightness level - updateScreen: Whether or not to update the screen """
if not _initialized: return
_zoomer.setBrightness(red, green, blue)
if updateScreen: _zoomer.markDirty(_roi)
def setZoomerContrast(red=0, green=0, blue=0, updateScreen=True): """Increases/Decreases the contrast level by the specified increments. Increments are floats ranging from -1 (grey/no contrast) to 1 (white/back/100% contrast). 0 means no change.
Arguments: - red: The amount to alter the red contrast level - green: The amount to alter the green contrast level - blue: The amount to alter the blue contrast level - updateScreen: Whether or not to update the screen """
if not _initialized: return
_zoomer.setContrast(red, green, blue)
if updateScreen: _zoomer.markDirty(_roi)
def setMagnifierObjectSize(magProperty, size, updateScreen=True): """Sets the specified magnifier property to the specified size.
Arguments: - magProperty: The property to set (as a string) - size: The size to apply - updateScreen: Whether or not to update the screen """
if not _initialized: return
bonobo.pbclient_set_long(_magnifierPBag, magProperty, size)
if updateScreen: _zoomer.markDirty(_roi)
def setZoomerObjectSize(magProperty, size, updateScreen=True): """Sets the specified zoomer property to the specified size.
Arguments: - magProperty: The property to set (as a string) - size: The size to apply - updateScreen: Whether or not to update the screen """
if not _initialized: return
if magProperty == "border-size": try: left = right = top = bottom = 0 if orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_RIGHT_HALF: left = size elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_LEFT_HALF: right = size elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_TOP_HALF: bottom = size elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_BOTTOM_HALF: top = size elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_CUSTOM: if _targetDisplayBounds.x1 > _sourceDisplayBounds.x1: left = size if _targetDisplayBounds.x2 < _sourceDisplayBounds.x2: right = size if _targetDisplayBounds.y1 > _sourceDisplayBounds.y1: top = size if _targetDisplayBounds.y2 < _sourceDisplayBounds.y2: bottom = size bonobo.pbclient_set_long(_zoomerPBag, "border-size-left", left) bonobo.pbclient_set_long(_zoomerPBag, "border-size-top", top) bonobo.pbclient_set_long(_zoomerPBag, "border-size-right", right) bonobo.pbclient_set_long(_zoomerPBag, "border-size-bottom", bottom) except: bonobo.pbclient_set_long(_zoomerPBag, "border-size", size) else: bonobo.pbclient_set_long(_zoomerPBag, magProperty, size)
if updateScreen: _zoomer.markDirty(_roi)
def setZoomerObjectColor(magProperty, colorSetting, updateScreen=True): """Sets the specified zoomer property to the specified color.
Arguments: - magProperty: The property to set (as a string) - colorSetting: The Orca color setting to apply - updateScreen: Whether or not to update the screen """
if not _initialized: return
colorPreference = gtk.gdk.color_parse(colorSetting)
# Convert the colorPreference string to something we can use. # The main issue here is that the color preferences are saved # as 4 byte values per color. We only need 2 bytes, so we # get rid of the bottom 8 bits. # colorPreference.red = colorPreference.red >> 8 colorPreference.blue = colorPreference.blue >> 8 colorPreference.green = colorPreference.green >> 8 colorString = "0x%02X%02X%02X" \ % (colorPreference.red, colorPreference.green, colorPreference.blue)
toChange = _zoomerPBag.getValue(magProperty) _zoomerPBag.setValue(magProperty, ORBit.CORBA.Any(toChange.typecode(), long(colorString, 0))) if updateScreen: _zoomer.markDirty(_roi)
def setMagnifierObjectColor(magProperty, colorSetting, updateScreen=True): """Sets the specified magnifier property to the specified color.
Arguments: - magProperty: The property to set (as a string) - colorSetting: The Orca color setting to apply - updateScreen: Whether or not to update the screen """
if not _initialized: return
colorPreference = gtk.gdk.color_parse(colorSetting)
# Convert the colorPreference string to something we can use. # The main issue here is that the color preferences are saved # as 4 byte values per color. We only need 2 bytes, so we # get rid of the bottom 8 bits. # colorPreference.red = colorPreference.red >> 8 colorPreference.blue = colorPreference.blue >> 8 colorPreference.green = colorPreference.green >> 8 colorString = "0x%02X%02X%02X" \ % (colorPreference.red, colorPreference.green, colorPreference.blue)
toChange = _magnifierPBag.getValue(magProperty) _magnifierPBag.setValue(magProperty, ORBit.CORBA.Any(toChange.typecode(), long(colorString, 0))) if updateScreen: _zoomer.markDirty(_roi)
def setZoomerMagFactor(x, y, updateScreen=True): """Sets the magnification level.
Arguments: - x: The horizontal magnification level - y: The vertical magnification level - updateScreen: Whether or not to update the screen """
global _minROIX global _minROIY
if not _initialized: return
[oldX, oldY] = _zoomer.getMagFactor()
_zoomer.setMagFactor(x, y)
if updateScreen: __updateROIDimensions() if (oldX > x) and (x < 1.5): _minROIX = _sourceDisplayBounds.x1 _minROIY = _sourceDisplayBounds.y1 __setROI(GNOME.Magnifier.RectBounds(_minROIX, _minROIY, _minROIX + _roiWidth, _minROIY + _roiHeight)) else: extents = orca_state.locusOfFocus.queryComponent().getExtents(0) __setROICenter(extents.x, extents.y)
def setZoomerSmoothingType(smoothingType, updateScreen=True): """Sets the zoomer's smoothing type.
Arguments: - smoothingType: The type of smoothing to use - updateScreen: Whether or not to update the screen """
if not _initialized: return
if smoothingType == settings.MAG_SMOOTHING_MODE_BILINEAR: string = "bilinear" else: string = "None"
try: bonobo.pbclient_set_string(_zoomerPBag, "smoothing-type", string) except: pass
if updateScreen: _zoomer.markDirty(_roi)
def setZoomerColorFilter(colorFilter, updateScreen=True): """Sets the zoomer's color filter.
Arguments: - colorFilter: The color filter to apply - updateScreen: Whether or not to update the screen """
if not _initialized or not isFilteringCapable(): return
if colorFilter == settings.MAG_COLOR_FILTERING_MODE_SATURATE_RED: toApply = _zoomer.COLORBLIND_FILTER_T_SELECTIVE_SATURATE_RED elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_SATURATE_GREEN: toApply = _zoomer.COLORBLIND_FILTER_T_SELECTIVE_SATURATE_GREEN elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_SATURATE_BLUE: toApply = _zoomer.COLORBLIND_FILTER_T_SELECTIVE_SATURATE_BLUE elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_DESATURATE_RED: toApply = _zoomer.COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_RED elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_DESATURATE_GREEN: toApply = _zoomer.COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_GREEN elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_DESATURATE_BLUE: toApply = _zoomer.COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_BLUE elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_NEGATIVE_HUE_SHIFT: toApply = _zoomer.COLORBLIND_FILTER_T_HUE_SHIFT_NEGATIVE elif colorFilter == settings.MAG_COLOR_FILTERING_MODE_POSITIVE_HUE_SHIFT: toApply = _zoomer.COLORBLIND_FILTER_T_HUE_SHIFT_POSITIVE else: toApply = _zoomer.COLORBLIND_FILTER_T_NO_FILTER
colorFilter = _zoomerPBag.getValue("color-blind-filter") _zoomerPBag.setValue( "color-blind-filter", ORBit.CORBA.Any( colorFilter.typecode(), toApply))
if updateScreen: _zoomer.markDirty(_roi)
def hideSystemPointer(hidePointer): """Hide or show the system pointer.
Arguments: -hidePointer: If True, hide the system pointer, otherwise show it. """
# Depends upon new functionality in gnome-mag, so just catch the # exception if this functionality isn't there. # try: if hidePointer: _magnifier.hideCursor() else: _magnifier.showCursor() except: debug.printException(debug.LEVEL_FINEST)
def isFullScreenCapable(): """Returns True if we are capable of doing full screen (i.e. whether composite is being used. """
try: capable = _magnifier.fullScreenCapable() except: capable = False
return capable
def isFilteringCapable(): """Returns True if we're able to take advantage of libcolorblind's color filtering. """
try: capable = _magnifier.supportColorblindFilters() except: capable = False
return capable
def updateMouseTracking(newMode): """Updates the mouse tracking mode.
Arguments: -newMode: The new mode to use. """
global _mouseTracking _mouseTracking = newMode
def updateControlTracking(newMode): """Updates the control tracking mode.
Arguments: -newMode: The new mode to use. """
global _controlTracking _controlTracking = newMode
def updateTextTracking(newMode): """Updates the text tracking mode.
Arguments: -newMode: The new mode to use. """
global _textTracking _textTracking = newMode
def updateEdgeMargin(amount): """Updates the edge margin
Arguments: -amount: The new margin to use, in pixels. """
global _edgeMargin _edgeMargin = amount
def updatePointerFollowsFocus(enabled): """Updates the pointer follows focus setting.
Arguments: -enabled: whether or not pointer follows focus should be enabled. """
global _pointerFollowsFocus _pointerFollowsFocus = enabled
def updatePointerFollowsZoomer(enabled): """Updates the pointer follows zoomer setting.
Arguments: -enabled: whether or not pointer follows zoomer should be enabled. """
global _pointerFollowsZoomer _pointerFollowsZoomer = enabled
def finishLiveUpdating(): """Restores things that were altered via a live update."""
global _liveUpdatingMagnifier global _mouseTracking global _controlTracking global _textTracking global _edgeMargin global _pointerFollowsFocus global _pointerFollowsZoomer
_liveUpdatingMagnifier = False _mouseTracking = settings.magMouseTrackingMode _controlTracking = settings.magControlTrackingMode _textTracking = settings.magTextTrackingMode _edgeMargin = settings.magEdgeMargin _pointerFollowsFocus = settings.magPointerFollowsFocus _pointerFollowsZoomer = settings.magPointerFollowsZoomer
if settings.enableMagnifier: setupMagnifier(settings.magZoomerType) init() else: shutdown()
###################################################################### # # # Input Event Handlers # # # ######################################################################
def toggleColorEnhancements(script=None, inputEvent=None): """Toggles the color enhancements on/off."""
if not _initialized: return
# We don't want to stomp on a command-altered magnification level. # [levelX, levelY] = _zoomer.getMagFactor() normal = {'enableMagZoomerColorInversion': False, 'magBrightnessLevelRed': 0, 'magBrightnessLevelGreen': 0, 'magBrightnessLevelBlue': 0, 'magContrastLevelRed': 0, 'magContrastLevelGreen': 0, 'magContrastLevelBlue': 0, 'magColorFilteringMode': settings.MAG_COLOR_FILTERING_MODE_NONE, 'magSmoothingMode': settings.MAG_SMOOTHING_MODE_BILINEAR, 'magZoomerBorderColor': '#000000', 'magZoomFactor': levelX}
if orca_state.colorEnhancementsEnabled: __setupZoomer(restore = normal) # Translators: "color enhancements" are changes users can # make to the appearance of the screen to make things easier # to see, such as inverting the colors or applying a tint. # speech.speak(_("Color enhancements disabled.")) else: toRestore = {'magZoomFactor': levelX} __setupZoomer(restore = toRestore) # Translators: "color enhancements" are changes users can # make to the appearance of the screen to make things easier # to see, such as inverting the colors or applying a tint. # speech.speak(_("Color enhancements enabled."))
orca_state.colorEnhancementsEnabled = \ not orca_state.colorEnhancementsEnabled
return True
def toggleMouseEnhancements(script=None, inputEvent=None): """Toggles the mouse enhancements on/off."""
if not _initialized: return
if orca_state.mouseEnhancementsEnabled: setMagnifierCrossHair(False, False) setMagnifierObjectColor("cursor-color", "#000000", False) setMagnifierCursor(True, False, 0) # Translators: "mouse enhancements" are changes users can # make to the appearance of the mouse pointer to make it # easier to see, such as increasing its size, changing its # color, and surrounding it with crosshairs. # speech.speak(_("Mouse enhancements disabled.")) else: # We normally toggle "on" what the user has enabled by default. # However, if the user's default settings are to disable all mouse # enhancements "on" and "off" are the same thing. If that is the # case and this command is being used, the user probably expects # to see *something* change. We don't know what, so enable both # the cursor and the cross-hairs. # cursorEnable = settings.enableMagCursor crossHairEnable = settings.enableMagCrossHair if not (cursorEnable or crossHairEnable): cursorEnable = True crossHairEnable = True
setMagnifierCursor(cursorEnable, settings.enableMagCursorExplicitSize, settings.magCursorSize, False) setMagnifierObjectColor("cursor-color", settings.magCursorColor, False) setMagnifierObjectColor("crosswire-color", settings.magCrossHairColor, False) setMagnifierCrossHairClip(settings.enableMagCrossHairClip, False) setMagnifierCrossHair(crossHairEnable) # Translators: "mouse enhancements" are changes users can # make to the appearance of the mouse pointer to make it # easier to see, such as increasing its size, changing its # color, and surrounding it with crosshairs. # speech.speak(_("Mouse enhancements enabled."))
orca_state.mouseEnhancementsEnabled = \ not orca_state.mouseEnhancementsEnabled return True
def increaseMagnification(script=None, inputEvent=None): """Increases the magnification level."""
if not _initialized: return
[levelX, levelY] = _zoomer.getMagFactor()
# Move in increments that are sensible based on the current level of # magnification. # if 1 <= levelX < 4: increment = 0.25 elif 4 <= levelX < 7: increment = 0.5 else: increment = 1
newLevel = levelX + increment if newLevel <= 16: setZoomerMagFactor(newLevel, newLevel) speech.speak(str(newLevel))
return True
def decreaseMagnification(script=None, inputEvent=None): """Decreases the magnification level."""
if not _initialized: return
[levelX, levelY] = _zoomer.getMagFactor()
# Move in increments that are sensible based on the current level of # magnification. # if 1 <= levelX < 4: increment = 0.25 elif 4 <= levelX < 7: increment = 0.5 else: increment = 1
newLevel = levelX - increment if newLevel >= 1: setZoomerMagFactor(newLevel, newLevel) speech.speak(str(newLevel))
return True
def toggleMagnifier(script=None, inputEvent=None): """Toggles the magnifier."""
if not _initialized: init() # Translators: this is the message spoken when a user enables the # magnifier. In addition to screen magnification, the user's # preferred colors and mouse customizations are loaded. # speech.speak(_("Magnifier enabled.")) else: shutdown() # Translators: this is the message spoken when a user disables the # magnifier, restoring the screen contents to their normal colors # and sizes. # speech.speak(_("Magnifier disabled."))
return True
def cycleZoomerType(script=None, inputEvent=None): """Allows the user to cycle through the available zoomer types."""
if not _initialized: return
# There are 6 possible zoomer types # orca_state.zoomerType += 1
if orca_state.zoomerType >= 6: orca_state.zoomerType = 0
if orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_FULL_SCREEN \ and not _fullScreenCapable: orca_state.zoomerType += 1
# We don't want to stomp on any command-altered settings # toRestore = {}
[levelX, levelY] = _zoomer.getMagFactor() if levelX != settings.magZoomFactor: toRestore['magZoomFactor'] = levelX
if not orca_state.colorEnhancementsEnabled: toRestore.update(\ {'enableMagZoomerColorInversion': False, 'magBrightnessLevelRed': 0, 'magBrightnessLevelGreen': 0, 'magBrightnessLevelBlue': 0, 'magContrastLevelRed': 0, 'magContrastLevelGreen': 0, 'magContrastLevelBlue': 0, 'magColorFilteringMode': settings.MAG_COLOR_FILTERING_MODE_NONE, 'magSmoothingMode': settings.MAG_SMOOTHING_MODE_BILINEAR, 'magZoomerBorderColor': '#000000'})
setupMagnifier(orca_state.zoomerType, restore = toRestore)
if not orca_state.mouseEnhancementsEnabled: setMagnifierCrossHair(False) setMagnifierObjectColor("cursor-color", settings.magCursorColor, False) setMagnifierCursor(False, False, 0)
if orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_FULL_SCREEN: if _fullScreenCapable: # Translators: magnification will use the full screen. # zoomerType = _("Full Screen") else: # Translators: the user attempted to switch to full screen # magnification, but his/her system doesn't support it. # zoomerType = _("Full Screen mode unavailable") elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_TOP_HALF: # Translators: magnification will use the top half of the screen. # zoomerType = _("Top Half") elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_BOTTOM_HALF: # Translators: magnification will use the bottom half of the screen. # zoomerType = _("Bottom Half") elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_LEFT_HALF: # Translators: magnification will use the left half of the screen. # zoomerType = _("Left Half") elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_RIGHT_HALF: # Translators: magnification will use the right half of the screen. # zoomerType = _("Right Half") elif orca_state.zoomerType == settings.MAG_ZOOMER_TYPE_CUSTOM: # Translators: the user has selected a custom area of the screen # to use for magnification. # zoomerType = _("Custom") else: # This shouldn't happen, but just in case.... zoomerType = ""
speech.speak(zoomerType)
return True
|