/usr/share/pyshared/Onboard/KeyCommon.py is in onboard 0.97.0-0ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | # -*- coding: UTF-8 -*-
"""
KeyCommon hosts the abstract classes for the various types of Keys.
UI-specific keys should be defined in KeyGtk or KeyKDE files.
"""
from __future__ import division, print_function, unicode_literals
from Onboard.utils import Rect, brighten
from Onboard.Layout import LayoutItem
### Logging ###
import logging
_logger = logging.getLogger("KeyCommon")
###############
### Config Singleton ###
from Onboard.Config import Config
config = Config()
########################
BASE_PANE_TAB_HEIGHT = 40
(CHAR_ACTION, KEYSYM_ACTION, KEYCODE_ACTION, MODIFIER_ACTION, MACRO_ACTION,
SCRIPT_ACTION, KEYPRESS_NAME_ACTION, BUTTON_ACTION) = list(range(1,9))
class KeyCommon(LayoutItem):
"""
library-independent key class. Specific rendering options
are stored elsewhere.
"""
# indexed id for key specific theme tweaks
# e.g. theme_id=DELE.1 (with id=DELE)
theme_id = None
# Type of action to do when key is pressed.
action_type = None
# Data used in action.
action = None
# Keys that stay stuck when pressed like modifiers.
sticky = False
# True when key is being hovered over (not implemented yet)
prelight = False
# True when key is being pressed.
pressed = False
# True when key stays 'on'
active = False
# True when key is sticky and pressed twice.
locked = False
# True when Onboard is in scanning mode and key is highlighted
scanned = False
# False if the key should be ignored by the scanner
scannable = True
# Determines scanning order
scan_priority = 0
# Size to draw the label text in Pango units
font_size = 1
# Index in labels that is currently displayed by this key
label_index = 0
# Labels which are displayed by this key
labels = None
# Image displayed by this key (optional)
image_filename = None
# Cached pixbuf object of the image
image_pixbuf = None
# horizontal label alignment
label_x_align = config.DEFAULT_LABEL_X_ALIGN
# vertical label alignment
label_y_align = config.DEFAULT_LABEL_Y_ALIGN
# tooltip text
tooltip = None
###################
def __init__(self):
LayoutItem.__init__(self)
def configure_label(self, mods):
if mods[1]:
if mods[128] and self.labels[4]:
self.label_index = 4
elif self.labels[2]:
self.label_index = 2
elif self.labels[1]:
self.label_index = 1
else:
self.label_index = 0
elif mods[128] and self.labels[3]:
self.label_index = 3
elif mods[2]:
if self.labels[1]:
self.label_index = 1
else:
self.label_index = 0
else:
self.label_index = 0
def draw_label(self, context = None):
raise NotImplementedError()
def get_label(self):
return self.labels[self.label_index]
def is_active(self):
return not self.action_type is None
def get_id(self):
return ""
def set_id(self, value):
"""
The theme id has the form <id>.<arbitrary identifier>, where
the identifier should be a descripttion of the location of
the key, e.g. 'DELE.next-to-backspace'.
Don't use layout names or layer ids for the theme id, layouts
may be copied and renamed by users.
"""
self.id = value.split(".")[0]
self.theme_id = value
def is_layer_button(self):
return self.id.startswith("layer")
def is_modifier(self):
"""
Modifiers are all latchable/lockable keys:
"LWIN", "RTSH", "LFSH", "RALT", "LALT",
"RCTL", "LCTL", "CAPS", "NMLK"
"""
return self.sticky
def is_pressed_only(self):
return self.pressed and not (self.active or \
self.locked or \
self.scanned)
def get_layer_index(self):
assert(self.is_layer_button())
return int(self.id[5:])
class RectKeyCommon(KeyCommon):
""" An abstract class for rectangular keyboard buttons """
def __init__(self, id, border_rect):
KeyCommon.__init__(self)
self.id = id
self.colors = {}
self.context.log_rect = border_rect \
if not border_rect is None else Rect()
def get_id(self):
return self.id
def draw(self, context = None):
pass
def align_label(self, label_size, key_size):
""" returns x- and yoffset of the aligned label """
xoffset = self.label_x_align * (key_size[0] - label_size[0])
yoffset = self.label_y_align * (key_size[1] - label_size[1])
return xoffset, yoffset
def get_fill_color(self):
return self._get_color("fill")
def get_stroke_color(self):
return self._get_color("stroke")
def get_label_color(self):
return self._get_color("label")
def get_dwell_progress_color(self):
return self._get_color("dwell-progress")
def _get_color(self, element):
color_key = (element, self.prelight, self.pressed,
self.active, self.locked,
self.sensitive, self.scanned)
rgba = self.colors.get(color_key)
if not rgba:
if self.color_scheme:
rgba = self.color_scheme.get_key_rgba(self, element)
elif element == "label":
rgba = [0.0, 0.0, 0.0, 1.0]
else:
rgba = [1.0, 1.0, 1.0, 1.0]
self.colors[color_key] = rgba
return rgba
def get_fullsize_rect(self):
""" Get bounding box of the key at 100% size in logical coordinates """
rect = LayoutItem.get_rect(self)
return rect
def get_canvas_fullsize_rect(self):
""" Get bounding box of the key at 100% size in canvas coordinates """
return self.context.log_to_canvas_rect(self.get_fullsize_rect())
def get_rect(self):
""" Get bounding box in logical coordinates """
rect = self.get_fullsize_rect()
# fake physical key action
if self.pressed:
key_style = config.theme_settings.key_style
if key_style == "dish":
k = 0.45
rect.x += k
rect.y += 2 * k
rect.w - 2 * k
rect.h - k
# shrink keys to key_size
#
size = config.theme_settings.key_size / 100.0
bx = rect.w * (1.0 - size) / 2.0
by = rect.h * (1.0 - size) / 2.0
# keys with aspect < 1.0, e.g. click, move, number block + and enter
if rect.h > rect.w:
by = bx
# keys with aspect > 1.0, e.g. space, shift
if rect.h < rect.w:
bx = by
return rect.deflate(bx, by)
def get_label_rect(self):
""" Label area in logical coordinates """
rect = self.get_rect()
if config.theme_settings.key_style == "dish":
rect = rect.deflate(*config.DISH_KEY_BORDER)
rect.y -= config.DISH_KEY_Y_OFFSET
return rect
else:
return rect.deflate(*config.LABEL_MARGIN)
|