Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Crouch <bartius.crouch@gmail.com>2012-01-05 19:24:18 +0400
committerBart Crouch <bartius.crouch@gmail.com>2012-01-05 19:24:18 +0400
commitd827762474e90e9db682e5c0694255777fc473c2 (patch)
tree76aaf350eae039bd9f0efa6363ab0266f62da219 /space_view3d_screencast_keys.py
parent188d0026b4bcab85c056831fc32f1dab4c4b1066 (diff)
pep8 compliancy
general code cleaning reset multiplier after text has disappeared support for mousewheel in icon-display improved fading, using a timer
Diffstat (limited to 'space_view3d_screencast_keys.py')
-rw-r--r--space_view3d_screencast_keys.py324
1 files changed, 169 insertions, 155 deletions
diff --git a/space_view3d_screencast_keys.py b/space_view3d_screencast_keys.py
index be431f41..8494a9ff 100644
--- a/space_view3d_screencast_keys.py
+++ b/space_view3d_screencast_keys.py
@@ -16,12 +16,14 @@
#
# ##### END GPL LICENSE BLOCK #####
+# <pep8 compliant>
+
bl_info = {
'name': 'Screencast Keys',
- 'author': 'Paulo Gomes, Bart Crouch, John E. Herrenyo',
- 'version': (1, 4),
- 'blender': (2, 5, 9),
- 'api': 39933,
+ 'author': 'Paulo Gomes, Bart Crouch, John E. Herrenyo, Gaia Clary',
+ 'version': (1, 5),
+ 'blender': (2, 6, 1),
+ 'api': 43073,
'location': 'View3D > Properties panel > Screencast Keys',
'warning': '',
'description': 'Display keys pressed in the 3d-view, '\
@@ -33,53 +35,47 @@ bl_info = {
'category': '3D View'}
-# #####
-#
-# Modification history:
-# - Version 1,4
-# - 07-sep-2011 (Gaia Clary):
-# - settings now stored in blend file
-# - grouping mouse&text
-# - mouse_size and font_size separated
-# - boundingBox for improved readability.
-# - missing mouse "release" clicks added
-#
-# ####
-
-
import bgl
import blf
import bpy
import time
+
MOUSE_RATIO = 0.535
+
def getDisplayLocation(context):
- sc = context.scene
- mouse_size = sc.screencast_keys_mouse_size
- pos_x = int( (context.region.width - mouse_size*MOUSE_RATIO) * sc.screencast_keys_pos_x / 100)
- pos_y = int( (context.region.height - mouse_size) * sc.screencast_keys_pos_y / 100)
- return pos_x, pos_y
+ scene = context.scene
+ mouse_size = scene.screencast_keys_mouse_size
+
+ pos_x = int( (context.region.width - mouse_size * MOUSE_RATIO) * \
+ scene.screencast_keys_pos_x / 100)
+ pos_y = int( (context.region.height - mouse_size) *
+ scene.screencast_keys_pos_y / 100)
+
+ return(pos_x, pos_y)
+
def getBoundingBox(current_width, current_height, new_text):
w,h = blf.dimensions(0,new_text)
if w > current_width:
current_width = w
current_height += h
- return current_width, current_height
+
+ return(current_width, current_height)
+
def draw_callback_px(self, context):
wm = context.window_manager
sc = context.scene
if not wm.screencast_keys_keys:
return
-
+
font_size = sc.screencast_keys_font_size
mouse_size = sc.screencast_keys_mouse_size
link = sc.screencast_keys_link
pos_x, pos_y = getDisplayLocation(context)
-
# draw text in the 3d-view
# ========================
blf.size(0, sc.screencast_keys_font_size, 72)
@@ -107,17 +103,17 @@ def draw_callback_px(self, context):
alpha = min(1.0, max(0.0, 2 * (2 - label_time)))
bgl.glColor4f(r, g, b, alpha)
blf.draw(0, self.key[i])
- text_width, text_height = getBoundingBox(text_width, text_height, self.key[i])
+ text_width, text_height = getBoundingBox(text_width, text_height,
+ self.key[i])
row_count += 1
- final = i
+ final = i + 1
else:
break
# get rid of status texts that aren't displayed anymore
- self.key = self.key[:final+1]
- self.time = self.time[:final+1]
-
-
+ self.key = self.key[:final]
+ self.time = self.time[:final]
+
# draw graphical representation of the mouse
# ==========================================
if sc.screencast_keys_mouse == 'icon':
@@ -132,49 +128,32 @@ def draw_callback_px(self, context):
if shape:
alpha = min(1.0, max(0.0, 2 * (2 - click_time)))
draw_mouse(context, shape, "filled", alpha)
- final = i
+ final = i + 1
else:
break
-
# get rid of mouse clicks that aren't displayed anymore
- self.mouse = self.mouse[:final+1]
- self.mouse_time = self.mouse_time[:final+1]
-
+ self.mouse = self.mouse[:final]
+ self.mouse_time = self.mouse_time[:final]
# Draw border (if enabled)
# ========================
- if link == True and row_count > 0:
- bgl.glEnable(bgl.GL_BLEND)
- bgl.glBegin(bgl.GL_QUADS)
- bgl.glLineWidth(2)
- bgl.glColor4f(r, g, b, 0.2)
- drawRectangle(pos_x , pos_y , text_width+mouse_size*MOUSE_RATIO*1.3 , max(mouse_size, font_size*row_count), 4 )
- bgl.glEnd()
- bgl.glBegin(bgl.GL_LINES)
- bgl.glColor4f(r, g, b, alpha )
- drawRectangle(pos_x , pos_y , text_width+mouse_size*MOUSE_RATIO*1.3 , max(mouse_size, font_size*row_count), 4 )
- bgl.glEnd()
-
-
-# Draw a line. currently not used.
-def drawLinef(from_x, from_y, to_x, to_y):
- bgl.glVertex2f(from_x, from_y)
- bgl.glVertex2f(to_x, to_y)
-
-
-# Draw a rectangle. Currently not used
-def drawRectangle (ox, oy, ow, oh, padding=0):
-
- x = ox - 2*padding
- y = oy - padding
- w = ow + 4 * padding
- h = oh + 2 * padding
-
- drawLinef(x, y, x+w, y)
- drawLinef(x+w, y, x+w, y+h)
- drawLinef(x+w, y+h, x , y+h)
- drawLinef(x , y+h, x , y)
+ if link and row_count > 0:
+ padding = 8
+ x0 = max(0, pos_x - padding)
+ y0 = max(0, pos_y - padding)
+ x1 = pos_x + text_width + mouse_size * MOUSE_RATIO * 1.3 + padding
+ y1 = pos_y + max(mouse_size, font_size * row_count) + padding
+ positions = [[x0, y0], [x0, y1], [x1, y1], [x1, y0]]
+ settings = [[bgl.GL_QUADS, min(0.2, alpha)], [bgl.GL_LINE_LOOP, alpha]]
+
+ for mode, box_alpha in settings:
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glBegin(mode)
+ bgl.glColor4f(r, g, b, box_alpha)
+ for v1, v2 in positions:
+ bgl.glVertex2f(v1, v2)
+ bgl.glEnd()
def draw_mouse(context, shape, style, alpha):
@@ -185,7 +164,7 @@ def draw_mouse(context, shape, style, alpha):
link = sc.screencast_keys_link
pos_x, pos_y = getDisplayLocation(context)
- if link==True:
+ if link:
offset_x = pos_x
else:
offset_x = context.region.width - pos_x - (mouse_size * MOUSE_RATIO)
@@ -193,7 +172,7 @@ def draw_mouse(context, shape, style, alpha):
offset_y = pos_y
if font_size > mouse_size:
offset_y += (font_size - mouse_size) / 2
-
+
shape_data = get_shape_data(shape)
bgl.glTranslatef(offset_x, offset_y, 0)
@@ -201,15 +180,14 @@ def draw_mouse(context, shape, style, alpha):
# color
r, g, b = sc.screencast_keys_color
bgl.glEnable(bgl.GL_BLEND)
- #bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA)
- #bgl.glColor4f(r, g, b, alpha)
-
+ bgl.glColor4f(r, g, b, alpha)
+
# inner shape for filled style
if style == "filled":
inner_shape = []
for i in shape_data:
inner_shape.append(i[0])
-
+
# outer shape
for i in shape_data:
shape_segment = i
@@ -217,16 +195,14 @@ def draw_mouse(context, shape, style, alpha):
shape_segment[1] = [mouse_size * k for k in shape_segment[1]]
shape_segment[2] = [mouse_size * k for k in shape_segment[2]]
shape_segment[3] = [mouse_size * k for k in shape_segment[3]]
-
+
# create the buffer
shape_buffer = bgl.Buffer(bgl.GL_FLOAT, [4, 3], shape_segment)
-
+
# create the map and draw the triangle fan
bgl.glMap1f(bgl.GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, shape_buffer)
bgl.glEnable(bgl.GL_MAP1_VERTEX_3)
- bgl.glColor4f(r, g, b, alpha)
-
if style == "outline":
bgl.glBegin(bgl.GL_LINE_STRIP)
else: # style == "filled"
@@ -234,22 +210,21 @@ def draw_mouse(context, shape, style, alpha):
for j in range(10):
bgl.glEvalCoord1f(j / 10.0)
x, y, z = shape_segment[3]
-
+
# make sure the last vertex is indeed the last one, to avoid gaps
bgl.glVertex3f(x, y, z)
bgl.glEnd()
bgl.glDisable(bgl.GL_MAP1_VERTEX_3)
-
+
# draw interior
if style == "filled":
- bgl.glColor4f(r, g, b, alpha)
bgl.glBegin(bgl.GL_TRIANGLE_FAN)
for i in inner_shape:
j = [mouse_size * k for k in i]
x, y, z = j
bgl.glVertex3f(x, y, z)
bgl.glEnd()
-
+
bgl.glTranslatef(-offset_x, -offset_y, 0)
@@ -339,6 +314,44 @@ def get_shape_data(shape):
[0.303, 0.833, 0.0],
[0.302, 0.817, 0.0],
[0.301, 0.8, 0.0]]]
+ elif shape == "middle_down_button":
+ data = [[[0.301, 0.8, 0.0],
+ [0.298, 0.768, 0.0],
+ [0.231, 0.768, 0.0],
+ [0.228, 0.8, 0.0]],
+ [[0.228, 0.8, 0.0],
+ [0.226, 0.817, 0.0],
+ [0.225, 0.833, 0.0],
+ [0.224, 0.85, 0.0]],
+ [[0.224, 0.85, 0.0],
+ [0.264, 0.873, 0.0],
+ [0.284, 0.873, 0.0],
+ [0.305, 0.85, 0.0]],
+ [[0.305, 0.85, 0.0],
+ [0.303, 0.833, 0.0],
+ [0.302, 0.817, 0.0],
+ [0.301, 0.8, 0.0]]]
+ elif shape == "middle_up_button":
+ data = [[[0.270, 0.873, 0.0],
+ [0.264, 0.873, 0.0],
+ [0.222, 0.877, 0.0],
+ [0.224, 0.9, 0.0]],
+ [[0.224, 0.9, 0.0],
+ [0.225, 0.917, 0.0],
+ [0.226, 0.933, 0.0],
+ [0.228, 0.95, 0.0]],
+ [[0.228, 0.95, 0.0],
+ [0.231, 0.982, 0.0],
+ [0.298, 0.982, 0.0],
+ [0.301, 0.95, 0.0]],
+ [[0.301, 0.95, 0.0],
+ [0.302, 0.933, 0.0],
+ [0.303, 0.917, 0.0],
+ [0.305, 0.9, 0.0]],
+ [[0.305, 0.9, 0.0],
+ [0.307, 0.877, 0.0],
+ [0.284, 0.873, 0.0],
+ [0.270, 0.873, 0.0]]]
elif shape == "right_button":
data = [[[0.375, 0.763, 0.0],
[0.402, 0.755, 0.0],
@@ -364,20 +377,25 @@ def get_shape_data(shape):
[0.334, 0.77, 0.0],
[0.348, 0.771, 0.0],
[0.375, 0.763, 0.0]]]
-
+
return(data)
# return the shape that belongs to the given event
def map_mouse_event(event):
shape = False
-
+
if event == 'LEFTMOUSE':
shape = "left_button"
elif event == 'MIDDLEMOUSE':
shape = "middle_button"
elif event == 'RIGHTMOUSE':
shape = "right_button"
+ elif event == 'WHEELDOWNMOUSE':
+ shape = "middle_down_button"
+ elif event == 'WHEELUPMOUSE':
+ shape = "middle_up_button"
+
return(shape)
@@ -387,34 +405,38 @@ class ScreencastKeysStatus(bpy.types.Operator):
bl_description = "Display keys pressed in the 3D-view"
last_activity = 'NONE'
+ _handle = None
+ _timer = None
+
def modal(self, context, event):
if context.area:
context.area.tag_redraw()
- sc = context.scene
+
+ if event.type == 'TIMER':
+ # no input, so no need to change the display
+ return {'PASS_THROUGH'}
+
+ scene = context.scene
# keys that shouldn't show up in the 3d-view
mouse_keys = ['MOUSEMOVE','MIDDLEMOUSE','LEFTMOUSE',
'RIGHTMOUSE', 'WHEELDOWNMOUSE','WHEELUPMOUSE']
ignore_keys = ['LEFT_SHIFT', 'RIGHT_SHIFT', 'LEFT_ALT',
'RIGHT_ALT', 'LEFT_CTRL', 'RIGHT_CTRL', 'TIMER']
- if sc.screencast_keys_mouse != 'text':
+ if scene.screencast_keys_mouse != 'text':
ignore_keys.extend(mouse_keys)
-
- #if (event.value != "NOTHING" and event.value != "PRESS"):
- # print (event.value, event.type, "Previous activity was: ", self.last_activity)
-
- if event.value == 'PRESS' or (event.value == 'RELEASE' and self.last_activity == 'KEYBOARD' and event.type in mouse_keys ) :
+ if event.value == 'PRESS' or (event.value == 'RELEASE' and \
+ self.last_activity == 'KEYBOARD' and event.type in mouse_keys):
# add key-press to display-list
sc_keys = []
-
if event.ctrl:
sc_keys.append("Ctrl ")
if event.alt:
sc_keys.append("Alt ")
if event.shift:
sc_keys.append("Shift ")
-
+
sc_amount = ""
if self.key:
@@ -430,14 +452,15 @@ class ScreencastKeysStatus(bpy.types.Operator):
sc_amount = " x2"
del self.key[0]
del self.time[0]
-
+
if event.type not in ignore_keys:
#print("Recorded as key")
sc_keys.append(event.type)
self.key.insert(0, "+ ".join(sc_keys) + sc_amount)
self.time.insert(0, time.time())
-
- elif event.type in mouse_keys and sc.screencast_keys_mouse == 'icon':
+
+ elif event.type in mouse_keys and \
+ scene.screencast_keys_mouse == 'icon':
#print("Recorded as mouse press")
self.mouse.insert(0, event.type)
self.mouse_time.insert(0, time.time())
@@ -447,22 +470,22 @@ class ScreencastKeysStatus(bpy.types.Operator):
else:
self.last_activity = 'KEYBOARD'
#print("Last activity set to:", self.last_activity)
-
+
if not context.window_manager.screencast_keys_keys:
# stop script
+ context.window_manager.event_timer_remove(self._timer)
context.region.callback_remove(self._handle)
return {'CANCELLED'}
return {'PASS_THROUGH'}
-
def cancel(self, context):
if context.window_manager.screencast_keys_keys:
+ context.window_manager.event_timer_remove(self._timer)
context.region.callback_remove(self._handle)
context.window_manager.screencast_keys_keys = False
return {'CANCELLED'}
-
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
if context.window_manager.screencast_keys_keys == False:
@@ -475,6 +498,8 @@ class ScreencastKeysStatus(bpy.types.Operator):
self.mouse_time = []
self._handle = context.region.callback_add(draw_callback_px,
(self, context), 'POST_PIXEL')
+ self._timer = context.window_manager.event_timer_add(0.05,
+ context.window)
return {'RUNNING_MODAL'}
else:
# operator is called again, stop displaying
@@ -491,62 +516,52 @@ class ScreencastKeysStatus(bpy.types.Operator):
# properties used by the script
def init_properties():
-
- sc = bpy.types.Scene
+ scene = bpy.types.Scene
wm = bpy.types.WindowManager
- sc.screencast_keys_pos_x = bpy.props.IntProperty(
- name="Pos X",
- description="Margin on the x axis",
- default=5,
- min=0,
- max=100)
-
- sc.screencast_keys_pos_y = bpy.props.IntProperty(
- name="Pos Y",
- description="Margin on the y axis",
- default=10,
- min=0,
- max=100)
-
- sc.screencast_keys_font_size = bpy.props.IntProperty(
- name="Font",
- description="Fontsize",
- default=20, min=10, max=150)
-
- sc.screencast_keys_mouse_size = bpy.props.IntProperty(
- name="Mouse",
- description="Mousesize",
- default=60, min=10, max=150)
-
-
- sc.screencast_keys_color = bpy.props.FloatVectorProperty(
- name="Color",
- description="Font color",
- default=(1.0, 1.0, 1.0),
- min=0,
- max=1,
- subtype='COLOR')
-
- sc.screencast_keys_mouse = bpy.props.EnumProperty(
- items=(("none", "None", "Don't display mouse events"),
- ("icon", "Icon", "Display graphical represenation of "\
- "the mouse"),
- ("text", "Text", "Display mouse events as text lines")),
- name="Mouse display",
- description="Display mouse events",
- default='text')
-
- sc.screencast_keys_link = bpy.props.BoolProperty(
- name="Group Mouse & Text",
- description = "Link mouse to text",
- default = False)
-
- print ("Screencast Keys: initialized from AddOn default settings.")
+ scene.screencast_keys_pos_x = bpy.props.IntProperty(
+ name="Pos X",
+ description="Margin on the x axis",
+ default=5,
+ min=0,
+ max=100)
+ scene.screencast_keys_pos_y = bpy.props.IntProperty(
+ name="Pos Y",
+ description="Margin on the y axis",
+ default=10,
+ min=0,
+ max=100)
+ scene.screencast_keys_font_size = bpy.props.IntProperty(
+ name="Font",
+ description="Fontsize",
+ default=20, min=10, max=150)
+ scene.screencast_keys_mouse_size = bpy.props.IntProperty(
+ name="Mouse",
+ description="Mousesize",
+ default=60, min=10, max=150)
+ scene.screencast_keys_color = bpy.props.FloatVectorProperty(
+ name="Color",
+ description="Font color",
+ default=(1.0, 1.0, 1.0),
+ min=0,
+ max=1,
+ subtype='COLOR')
+ scene.screencast_keys_mouse = bpy.props.EnumProperty(
+ items=(("none", "None", "Don't display mouse events"),
+ ("icon", "Icon", "Display graphical represenation of "\
+ "the mouse"),
+ ("text", "Text", "Display mouse events as text lines")),
+ name="Mouse display",
+ description="Display mouse events",
+ default='text')
+ scene.screencast_keys_link = bpy.props.BoolProperty(
+ name="Group Mouse & Text",
+ description = "Link mouse to text",
+ default = False)
# Runstate initially always set to False
# note: it is not stored in the Scene, but in window manager:
- wm.screencast_keys_keys = bpy.props.BoolProperty(default=False)
+ wm.screencast_keys_keys = bpy.props.BoolProperty(default=False)
# removal of properties when script is disabled
@@ -569,19 +584,19 @@ class OBJECT_PT_keys_status(bpy.types.Panel):
bl_label = "Screencast Keys"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
-
+
def draw(self, context):
sc = context.scene
wm = context.window_manager
layout = self.layout
-
+
if not wm.screencast_keys_keys:
layout.operator("view3d.screencast_keys", text="Start display",
icon='PLAY')
else:
layout.operator("view3d.screencast_keys", text="Stop display",
icon='PAUSE')
-
+
col = layout.column(align=True)
row = col.row(align=True)
row.prop(sc, "screencast_keys_pos_x")
@@ -593,7 +608,7 @@ class OBJECT_PT_keys_status(bpy.types.Panel):
row.prop(sc, "screencast_keys_mouse", text="Mouse")
row = col.row(align=True)
row.prop(sc, "screencast_keys_link")
-
+
layout.prop(sc, "screencast_keys_color")
@@ -615,4 +630,3 @@ def unregister():
if __name__ == "__main__":
register()
-