diff --git a/space_view3d_panel_measure.py b/space_view3d_panel_measure.py
index 4c82b44497e21fd21de9e61895f4c3c139300362..af3faffed433787659b37c35f3eebe86fb5c5b29 100644
--- a/space_view3d_panel_measure.py
+++ b/space_view3d_panel_measure.py
@@ -27,7 +27,7 @@ bl_info = {
     "author": "Buerbaum Martin (Pontiac), TNae (Normal patch)," \
         " Benjamin Lauritzen (Loonsbury; Volume code)," \
         " Alessandro Sala (patch: Units in 3D View)",
-    "version": (0, 8, 6),
+    "version": (0, 8, 7),
     "blender": (2, 6, 0),
     "location": "View3D > Properties > Measure Panel",
     "description": "Measure distances between objects",
@@ -73,11 +73,12 @@ http://blenderartists.org/forum/showthread.php?t=177800
 
 import bpy
 from bpy.props import *
+from bpy.app.handlers import persistent
 from mathutils import Vector, Matrix
 import bgl
 import blf
 from bpy_extras.view3d_utils import location_3d_to_region_2d
-from bpy_extras.mesh_utils import ngon_tesselate
+from bpy_extras.mesh_utils import ngon_tessellate
 
 
 # Precicion for display of float values.
@@ -87,6 +88,15 @@ PRECISION = 4
 COLOR_LOCAL = (1.0, 0.5, 0.0, 0.8)
 COLOR_GLOBAL = (0.5, 0.0, 1.0, 0.8)
 
+# 3D View - text offset
+OFFSET_LINE = 10   # Offset the text a bit to the right.
+OFFSET_Y = 15      # Offset of the lines.
+OFFSET_VALUE = 30  # Offset of value(s) from the text.
+
+# 3D View - line width
+LINE_WIDTH_XYZ = 1
+LINE_WIDTH_DIST = 2
+
 
 # Returns a tuple describing the current measuring system
 # and formatting options.
@@ -146,9 +156,9 @@ def convertDistance(val, units_info):
 # Returns a single selected object.
 # Returns None if more than one (or nothing) is selected.
 # Note: Ignores the active object.
-def getSingleObject(context):
-    if len(context.selected_objects) == 1:
-        return context.selected_objects[0]
+def getSingleObject():
+    if len(bpy.context.selected_objects) == 1:
+        return bpy.context.selected_objects[0]
 
     return None
 
@@ -157,11 +167,12 @@ def getSingleObject(context):
 # depending on the current view mode and the selection.
 def getMeasurePoints(context):
     sce = context.scene
+    mode = context.mode
 
     # Get a single selected object (or nothing).
-    obj = getSingleObject(context)
+    obj = getSingleObject()
 
-    if context.mode == 'EDIT_MESH':
+    if mode == 'EDIT_MESH':
         obj = context.active_object
 
         if obj and obj.type == 'MESH' and obj.data:
@@ -231,7 +242,7 @@ def getMeasurePoints(context):
             else:
                 return None
 
-    elif context.mode == 'OBJECT':
+    elif mode == 'OBJECT':
         # We are working in object mode.
 
         if len(context.selected_objects) > 2:
@@ -324,7 +335,7 @@ def polyAreaGlobal(poly, obj):
 
     if len(poly.vertices) > 3:
         # Tesselate the polygon into multiple tris
-        tris = ngon_tesselate(mesh, poly.vertices)
+        tris = ngon_tessellate(mesh, poly.vertices)
 
         for tri in tris:
             # Get vertex data
@@ -561,303 +572,329 @@ def measureLocal(sce):
     return (sce.measure_panel_transform == "measure_local")
 
 
-def draw_measurements_callback(self, context):
-    sce = context.scene
-
-    draw = 0
-    if hasattr(sce, "measure_panel_draw"):
-        draw = sce.measure_panel_draw
-
-    # 2D drawing code example
-    #bgl.glBegin(bgl.GL_LINE_STRIP)
-    #bgl.glVertex2i(0, 0)
-    #bgl.glVertex2i(80, 100)
-    #bgl.glEnd()
-
-    # Get measured 3D points and colors.
-    line = getMeasurePoints(context)
-    if line and draw:
-        p1, p2, color = line
-
-        # Get and convert the Perspective Matrix of the current view/region.
-        view3d = bpy.context
-        region = view3d.region_data
-        perspMatrix = region.perspective_matrix
-        tempMat = [perspMatrix[j][i] for i in range(4) for j in range(4)]
-        perspBuff = bgl.Buffer(bgl.GL_FLOAT, 16, tempMat)
-
-        # ---
-        # Store previous OpenGL settings.
-        # Store MatrixMode
-        MatrixMode_prev = bgl.Buffer(bgl.GL_INT, [1])
-        bgl.glGetIntegerv(bgl.GL_MATRIX_MODE, MatrixMode_prev)
-        MatrixMode_prev = MatrixMode_prev[0]
-
-        # Store projection matrix
-        ProjMatrix_prev = bgl.Buffer(bgl.GL_DOUBLE, [16])
-        bgl.glGetFloatv(bgl.GL_PROJECTION_MATRIX, ProjMatrix_prev)
-
-        # Store Line width
-        lineWidth_prev = bgl.Buffer(bgl.GL_FLOAT, [1])
-        bgl.glGetFloatv(bgl.GL_LINE_WIDTH, lineWidth_prev)
-        lineWidth_prev = lineWidth_prev[0]
-
-        # Store GL_BLEND
-        blend_prev = bgl.Buffer(bgl.GL_BYTE, [1])
-        bgl.glGetFloatv(bgl.GL_BLEND, blend_prev)
-        blend_prev = blend_prev[0]
-
-        line_stipple_prev = bgl.Buffer(bgl.GL_BYTE, [1])
-        bgl.glGetFloatv(bgl.GL_LINE_STIPPLE, line_stipple_prev)
-        line_stipple_prev = line_stipple_prev[0]
-
-        # Store glColor4f
-        color_prev = bgl.Buffer(bgl.GL_FLOAT, [4])
-        bgl.glGetFloatv(bgl.GL_COLOR, color_prev)
-
-        # ---
-        # Prepare for 3D drawing
-        bgl.glLoadIdentity()
-        bgl.glMatrixMode(bgl.GL_PROJECTION)
-        bgl.glLoadMatrixf(perspBuff)
-
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glEnable(bgl.GL_LINE_STIPPLE)
-
-        # ---
-        # Draw 3D stuff.
-        width = 1
-        bgl.glLineWidth(width)
-        # X
-        bgl.glColor4f(1, 0, 0, 0.8)
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex3f(p1[0], p1[1], p1[2])
-        bgl.glVertex3f(p2[0], p1[1], p1[2])
-        bgl.glEnd()
-        # Y
-        bgl.glColor4f(0, 1, 0, 0.8)
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex3f(p1[0], p1[1], p1[2])
-        bgl.glVertex3f(p1[0], p2[1], p1[2])
-        bgl.glEnd()
-        # Z
-        bgl.glColor4f(0, 0, 1, 0.8)
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex3f(p1[0], p1[1], p1[2])
-        bgl.glVertex3f(p1[0], p1[1], p2[2])
-        bgl.glEnd()
-
-        # Dist
-        width = 2
-        bgl.glLineWidth(width)
-        bgl.glColor4f(color[0], color[1], color[2], color[3])
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        bgl.glVertex3f(p1[0], p1[1], p1[2])
-        bgl.glVertex3f(p2[0], p2[1], p2[2])
-        bgl.glEnd()
-
-        # ---
-        # Restore previous OpenGL settings
-        bgl.glLoadIdentity()
-        bgl.glMatrixMode(MatrixMode_prev)
-        bgl.glLoadMatrixf(ProjMatrix_prev)
-        bgl.glLineWidth(lineWidth_prev)
-        if not blend_prev:
-            bgl.glDisable(bgl.GL_BLEND)
-        if not line_stipple_prev:
-            bgl.glDisable(bgl.GL_LINE_STIPPLE)
-        bgl.glColor4f(color_prev[0],
-            color_prev[1],
-            color_prev[2],
-            color_prev[3])
-
-        # ---
-        # Draw (2D) text
-        # We do this after drawing the lines so
-        # we can draw it OVER the line.
-        coord_2d = location_3d_to_region_2d(context.region,
-                                            context.space_data.region_3d,
-                                            p1.lerp(p2, 0.5),
-                                            )
-        OFFSET_LINE = 10   # Offset the text a bit to the right.
-        OFFSET_Y = 15      # Offset of the lines.
-        OFFSET_VALUE = 30  # Offset of value(s) from the text.
-        dist = (p1 - p2).length
-
-        # Write distance value into the scene property,
-        # so we can display it in the panel & refresh the panel.
-        if hasattr(sce, "measure_panel_dist"):
-            sce.measure_panel_dist = dist
-            context.area.tag_redraw()
-
-        texts = [("Dist:", dist),
-            ("X:", abs(p1[0] - p2[0])),
-            ("Y:", abs(p1[1] - p2[1])),
-            ("Z:", abs(p1[2] - p2[2]))]
-
-        # Draw all texts
-        # @todo Get user pref for text color in 3D View
-        bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
-        blf.size(0, 12, 72)  # Prevent font size to randomly change.
-
-        uinfo = getUnitsInfo()
-
-        loc_x = coord_2d[0] + OFFSET_LINE
-        loc_y = coord_2d[1]
-        for t in texts:
-            text = t[0]
-
-            value = convertDistance(t[1], uinfo)
-
-            blf.position(0, loc_x, loc_y, 0)
-            blf.draw(0, text)
-            blf.position(0, loc_x + OFFSET_VALUE, loc_y, 0)
-            blf.draw(0, value)
-
-            loc_y -= OFFSET_Y
-
-    if sce.measure_panel_calc_edge_length:
-        if context.mode == 'EDIT_MESH':
-            obj = context.active_object
-
-            length_total = objectEdgeLength(obj, True, measureGlobal(sce))
-
-            sce.measure_panel_edge_length = length_total
+# Calculate values if geometry, selection or cursor changed.
+@persistent
+def scene_update(context):
+    sce = context
+    mode = bpy.context.mode
 
-        elif context.mode == 'OBJECT':
-            length_total = -1
+    if (mode == 'EDIT_MESH' and not sce.measure_panel_update):
+        return
 
-            for o in context.selected_objects:
-                if o.type == 'MESH':
-                    length = objectEdgeLength(o, False, measureGlobal(sce))
+    if (bpy.data.objects.is_updated
+        or bpy.context.scene.is_updated
+        or sce.measure_panel_update):
+        # TODO: Better way to check selection changes and cursor changes?
 
-                    if length >= 0:
-                        if length_total < 0:
-                            length_total = 0
+        sel_objs = bpy.context.selected_objects
 
-                        length_total += length
+        # EDGE LENGTH
+        if sce.measure_panel_calc_edge_length:
+            if (mode == 'EDIT_MESH'
+                and sce.measure_panel_update):
+                sce.measure_panel_update = 0
+                obj = context.active_object
 
-            sce.measure_panel_edge_length = length_total
-
-    # Handle mesh surface area calulations
-    if sce.measure_panel_calc_area:
-        # Get a single selected object (or nothing).
-        obj = getSingleObject(context)
+                #if obj.is_updated:
+                length_total = objectEdgeLength(obj, True,
+                    measureGlobal(sce))
+                sce.measure_panel_edge_length = length_total
+
+            elif mode == 'OBJECT':
+                length_total = -1
+
+                for o in sel_objs:
+                    if o.type == 'MESH':
+                        length = objectEdgeLength(o, False, measureGlobal(sce))
+
+                        if length >= 0:
+                            if length_total < 0:
+                                length_total = 0
+
+                            length_total += length
+
+                sce.measure_panel_edge_length = length_total
+
+        # AREA
+        # Handle mesh surface area calulations
+        if sce.measure_panel_calc_area:
+            if (mode == 'EDIT_MESH'
+                and sce.measure_panel_update):
+                sce.measure_panel_update = 0
+                obj = bpy.context.active_object
+
+                if obj and obj.type == 'MESH' and obj.data:
+                    # "Note: a Mesh will return the selection state of the mesh
+                    # when EditMode was last exited. A Python script operating
+                    # in EditMode must exit EditMode before getting the current
+                    # selection state of the mesh."
+                    # http://www.blender.org/documentation/249PythonDoc/
+                    # /Mesh.MVert-class.html#sel
+                    # We can only provide this by existing &
+                    # re-entering EditMode.
+                    # @todo: Better way to do this?
+
+                    # Get mesh data from Object.
+                    me = obj.data
+
+                    # Get transformation matrix from object.
+                    ob_mat = obj.matrix_world
+                    # Also make an inversed copy! of the matrix.
+                    ob_mat_inv = ob_mat.copy()
+                    Matrix.invert(ob_mat_inv)
+
+                    # Get the selected vertices.
+                    # @todo: Better (more efficient) way to do this?
+                    verts_selected = [v for v in me.vertices if v.select == 1]
 
-        if context.mode == 'EDIT_MESH':
-            obj = context.active_object
+                    if len(verts_selected) >= 3:
+                        # Get selected faces
+                        # @todo: Better (more efficient) way to do this?
+                        polys_selected = [p for p in me.polygons
+                            if p.select == 1]
 
-            if obj and obj.type == 'MESH' and obj.data:
-                # "Note: a Mesh will return the selection state of the mesh
-                # when EditMode was last exited. A Python script operating
-                # in EditMode must exit EditMode before getting the current
-                # selection state of the mesh."
-                # http://www.blender.org/documentation/249PythonDoc/
-                # /Mesh.MVert-class.html#sel
-                # We can only provide this by existing & re-entering EditMode.
-                # @todo: Better way to do this?
+                        if len(polys_selected) > 0:
+                            area, normal = objectSurfaceArea(obj, True,
+                                measureGlobal(sce))
+                            if area >= 0.0:
+                                sce.measure_panel_area1 = area
+                                sce.measure_panel_normal1 = normal
 
-                # Get mesh data from Object.
-                mesh = obj.data
+            elif mode == 'OBJECT':
+                # We are working in object mode.
 
-                # Get transformation matrix from object.
-                ob_mat = obj.matrix_world
-                # Also make an inversed copy! of the matrix.
-                ob_mat_inv = ob_mat.copy()
-                Matrix.invert(ob_mat_inv)
+                # Get a single selected object (or nothing).
+                obj = getSingleObject()
 
-                # Get the selected vertices.
-                # @todo: Better (more efficient) way to do this?
-                verts_selected = [v for v in mesh.vertices if v.select == 1]
+                if len(sel_objs) > 2:
+                    return
+# @todo Make this work again.
+#                    # We have more that 2 objects selected...
+#
+#                    mesh_objects = [o for o in context.selected_objects
+#                       if o.type == 'MESH']
 
-                if len(verts_selected) >= 3:
-                    # Get selected faces
-                    # @todo: Better (more efficient) way to do this?
-                    polys_selected = [f for f in mesh.polygons
-                        if f.select == 1]
+#                    if len(mesh_objects) > 0:
+#                        # ... and at least one of them is a mesh.
+#
+#                        for o in mesh_objects:
+#                            area = objectSurfaceArea(o, False,
+#                                measureGlobal(sce))
+#                           if area >= 0:
+#                               #row.label(text=o.name, icon='OBJECT_DATA')
+#                               #row.label(text=str(round(area, PRECISION))
+#                               #    + " BU^2")
 
-                    if len(polys_selected) > 0:
-                        area, normal = objectSurfaceArea(obj, True,
-                            measureGlobal(sce))
-                        if area >= 0.0:
-                            sce.measure_panel_area1 = area
-                            sce.measure_panel_normal1 = normal
+                elif len(sel_objs) == 2:
+                    # 2 objects selected.
 
-        elif context.mode == 'OBJECT':
-            # We are working in object mode.
+                    obj1, obj2 = sel_objs
 
-            if len(context.selected_objects) > 2:
-                return
-# @todo Make this work again.
-#                # We have more that 2 objects selected...
-#
-#                mesh_objects = [o for o in context.selected_objects
-#                    if o.type == 'MESH']
+                    # Calculate surface area of the objects.
+                    area1, normal1 = objectSurfaceArea(obj1, False,
+                        measureGlobal(sce))
+                    area2, normal2 = objectSurfaceArea(obj2, False,
+                        measureGlobal(sce))
+                    sce.measure_panel_area1 = area1
+                    sce.measure_panel_area2 = area2
+                    sce.measure_panel_normal1 = normal1
+                    sce.measure_panel_normal2 = normal2
 
-#                if len(mesh_objects) > 0:
-#                    # ... and at least one of them is a mesh.
-#
-#                    for o in mesh_objects:
-#                        area = objectSurfaceArea(o, False,
-#                            measureGlobal(sce))
-#                        if area >= 0:
-#                            #row.label(text=o.name, icon='OBJECT_DATA')
-#                            #row.label(text=str(round(area, PRECISION))
-#                            #    + " BU^2")
+                elif obj:
+                    # One object selected.
 
-            elif len(context.selected_objects) == 2:
-                # 2 objects selected.
+                    # Calculate surface area of the object.
+                    area, normal = objectSurfaceArea(obj, False,
+                        measureGlobal(sce))
 
-                obj1, obj2 = context.selected_objects
+                    sce.measure_panel_area1 = area
+                    sce.measure_panel_normal1 = normal
 
-                # Calculate surface area of the objects.
-                area1, normal1 = objectSurfaceArea(obj1, False,
-                    measureGlobal(sce))
-                area2, normal2 = objectSurfaceArea(obj2, False,
-                    measureGlobal(sce))
-                sce.measure_panel_area1 = area1
-                sce.measure_panel_area2 = area2
-                sce.measure_panel_normal1 = normal1
-                sce.measure_panel_normal2 = normal2
+        # VOLUME
+        # Handle mesh volume calulations.
+        if sce.measure_panel_calc_volume:
+            obj = getSingleObject()
 
-            elif obj:
-                # One object selected.
+            if mode == 'OBJECT':
+                # We are working in object mode.
 
-                # Calculate surface area of the object.
-                area, normal = objectSurfaceArea(obj, False,
-                    measureGlobal(sce))
+                #if len(sel_objs) > 2:       # TODO
+                #el
+                if len(sel_objs) == 2:
+                    # 2 objects selected.
 
-                sce.measure_panel_area1 = area
-                sce.measure_panel_normal1 = normal
+                    obj1, obj2 = sel_objs
 
-    if sce.measure_panel_calc_volume:
-        obj = getSingleObject(context)
+                    # Calculate surface area of the objects.
+                    volume1 = objectVolume(obj1, measureGlobal(sce))
+                    volume2 = objectVolume(obj2, measureGlobal(sce))
 
-        if context.mode == 'OBJECT':
-            # We are working in object mode.
+                    sce.measure_panel_volume1 = volume1
+                    sce.measure_panel_volume2 = volume2
 
-            #if len(context.selected_objects) > 2:       # TODO
+                elif obj:
+                    # One object selected.
 
-            #el
-            if len(context.selected_objects) == 2:
-                # 2 objects selected.
+                    # Calculate surface area of the object.
+                    volume1 = objectVolume(obj, measureGlobal(sce))
 
-                obj1, obj2 = context.selected_objects
+                    sce.measure_panel_volume1 = volume1
 
-                # Calculate surface area of the objects.
-                volume1 = objectVolume(obj1, measureGlobal(sce))
-                volume2 = objectVolume(obj2, measureGlobal(sce))
 
-                sce.measure_panel_volume1 = volume1
-                sce.measure_panel_volume2 = volume2
+def draw_measurements_callback(self, context):
+    sce = context.scene
 
-            elif obj:
-                # One object selected.
+    draw = 0
+    if hasattr(sce, "measure_panel_draw"):
+        draw = sce.measure_panel_draw
 
-                # Calculate surface area of the object.
-                volume1 = objectVolume(obj, measureGlobal(sce))
+    # 2D drawing code example
+    #bgl.glBegin(bgl.GL_LINE_STRIP)
+    #bgl.glVertex2i(0, 0)
+    #bgl.glVertex2i(80, 100)
+    #bgl.glEnd()
 
-                sce.measure_panel_volume1 = volume1
+    if draw:
+        # Get measured 3D points and colors.
+        line = getMeasurePoints(context)
+
+        if line:
+            p1, p2, color = line
+
+            # Get & convert the Perspective Matrix of the current view/region.
+            view3d = bpy.context
+            region = view3d.region_data
+            perspMatrix = region.perspective_matrix
+            tempMat = [perspMatrix[j][i] for i in range(4) for j in range(4)]
+            perspBuff = bgl.Buffer(bgl.GL_FLOAT, 16, tempMat)
+
+            # ---
+            # Store previous OpenGL settings.
+            # Store MatrixMode
+            MatrixMode_prev = bgl.Buffer(bgl.GL_INT, [1])
+            bgl.glGetIntegerv(bgl.GL_MATRIX_MODE, MatrixMode_prev)
+            MatrixMode_prev = MatrixMode_prev[0]
+
+            # Store projection matrix
+            ProjMatrix_prev = bgl.Buffer(bgl.GL_DOUBLE, [16])
+            bgl.glGetFloatv(bgl.GL_PROJECTION_MATRIX, ProjMatrix_prev)
+
+            # Store Line width
+            lineWidth_prev = bgl.Buffer(bgl.GL_FLOAT, [1])
+            bgl.glGetFloatv(bgl.GL_LINE_WIDTH, lineWidth_prev)
+            lineWidth_prev = lineWidth_prev[0]
+
+            # Store GL_BLEND
+            blend_prev = bgl.Buffer(bgl.GL_BYTE, [1])
+            bgl.glGetFloatv(bgl.GL_BLEND, blend_prev)
+            blend_prev = blend_prev[0]
+
+            line_stipple_prev = bgl.Buffer(bgl.GL_BYTE, [1])
+            bgl.glGetFloatv(bgl.GL_LINE_STIPPLE, line_stipple_prev)
+            line_stipple_prev = line_stipple_prev[0]
+
+            # Store glColor4f
+            color_prev = bgl.Buffer(bgl.GL_FLOAT, [4])
+            bgl.glGetFloatv(bgl.GL_COLOR, color_prev)
+
+            # ---
+            # Prepare for 3D drawing
+            bgl.glLoadIdentity()
+            bgl.glMatrixMode(bgl.GL_PROJECTION)
+            bgl.glLoadMatrixf(perspBuff)
+
+            bgl.glEnable(bgl.GL_BLEND)
+            bgl.glEnable(bgl.GL_LINE_STIPPLE)
+
+            # ---
+            # Draw 3D stuff.
+            bgl.glLineWidth(LINE_WIDTH_XYZ)
+            # X
+            bgl.glColor4f(1, 0, 0, 0.8)
+            bgl.glBegin(bgl.GL_LINE_STRIP)
+            bgl.glVertex3f(p1[0], p1[1], p1[2])
+            bgl.glVertex3f(p2[0], p1[1], p1[2])
+            bgl.glEnd()
+            # Y
+            bgl.glColor4f(0, 1, 0, 0.8)
+            bgl.glBegin(bgl.GL_LINE_STRIP)
+            bgl.glVertex3f(p1[0], p1[1], p1[2])
+            bgl.glVertex3f(p1[0], p2[1], p1[2])
+            bgl.glEnd()
+            # Z
+            bgl.glColor4f(0, 0, 1, 0.8)
+            bgl.glBegin(bgl.GL_LINE_STRIP)
+            bgl.glVertex3f(p1[0], p1[1], p1[2])
+            bgl.glVertex3f(p1[0], p1[1], p2[2])
+            bgl.glEnd()
+
+            # Dist
+            bgl.glLineWidth(LINE_WIDTH_DIST)
+            bgl.glColor4f(color[0], color[1], color[2], color[3])
+            bgl.glBegin(bgl.GL_LINE_STRIP)
+            bgl.glVertex3f(p1[0], p1[1], p1[2])
+            bgl.glVertex3f(p2[0], p2[1], p2[2])
+            bgl.glEnd()
+
+            # ---
+            # Restore previous OpenGL settings
+            bgl.glLoadIdentity()
+            bgl.glMatrixMode(MatrixMode_prev)
+            bgl.glLoadMatrixf(ProjMatrix_prev)
+            bgl.glLineWidth(lineWidth_prev)
+            if not blend_prev:
+                bgl.glDisable(bgl.GL_BLEND)
+            if not line_stipple_prev:
+                bgl.glDisable(bgl.GL_LINE_STIPPLE)
+            bgl.glColor4f(
+                color_prev[0],
+                color_prev[1],
+                color_prev[2],
+                color_prev[3])
+
+            # ---
+            # Draw (2D) text
+            # We do this after drawing the lines so
+            # we can draw it OVER the line.
+            coord_2d = location_3d_to_region_2d(
+                context.region,
+                context.space_data.region_3d,
+                p1.lerp(p2, 0.5))
+            dist = (p1 - p2).length
+
+            # Write distance value into the scene property,
+            # so we can display it in the panel & refresh the panel.
+            if hasattr(sce, "measure_panel_dist"):
+                sce.measure_panel_dist = dist
+                context.area.tag_redraw()
+
+            texts = [
+                ("Dist:", dist),
+                ("X:", abs(p1[0] - p2[0])),
+                ("Y:", abs(p1[1] - p2[1])),
+                ("Z:", abs(p1[2] - p2[2]))]
+
+            # Draw all texts
+            # @todo Get user pref for text color in 3D View
+            bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
+            blf.size(0, 12, 72)  # Prevent font size to randomly change.
+
+            uinfo = getUnitsInfo()
+
+            loc_x = coord_2d[0] + OFFSET_LINE
+            loc_y = coord_2d[1]
+
+            for t in texts:
+                text = t[0]
+
+                value = convertDistance(t[1], uinfo)
+
+                blf.position(0, loc_x, loc_y, 0)
+                blf.draw(0, text)
+                blf.position(0, loc_x + OFFSET_VALUE, loc_y, 0)
+                blf.draw(0, value)
+
+                loc_y -= OFFSET_Y
 
 
 class VIEW3D_OT_display_measurements(bpy.types.Operator):
@@ -921,11 +958,13 @@ class VIEW3D_OT_reenter_editmode(bpy.types.Operator):
 
         # Get the active object.
         obj = context.active_object
+        sce = context.scene
 
         if obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH':
             # Exit and re-enter mesh EditMode.
             bpy.ops.object.mode_set(mode='OBJECT')
             bpy.ops.object.mode_set(mode='EDIT')
+            sce.measure_panel_update = 1
             return {'FINISHED'}
 
         return {'CANCELLED'}
@@ -940,9 +979,9 @@ class VIEW3D_PT_measure(bpy.types.Panel):
     @classmethod
     def poll(cls, context):
         # Only display this panel in the object and edit mode 3D view.
+        mode = context.mode
         if (context.area.type == 'VIEW_3D' and
-            (context.mode == 'EDIT_MESH'
-            or context.mode == 'OBJECT')):
+            (mode == 'EDIT_MESH' or mode == 'OBJECT')):
             return 1
 
         return 0
