--- a/graphics/GraphicCommons.py Fri Sep 30 17:16:02 2011 +0200
+++ b/graphics/GraphicCommons.py Sun Oct 09 19:51:14 2011 +0200
@@ -93,7 +93,14 @@
# Color for Highlighting
HIGHLIGHTCOLOR = wx.CYAN
-
+
+# Define highlight types
+ERROR_HIGHLIGHT = (wx.NamedColour("yellow"), wx.RED)
+SEARCH_RESULT_HIGHLIGHT = (wx.NamedColour("orange"), wx.WHITE)
+
+# Define highlight refresh inhibition period in second
+REFRESH_HIGHLIGHT_PERIOD = 0.1
+
HANDLE_CURSORS = {
(1, 1) : 2,
(3, 3) : 2,
@@ -531,19 +538,38 @@
event.Skip()
#-------------------------------------------------------------------------------
-# Helper for highlighting error in drawn text
+# Helpers for highlighting text
#-------------------------------------------------------------------------------
-def HighlightErrorZone(dc, x, y, width, height):
+def AddHighlight(highlights, infos):
+ RemoveHighlight(highlights, infos)
+ highlights.append(infos)
+
+def RemoveHighlight(highlights, infos):
+ if infos in highlights:
+ highlights.remove(infos)
+ return True
+ return False
+
+def ClearHighlight(highlights, highlight_type=None):
+ if highlight_type is not None:
+ return [highlight for highlight in highlights if highlight[2] != highlight_type]
+ return []
+
+def DrawHighlightedText(dc, text, highlights, x, y):
+ current_pen = dc.GetPen()
dc.SetPen(wx.TRANSPARENT_PEN)
- dc.SetLogicalFunction(wx.AND)
- dc.SetBrush(wx.Brush(wx.Colour(0,255,0)))
- dc.DrawRectangle(x, y, width, height)
- dc.SetLogicalFunction(wx.XOR)
- dc.SetBrush(wx.Brush(wx.Colour(255,0,0)))
- dc.DrawRectangle(x, y, width, height)
- dc.SetLogicalFunction(wx.COPY)
-
+ for start, end, highlight_type in highlights:
+ dc.SetBrush(wx.Brush(highlight_type[0]))
+ offset_width, offset_height = dc.GetTextExtent(text[:start[1]])
+ part = text[start[1]:end[1] + 1]
+ part_width, part_height = dc.GetTextExtent(part)
+ dc.DrawRectangle(x + offset_width, y, part_width, part_height)
+ dc.SetTextForeground(highlight_type[1])
+ dc.DrawText(part, x + offset_width, y)
+ dc.SetPen(current_pen)
+ dc.SetTextForeground(wx.BLACK)
+
#-------------------------------------------------------------------------------
# Graphic element base class
#-------------------------------------------------------------------------------
@@ -934,7 +960,16 @@
return movex, movey
return 0, 0
- def AddError(self, infos, start, end):
+ # Override this method for defining the method to call for adding an highlight to this element
+ def AddHighlight(self, infos, start, end, highlight_type):
+ pass
+
+ # Override this method for defining the method to call for removing an highlight from this element
+ def RemoveHighlight(self, infos, start, end, highlight_type):
+ pass
+
+ # Override this method for defining the method to call for removing all the highlights of one particular type from this element
+ def ClearHighlight(self, highlight_type=None):
pass
# Override this method for defining the method to call for refreshing the model of this element
@@ -1300,7 +1335,7 @@
self.Value = None
self.Forced = False
self.Selected = False
- self.Errors = {}
+ self.Highlights = []
self.RefreshNameSize()
def Flush(self):
@@ -1396,7 +1431,7 @@
self.Valid = True
for wire, handle in self.Wires:
self.Valid &= wire.GetValid()
-
+
def ReceivingCurrent(self):
current = False
for wire, handle in self.Wires:
@@ -1607,21 +1642,50 @@
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
- def AddError(self, infos, start, end):
- if len(infos) == 0:
+ # Adds an highlight to the connector
+ def AddHighlight(self, infos, start, end, highlight_type):
+ if highlight_type == ERROR_HIGHLIGHT:
for wire, handle in self.Wires:
wire.SetValid(False)
+ AddHighlight(self.Highlights, (start, end, highlight_type))
+
+ # Removes an highlight from the connector
+ def RemoveHighlight(self, infos, start, end, highlight_type):
+ error = False
+ highlights = []
+ for highlight in self.Highlights:
+ if highlight != (start, end, highlight_type):
+ highlights.append(highlight)
+ error |= highlight == ERROR_HIGHLIGHT
+ self.Highlights = highlights
+ if not error:
+ for wire, handle in self.Wires:
+ wire.SetValid(wire.IsConnectedCompatible())
+
+ # Removes all the highlights of one particular type from the connector
+ def ClearHighlight(self, highlight_type=None):
+ error = False
+ if highlight_type is None:
+ self.Highlights = []
else:
- self.Errors[infos[0]] = (start, end)
+ highlights = []
+ for highlight in self.Highlights:
+ if highlight[2] != highlight_type:
+ highlights.append(highlight)
+ error |= highlight == ERROR_HIGHLIGHT
+ self.Highlights = highlights
+ if not error:
+ for wire, handle in self.Wires:
+ wire.SetValid(wire.IsConnectedCompatible())
# Draws the connector
def Draw(self, dc):
if self.Selected:
dc.SetPen(MiterPen(wx.BLUE, 3))
dc.SetBrush(wx.WHITE_BRUSH)
- elif len(self.Errors) > 0:
- dc.SetPen(MiterPen(wx.RED))
- dc.SetBrush(wx.Brush(wx.Colour(255, 255, 0)))
+ #elif len(self.Highlights) > 0:
+ # dc.SetPen(MiterPen(self.Highlights[-1][1]))
+ # dc.SetBrush(wx.Brush(self.Highlights[-1][0]))
else:
if not self.Valid:
dc.SetPen(MiterPen(wx.RED))
@@ -1672,9 +1736,6 @@
xend = xstart + CONNECTOR_SIZE * self.Direction[0]
yend = ystart + CONNECTOR_SIZE * self.Direction[1]
dc.DrawLine(xstart + self.Direction[0], ystart + self.Direction[1], xend, yend)
- if len(self.Errors) > 0:
- dc.SetPen(self.Pen)
- dc.SetBrush(wx.WHITE_BRUSH)
if self.Direction[0] != 0:
ytext = parent_pos[1] + self.Pos.y - name_size[1] / 2
if self.Direction[0] < 0:
@@ -1689,7 +1750,8 @@
ytext = parent_pos[1] + self.Pos.y - (name_size[1] + 5)
# Draw the text
dc.DrawText(self.Name, xtext, ytext)
-
+ if not getattr(dc, "printing", False):
+ DrawHighlightedText(dc, self.Name, self.Highlights, xtext, ytext)
#-------------------------------------------------------------------------------
# Common Wire Element
@@ -2775,7 +2837,7 @@
if self.EndConnected is not None:
self.EndConnected.DrawHighlightment(dc)
self.EndConnected.Draw(dc)
-
+
# Draws the wire lines and points
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -2848,6 +2910,26 @@
# Graphic comment element
#-------------------------------------------------------------------------------
+def FilterHighlightsByRow(highlights, row, length):
+ _highlights = []
+ for start, end, highlight_type in highlights:
+ if start[0] <= row and end[0] >= row:
+ if start[0] < row:
+ start = (row, 0)
+ if end[0] > row:
+ end = (row, length)
+ _highlights.append((start, end, highlight_type))
+ return _highlights
+
+def FilterHighlightsByColumn(highlights, start_col, end_col):
+ _highlights = []
+ for start, end, highlight_type in highlights:
+ if end[1] > start_col and start[1] < end_col:
+ start = (start[0], max(start[1], start_col) - start_col)
+ end = (end[0], min(end[1], end_col) - start_col)
+ _highlights.append((start, end, highlight_type))
+ return _highlights
+
"""
Class that implements a comment
"""
@@ -2861,6 +2943,7 @@
self.Content = content
self.Pos = wx.Point(0, 0)
self.Size = wx.Size(0, 0)
+ self.Highlights = []
# Make a clone of this comment
def Clone(self, parent, id = None, pos = None):
@@ -2958,6 +3041,19 @@
# Edit the comment content
self.Parent.EditCommentContent(self)
+ # Adds an highlight to the comment
+ def AddHighlight(self, infos, start, end, highlight_type):
+ if infos[0] == "content":
+ AddHighlight(self.Highlights, (start, end, highlight_type))
+
+ # Removes an highlight from the comment
+ def RemoveHighlight(self, infos, start, end, highlight_type):
+ RemoveHighlight(self.Highlights, (start, end, highlight_type))
+
+ # Removes all the highlights of one particular type from the comment
+ def ClearHighlight(self, highlight_type=None):
+ self.Highlights = ClearHighlights(self.Highlights, highlight_type)
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -2999,32 +3095,46 @@
dc.DrawLines(lines)
# Draws the comment content
y = self.Pos.y + 10
- for line in self.Content.splitlines():
+ for idx, line in enumerate(self.Content.splitlines()):
first = True
linetext = ""
words = line.split(" ")
+ if not getattr(dc, "printing", False):
+ highlights = FilterHighlightsByRow(self.Highlights, idx, len(line))
+ highlights_offset = 0
for i, word in enumerate(words):
if first:
- test = word
+ text = word
else:
- test = linetext + " " + word
- wordwidth, wordheight = dc.GetTextExtent(test)
+ text = linetext + " " + word
+ wordwidth, wordheight = dc.GetTextExtent(text)
if y + wordheight > self.Pos.y + self.Size[1] - 10:
break
if wordwidth < self.Size[0] - 20:
if i < len(words) - 1:
- linetext = test
+ linetext = text
first = False
else:
- dc.DrawText(test, self.Pos.x + 10, y)
+ dc.DrawText(text, self.Pos.x + 10, y)
+ if not getattr(dc, "printing", False):
+ DrawHighlightedText(dc, text, FilterHighlightsByColumn(highlights, highlights_offset, highlights_offset + len(text)), self.Pos.x + 10, y)
+ highlights_offset += len(text) + 1
y += wordheight + 5
else:
- dc.DrawText(linetext, self.Pos.x + 10, y)
- if i == len(words) - 1:
- y += wordheight + 5
- if y + wordheight > self.Pos.y + self.Size[1] - 10:
- break
+ if not first:
+ dc.DrawText(linetext, self.Pos.x + 10, y)
+ if not getattr(dc, "printing", False):
+ DrawHighlightedText(dc, linetext, FilterHighlightsByColumn(highlights, highlights_offset, highlights_offset + len(linetext)), self.Pos.x + 10, y)
+ highlights_offset += len(linetext) + 1
+ if first or i == len(words) - 1:
+ if not first:
+ y += wordheight + 5
+ if y + wordheight > self.Pos.y + self.Size[1] - 10:
+ break
dc.DrawText(word, self.Pos.x + 10, y)
+ if not getattr(dc, "printing", False):
+ DrawHighlightedText(dc, word, FilterHighlightsByColumn(highlights, highlights_offset, highlights_offset + len(word)), self.Pos.x + 10, y)
+ highlights_offset += len(word) + 1
else:
linetext = word
y += wordheight + 5