@@ -951,30 +990,23 @@ class VIEW3D_PT_measure(bpy.types.Panel):
         layout = self.layout
         sce = context.scene
 
-        # Force a redraw.
-        # This prevents the lines still be drawn after
-        # disabling the "measure_panel_draw" checkbox.
-        # @todo Better solution?
-        context.area.tag_redraw()
-
         mgr_ops = context.window_manager.operators.values()
         if (not "VIEW3D_OT_display_measurements"
             in [op.bl_idname for op in mgr_ops]):
             layout.operator("view3d.activate_measure_panel",
                         text="Activate")
 
-        context.area.tag_redraw()
-
     def draw(self, context):
         layout = self.layout
         sce = context.scene
+        mode = context.mode
 
         # Get a single selected object (or nothing).
-        obj = getSingleObject(context)
+        obj = getSingleObject()
 
         drawTansformButtons = 1
 
-        if context.mode == 'EDIT_MESH':
+        if mode == 'EDIT_MESH':
             obj = context.active_object
 
             row = layout.row()
@@ -1122,7 +1154,7 @@ class VIEW3D_PT_measure(bpy.types.Panel):
                         "measure_panel_transform",
                         expand=True)
 
-        elif context.mode == 'OBJECT':
+        elif mode == 'OBJECT':
             # We are working in object mode.
 
             mesh_objects = [o for o in context.selected_objects
@@ -1269,8 +1301,8 @@ class VIEW3D_PT_measure(bpy.types.Panel):
                                 icon='INFO')
                         else:  # -2
                             row = box.row()
-                            row.label(text="Mesh has faces with " \
-                                "more than 4 edges!",
+                            row.label(text="Mesh has n-gons (faces with " \
+                                "more than 4 edges)!",
                                 icon='INFO')
 
                     if sce.measure_panel_volume2 >= -2:
@@ -1288,8 +1320,8 @@ class VIEW3D_PT_measure(bpy.types.Panel):
                                 icon='INFO')
                         else:  # -2
                             row = box.row()
-                            row.label(text="Mesh has faces with " \
-                                "more than 4 edges!",
+                            row.label(text="Mesh has n-gons (faces with " \
+                                "more than 4 edges)!",
                                 icon='INFO')
 
             elif obj:
@@ -1369,8 +1401,8 @@ class VIEW3D_PT_measure(bpy.types.Panel):
                                 icon='INFO')
                         else:  # -2
                             row = box.row()
-                            row.label(text="Mesh has faces with " \
-                                "more than 4 edges!",
+                            row.label(text="Mesh has n-gons (faces with " \
+                                "more than 4 edges)!",
                                 icon='INFO')
 
             elif not context.selected_objects:
@@ -1404,6 +1436,8 @@ class VIEW3D_PT_measure(bpy.types.Panel):
 def register():
     bpy.utils.register_module(__name__)
 
+    bpy.app.handlers.scene_update_post.append(scene_update)
+
     # Define a temporary attribute for the distance value
     bpy.types.Scene.measure_panel_dist = bpy.props.FloatProperty(
         name="Distance",
@@ -1455,7 +1489,7 @@ def register():
     bpy.types.Scene.measure_panel_draw = bpy.props.BoolProperty(
         name="Draw distance",
         description="Draw distances in 3D View",
-        default=0)
+        default=1)
 
     bpy.types.Scene.measure_panel_calc_edge_length = bpy.props.BoolProperty(
         description="Calculate total length of (selected) edges",
@@ -1474,15 +1508,33 @@ def register():
                     "usage on bigger meshes)",
         default=0)
 
+     # Define dropdown for the global/local setting
+    bpy.types.Scene.measure_panel_update = bpy.props.BoolProperty(
+        description="Update CPU heavy calculations",
+        default=0)
+
     pass
 
 
 def unregister():
     bpy.utils.unregister_module(__name__)
-    bpy.types.Scene.measure_panel_draw = bpy.props.BoolProperty(
-        name="Draw distance",
-        description="Draw distances in 3D View",
-        default=0)
+
+    # Remove properties.
+    del bpy.types.Scene.measure_panel_dist
+    del bpy.types.Scene.measure_panel_edge_length
+    del bpy.types.Scene.measure_panel_area1
+    del bpy.types.Scene.measure_panel_area2
+    del bpy.types.Scene.measure_panel_normal1
+    del bpy.types.Scene.measure_panel_normal2
+    del bpy.types.Scene.measure_panel_volume1
+    del bpy.types.Scene.measure_panel_volume2
+    del bpy.types.Scene.measure_panel_transform
+    del bpy.types.Scene.measure_panel_draw
+    del bpy.types.Scene.measure_panel_calc_edge_length
+    del bpy.types.Scene.measure_panel_calc_area
+    del bpy.types.Scene.measure_panel_calc_volume
+    del bpy.types.Scene.measure_panel_update
+
     pass
 
 if __name__ == "__main__":