def append_poly(self, polys): for poly in polys: self.append(poly) self.polyList.append(poly) poly.textXMin = gui.SvgText(0, 0, "actualValue") poly.textXMax = gui.SvgText(0, 0, "actualValue") poly.textYVal = gui.SvgText(0, 0, "actualValue") poly.textYVal.style['font-size'] = gui.to_pix(self.font_size) poly.lineYValIndicator = gui.SvgLine(0, 0, 0, 0) poly.lineXMinIndicator = gui.SvgLine(0, 0, 0, 0) poly.lineXMaxIndicator = gui.SvgLine(0, 0, 0, 0) self.append([poly.textXMin, poly.textXMax, poly.textYVal, poly.lineYValIndicator, poly.lineXMinIndicator, poly.lineXMaxIndicator])
def __init__(self, width, height): super(JoystickWidget, self).__init__(width, height) self.width = width self.height = height # self.maxDragLength = min(width, height)/3.0*2.0 self.maxDragLength = min(width, height) / 3.0 self.startPointIndicator = gui.SvgCircle(0, 0, 20) self.startPointIndicator.set_fill('rgb(255,200,50)') self.startPointIndicator.set_stroke(1, 'white') self.endPointIndicator = gui.SvgCircle(0, 0, 10) self.endPointIndicator.set_fill('rgb(200,255,50)') self.endPointIndicator.set_stroke(1, 'white') self.pathLine = gui.SvgLine(0, 0, 0, 0) self.startX = 0 self.startY = 0 self.append('path_line', self.pathLine) self.append('start_point', self.startPointIndicator) self.append('end_point', self.endPointIndicator) self.drag_state = False self.set_on_mouseup_listener(self, 'mouseup') self.set_on_mousedown_listener(self, 'mousedown') self.set_on_mousemove_listener(self, 'mousemove') self.set_on_touchend_listener(self, 'mouseup') self.set_on_touchstart_listener(self, 'mousedown') self.set_on_touchmove_listener(self, 'mousemove') self.EVENT_ONMOVE = "ONJOYSTICKMOVE" self.reset_joystick(0, 0)
def __init__(self, x_pos, y_pos, wide, high, *args, **kwargs): """ x_pos and y_pos are coordinates indicated by the pointer, generally at the center of the shown tape """ gui.SvgGroup.__init__(self, *args, **kwargs) self.wide = wide self.high = high self.attributes['transform'] = 'translate(%s %s)' % (x_pos, y_pos) #it is used a subcontainer in order to show only a part of the entire tape self.subcontainer = gui.SvgSubcontainer(-self.wide, -self.high / 2, wide, high) self.subcontainer.set_viewbox(-self.wide / 2, -self.high / 2, wide, self.high) self.append(self.subcontainer) vertical_line_width = self.wide / 20 scale_vertical_line = gui.SvgLine(-self.wide / 2, -self.high / 2, -self.wide / 2, self.high) scale_vertical_line.set_stroke(vertical_line_width, 'lightgray') self.subcontainer.append(scale_vertical_line) self.pointer_line = gui.SvgLine(self.wide / 2, 0, -self.wide / 2, self.value * (self.high / 2)) self.pointer_line.set_stroke(self.wide / 14, 'lightgray') self.subcontainer.append(self.pointer_line) self.value_max = gui.SvgText(-self.wide / 2 + vertical_line_width, -self.high / 2, "10") self.value_max.attr_dominant_baseline = 'hanging' self.value_max.attr_text_anchor = 'start' self.value_max.set_fill('white') self.value_max.css_font_size = gui.to_pix(0.3 * self.wide) self.value_max.css_font_weight = 'bolder' #self.value_max.attributes['transform'] = 'translate(0 %s)'%(self.vh/2-0.11*self.vh) self.subcontainer.append(self.value_max) self.value_min = gui.SvgText(-self.wide / 2 + vertical_line_width, self.high / 2, "-10") self.value_min.attr_dominant_baseline = 'ideographic' self.value_min.attr_text_anchor = 'start' self.value_min.set_fill('white') self.value_min.css_font_size = gui.to_pix(0.3 * self.wide) self.value_min.css_font_weight = 'bolder' #self.value_min.attributes['transform'] = 'translate(0 %s)'%(self.vh/2-0.11*self.vh) self.subcontainer.append(self.value_min)
def build_scale(self): #self.group_scale.empty() #horizontal line along all the tape size x = self.wide / 2 if self.left_side else -self.wide / 2 line = gui.SvgLine(x, -self.value - self.scale_length_visible / 2, x, -self.value + self.scale_length_visible / 2) line.set_stroke(0.1 * self.wide, 'gray') self.group_scale.append(line, "line") #creating labels labels = {} labels_size = {} step = 10 for i in range( int(self.value / step - 1 - (self.scale_length_visible / step) / 2), int(self.value / step + (self.scale_length_visible / step) / 2 + 1)): if not i * step in labels.keys() and i * step >= 0: labels[i * step] = "%d" % (i * step) labels_size[i * step] = 1.0 indicator_x = (self.wide / 2 - self.indicator_size) if self.left_side else ( -self.wide / 2 + self.indicator_size) text_x = ((self.wide / 2 - self.indicator_size) if self.left_side else (self.wide / 2 - 0.05 * self.wide)) content = "" for v in range(int(self.value - self.scale_length_visible / 2), int(self.value + self.scale_length_visible / 2 + 1)): if v in labels.keys(): y = -v """line = gui.SvgLine(indicator_x, y, self.wide/2 if self.left_side else -self.wide/2, y) line.set_stroke(0.03*self.wide, 'gray') self.group_scale.append(line) """ content += """<line class="SvgLine" x1="%(x1)s" y1="%(y1)s" x2="%(x2)s" y2="%(y2)s" stroke="gray" stroke-width="0.6"></line>""" % { 'x1': indicator_x, 'y1': y, 'x2': (self.wide / 2 if self.left_side else -self.wide / 2), 'y2': y } content += """<text class="SvgText" x="%(x)s" y="%(y)s" fill="white" style="dominant-baseline:middle;text-anchor:end;font-size:%(font)s;font-weight:bolder">%(text)s</text>""" % { 'x': text_x, 'y': y, 'text': labels.get(v, ''), 'font': gui.to_pix(0.28 * self.wide) } """txt = gui.SvgText(text_x, y, labels.get(v, '')) txt.attr_dominant_baseline = 'middle' txt.attr_text_anchor = 'end' if self.left_side else 'end' txt.set_fill('white') txt.css_font_size = gui.to_pix(0.25*self.wide*labels_size[v]) txt.css_font_weight = 'bolder' self.group_scale.append(txt)""" self.group_scale.add_child('content', content)
def actionLines(self, lineX, lineY, action): for coord in action.coords: x1, y1 = fieldToSvgCoordinates(coord[0], coord[1]) line = gui.SvgLine(lineX, lineY, x1, y1) line.set_stroke(width=3) self.robotPathLines.append(line) self.fieldSvg.append(line) lineX, lineY = x1, y1 return lineX, lineY
def actionLines(self, lineX, lineY, coord): x1, y1 = fieldToSvgCoordinates(coord.x, coord.y, self.fieldWidth, self.fieldHeight, self.fieldPixelsPerFoot) line = gui.SvgLine(lineX, lineY, x1, y1) line.set_stroke(width=3) self.robotPathLines.append(line) self.fieldSvg.append(line) lineX, lineY = x1, y1 return lineX, lineY
def bezierCurve(self, lineX1, lineX2, lineX3, lineY1, lineY2, lineY3): curve = self._curve(5, (lineX1, lineY1), (lineX2, lineY2), (lineX3, lineY3)) x1, y1 = curve[0] for index in range(1, len(curve)): x2, y2 = curve[index] line = gui.SvgLine(x1, y1, x2, y2) line.set_stroke(width=3, color='red') self.robotPathLines.append(line) self.fieldSvg.append(line) x1, y1 = x2, y2
def test_init(self): widget = gui.SvgLine(10, 10, 20, 20) assertValidHTML(widget.repr())
def __init__(self, width, height, _min, _max): super(Gauge, self).__init__(width, height) self.width = width self.height = height self.min = _min self.max = _max self.scale_angle_range = math.pi * 2 - 1.0 self.scale_value_range = _max - _min self.base_angle = 0 #-self.scale_angle_range/2.0 self.radius = min(width, height) / 2.0 circle = gui.SvgCircle(width / 2.0, height / 2.0, self.radius) self.append(circle) circle.set_fill('gray') circle.set_stroke(1, 'lightgray') circle = gui.SvgCircle(width / 2.0, height / 2.0, self.radius * 92.0 / 100.0) self.append(circle) circle.set_fill('lightgray') circle.set_stroke(1, 'lightgray') font_size = self.radius * 10.0 / 100.0 xy = self.value_to_xy_tuple(_min, self.radius * 90.0 / 100.0) textMin = gui.SvgText(xy[0], xy[1], str(_min)) xy = self.value_to_xy_tuple(_max, self.radius * 90.0 / 100.0) textMax = gui.SvgText(xy[0], xy[1], str(_max)) textMin.style['font-size'] = gui.to_pix(font_size) textMax.style['font-size'] = gui.to_pix(font_size) textMin.style['text-anchor'] = "end" textMax.style['text-anchor'] = "end" textMin.set_fill('red') textMax.set_fill('green') for i in range(0, 11): xy1 = self.value_to_xy_tuple( self.min + self.scale_value_range / 10 * i, self.radius * 92.0 / 100.0) xy2 = self.value_to_xy_tuple( self.min + self.scale_value_range / 10 * i, self.radius) tick = gui.SvgLine(xy1[0], xy1[1], xy2[0], xy2[1]) tick.set_stroke(2, 'white') self.append(tick) self.append(textMin) self.append(textMax) self.arrow = gui.SvgPolyline() self.arrow.add_coord(-self.radius * 20.0 / 100.0, 0) self.arrow.add_coord(-self.radius * 23.0 / 100.0, self.radius * 10.0 / 100.0) self.arrow.add_coord(0, 0) self.arrow.add_coord(-self.radius * 23.0 / 100.0, -self.radius * 10.0 / 100.0) self.arrow.add_coord(-self.radius * 20.0 / 100.0, 0) self.arrow.style['fill'] = 'white' self.arrow.set_stroke(1.0, 'white') self.append(self.arrow) self.arrow_preview = gui.SvgPolyline() self.arrow_preview.add_coord(-self.radius * 10.0 / 100.0, 0) self.arrow_preview.add_coord(-self.radius * 13.0 / 100.0, self.radius * 5.0 / 100.0) self.arrow_preview.add_coord(0, 0) self.arrow_preview.add_coord(-self.radius * 13.0 / 100.0, -self.radius * 5.0 / 100.0) self.arrow_preview.add_coord(-self.radius * 10.0 / 100.0, 0) self.arrow_preview.style['fill'] = 'beige' self.arrow_preview.set_stroke(1.0, 'beige') self.append(self.arrow_preview) self.set_value(_min)
def __init__(self, *args, **kwargs): gui.SvgSubcontainer.__init__(self, -self.vw / 2, -self.vh / 2, self.vw, self.vh, *args, **kwargs) self.attr_viewBox = "%s %s %s %s" % (-self.vw / 2, -self.vh / 2, self.vw, self.vh) self.group_pitch = gui.SvgGroup() self.group_pitch.css_transform = "rotate(0deg), translate(0, 0)" self.group_pitch.css_transform_box = "fill-box" self.group_pitch.css_transform_origin = "center" self.group_roll = gui.SvgGroup() self.group_roll.css_transform = "rotate(0deg), translate(0, 0)" self.group_roll.css_transform_box = "fill-box" self.group_roll.css_transform_origin = "50% 20%" self.group_roll.append(self.group_pitch) #horizon #background is static and occupy the entire attidute indicator self.horizon_background = gui.SvgRectangle(-self.vw / 2, -self.vh / 2, self.vw, self.vh) self.horizon_background.set_fill("rgb(0,100,255)") self.append(self.horizon_background) self.group_horizon_terrain = gui.SvgGroup() self.horizon_terrain = gui.SvgRectangle(-self.vw, 0, self.vw * 2, self.vh * 2) self.horizon_terrain.set_fill("rgb(53, 151, 0)") self.horizon_terrain.set_stroke(self.vh / 1000.0, "lightgray") self.group_horizon_terrain.append(self.horizon_terrain) self.append(self.group_horizon_terrain) #pitch angle indication self.group_pitch_indicator = gui.SvgGroup() self.group_pitch.append(self.group_pitch_indicator) self.generate_pitch_indicator() self.append(self.group_roll) #roll angle indication min_radius = self.vw * 0.45 mid_radius = self.vw * 0.48 max_radius = self.vw * 0.5 angle_min = -60 angle_max = 60 angle_step = 20 # was 5 for angle in range(angle_min, angle_max + angle_step, angle_step): r = min_radius if (angle % 10) == 0 else mid_radius x_min = math.cos(math.radians(angle + 90)) * r y_min = -math.sin(math.radians(angle + 90)) * r x_max = math.cos(math.radians(angle + 90)) * max_radius y_max = -math.sin(math.radians(angle + 90)) * max_radius hide_scale = abs(int(angle)) > self.pitch_roll_scale_limit line = gui.SvgLine(x_min, y_min, x_max, y_max) line.set_stroke(self.vw * 0.005, 'white' if not hide_scale else 'transparent') self.append(line) if (angle % 10) == 0: x_txt = math.cos( math.radians(angle + 90)) * (min_radius - 0.025 * self.vw) y_txt = -math.sin(math.radians(angle + 90)) * (min_radius - 0.025 * self.vw) txt = gui.SvgText(x_txt, y_txt, str(abs(int(angle)))) txt.attr_dominant_baseline = 'hanging' txt.attr_text_anchor = 'middle' txt.set_fill('white' if not hide_scale else 'transparent') txt.css_font_size = gui.to_pix(self.vw * 0.04) txt.css_font_weight = 'bolder' self.append(txt) self.group_roll_indicator = gui.SvgGroup() self.group_roll_indicator.css_visibility = 'visible' self.append(self.group_roll_indicator) #roll and bank indicator self.group_roll_and_bank_angle_indicator = gui.SvgGroup() self.roll_indicator = gui.SvgPolygon(3) self.roll_indicator.set_fill('red') self.roll_indicator.set_stroke(1, 'black') self.roll_indicator.add_coord(-0.04 * self.vw, -0.06 * self.vw) self.roll_indicator.add_coord(0.0 * self.vw, (-0.06 - 0.03) * self.vw) self.roll_indicator.add_coord(0.04 * self.vw, -0.06 * self.vw) self.group_roll_and_bank_angle_indicator.append(self.roll_indicator) self.bank_indicator = gui.SvgPolygon(4) self.bank_indicator.set_fill('transparent') self.bank_indicator.set_stroke(1, 'black') self.bank_indicator_width = 0.08 self.bank_indicator.add_coord( -(self.bank_indicator_width / 2.0) * self.vw, (-0.06 + 0.005) * self.vw) self.bank_indicator.add_coord( (self.bank_indicator_width / 2.0) * self.vw, (-0.06 + 0.005) * self.vw) self.bank_indicator.add_coord( (self.bank_indicator_width / 2.0) * self.vw, (-0.06 + 0.025) * self.vw) self.bank_indicator.add_coord( -(self.bank_indicator_width / 2.0) * self.vw, (-0.06 + 0.025) * self.vw) self.group_roll_and_bank_angle_indicator.append(self.bank_indicator) self.group_roll_and_bank_angle_indicator.attributes[ 'transform'] = "translate(0 %s)" % (-0.3 * self.vh) self.group_roll_indicator.append( self.group_roll_and_bank_angle_indicator) #airplaine indicator is steady thick = 0.02 * self.vw self.airplane_svg_left = gui.SvgPolygon(8) self.airplane_svg_left.set_fill('gray') self.airplane_svg_left.set_stroke(0.005 * self.vw, 'black') self.airplane_svg_left.add_coord(-0.2 * self.vw, 0 * self.vw) #25x8 self.airplane_svg_left.add_coord(-0.40 * self.vw, 0 * self.vw) self.airplane_svg_left.add_coord(-0.40 * self.vw, thick) self.airplane_svg_left.add_coord(-0.2 * self.vw - thick, thick) self.airplane_svg_left.add_coord(-0.2 * self.vw - thick, thick + 0.08 * self.vw) self.airplane_svg_left.add_coord(-0.2 * self.vw, thick + 0.08 * self.vw) self.airplane_svg_left.add_coord(-0.2 * self.vw, 0.08 * self.vw) self.airplane_svg_right = gui.SvgPolygon(8) self.airplane_svg_right.set_fill('gray') self.airplane_svg_right.set_stroke(0.005 * self.vw, 'black') self.airplane_svg_right.add_coord(0.2 * self.vw, 0 * self.vw) #25x8 self.airplane_svg_right.add_coord(0.40 * self.vw, 0 * self.vw) self.airplane_svg_right.add_coord(0.40 * self.vw, thick) self.airplane_svg_right.add_coord(0.2 * self.vw + thick, thick) self.airplane_svg_right.add_coord(0.2 * self.vw + thick, thick + 0.08 * self.vw) self.airplane_svg_right.add_coord(0.2 * self.vw, thick + 0.08 * self.vw) self.airplane_svg_right.add_coord(0.2 * self.vw, 0.08 * self.vw) self.airplane_svg_center = gui.SvgRectangle(-0.02 * self.vw, -0.02 * self.vw, 0.04 * self.vw, 0.04 * self.vw) self.airplane_svg_center.set_fill('white') self.airplane_svg_center.set_stroke(0.005 * self.vw, 'lightgray') self.append([ self.airplane_svg_left, self.airplane_svg_right, self.airplane_svg_center ]) #self.generate_orientation_indicator() self.orientation_tape = OrientationTapeHorizontal( 0, 0.4 * self.vh, 0.8 * self.vw, 1.0 * self.vh) self.append(self.orientation_tape) self.set_skid_slip(0)
def __init__(self, x_pos, y_pos, wide, high, *args, **kwargs): """ x_pos and y_pos are coordinates indicated by the pointer, generally at the center of the shown tape """ gui.SvgGroup.__init__(self, *args, **kwargs) self.wide = wide self.high = high self.attributes['transform'] = 'translate(%s %s)' % (x_pos, y_pos) #it is used a subcontainer in order to show only a part of the entire tape self.subcontainer = gui.SvgSubcontainer(-wide / 2, 0, wide, high) self.subcontainer.set_viewbox(-self.scale_length_visible / 2, 0, self.scale_length_visible, high * (high / wide)) self.append(self.subcontainer) #horizontal line along all the tape size self.group_orientation_indicator = gui.SvgGroup() line = gui.SvgLine(-self.scale_length / 2, 0, self.scale_length / 2, 0) line.set_stroke(0.005 * high, 'white') self.group_orientation_indicator.append(line) #creating labels labels = {0: 'N', 90: 'E', 180: 'S', 270: 'W'} labels_size = {0: 1.0, 90: 1.0, 180: 1.0, 270: 1.0} for i in range(0, 36 + 1, 2): if not (i * 10) in labels.keys(): labels[i * 10] = "%02d" % i labels_size[i * 10] = 0.7 for angle in range(int(-self.scale_length / 2), int(self.scale_length / 2) + 1): if angle % 360 in labels.keys(): x = angle y = 0.05 * self.high * labels_size[angle % 360] line = gui.SvgLine(x, 0, x, y) line.set_stroke(1, 'white') self.group_orientation_indicator.append(line) txt = gui.SvgText(x, y, labels.get(angle % 360, '')) txt.attr_dominant_baseline = 'hanging' txt.attr_text_anchor = 'middle' txt.set_fill('white') txt.css_font_size = gui.to_pix(7 * labels_size[angle % 360]) txt.css_font_weight = 'bolder' self.group_orientation_indicator.append(txt) self.subcontainer.append(self.group_orientation_indicator) #self.group_orientation_indicator.attributes['transform'] = 'translate(0 %s)'%(self.vh/2-0.11*self.vh) self.orientation_pointer = gui.SvgPolygon(3) self.orientation_pointer.set_fill('red') self.orientation_pointer.set_stroke(0.005 * self.scale_length_visible, 'black') self.orientation_pointer.add_coord(-0.01 * self.scale_length_visible, -0.02 * self.high) self.orientation_pointer.add_coord(0.0 * self.scale_length_visible, 0.0 * self.high) self.orientation_pointer.add_coord(0.01 * self.scale_length_visible, -0.02 * self.high) #self.orientation_pointer.attributes['transform'] = 'translate(0 %s)'%(self.vh/2-0.11*self.vh) self.append(self.orientation_pointer) self.orientation_value = gui.SvgText(0, -0.03 * high, "%d" % (self.orientation % 360)) self.orientation_value.attr_dominant_baseline = 'auto' self.orientation_value.attr_text_anchor = 'middle' self.orientation_value.set_fill('white') self.orientation_value.css_font_size = gui.to_pix( 0.03 * self.scale_length_visible) self.orientation_value.css_font_weight = 'bolder' #orientation_value.attributes['transform'] = 'translate(0 %s)'%(self.vh/2-0.11*self.vh) self.append(self.orientation_value)
def Draw_a_drawing_of_one_sheet(self, nrOfOccs, occs, parent_id): ''' - parent_id: the ID of the whole occurrence(box) of which the occNames(occurrences) are parts. ''' outputUID = '640019' # output role inputUID = '640016' # input role actorUID = '5036' # actor role (supertype of mechanism) subOutputs, subOutputUIDs = self.gel_net.Determine_subtype_list( outputUID) subInputs, subInputUIDs = self.gel_net.Determine_subtype_list(inputUID) subActors, subActorUIDs = self.gel_net.Determine_subtype_list(actorUID) thickness = 2 centerX = [] # X-Center of box[i] on canvas centerY = [] # Y-Center of box[i] on canvas midPts = [] boxes_on_sheet = [] lines_on_sheet = [] box_width = 120 # pixels box_height = 80 # pixels self.boxW2 = box_width / 2 # 1/2Width of boxes self.boxH2 = box_height / 2 # 1/2Height of boxes deltaX = self.screen_width / (nrOfOccs + 1) deltaY = self.screen_height / (nrOfOccs + 1) dxC = 8 # corner rounding dyC = 8 # dx = 8 # shifted start point for line on box dy = 8 # Initialize inputs, outputs, controls and mechanisms according to IDEF0. # occCon, occMech, occConUp and 0ccMechUp not yet used, but later exprected occIn = [] occOut = [] # occCon = [] # occMech = [] occInUp = [] occOutUp = [] # occConUp = [] # occMechUp = [] # Draw boxes (occurrences), return midpts[i] = N(x,y), S(x,y), E(x,y), W(x,y) for boxNr in range(0, nrOfOccs): centerX.append(deltaX + boxNr * deltaX) # X of center of box[i] on canvas centerY.append(deltaY + boxNr * deltaY) # Y of center of box[i] on canvas self.boxID = str(parent_id) + '.' + str(boxNr + 1) midPts.append( self.box_type_1(centerX[boxNr], centerY[boxNr], occs[boxNr].name)) # Debug print('NSEWPts:',boxNr,midPts[boxNr]) self.boxes.append(boxes_on_sheet) # Initialize number of I/O/C/M down and upwards for each occurrence on sheet occIn = [0 for i in range(0, nrOfOccs) ] # input stream nr of deltas downward occOut = [0 for i in range(0, nrOfOccs)] # occCon = [0 for i in range(0, nrOfOccs)] # control stream nr of deltas right # occMech = [0 for i in range(0, nrOfOccs)] occInUp = [0 for i in range(0, nrOfOccs) ] # input stream nr of deltas upward occOutUp = [0 for i in range(0, nrOfOccs)] # occConUp = [0 for i in range(0, nrOfOccs)] # control stream nr of deltas left # occMechUp = [0 for i in range(0, nrOfOccs)] # Draw lines (streams) strNr = 0 hor_size = 15 # horizontal half size of the rhombus polygon vert_size = 25 # vertical half size of the rhombus polygon left = True # indicator for left or right streamTree. border = 5 # Search for lines that have no begin/source occurrence (box), # but only a destination occurrence. for occur, involved, inv_role_kind, inv_kind_name in self.involv_table: # Debug print('ioRow[0]:', occur.uid, occur.name, involved.name, inv_role_kind.name) occUIDFrom = '0' # If inputStream to occurrence on this sheet, then if occur in occs and inv_role_kind.uid in subInputUIDs: # IndexTo is the nr of the occ that has stream as input. indexTo = occs.index(occur) # Verify whether found stream is an output of any box on sheet, # then set out = True origin = 'external' for occur_2, involved_2, inv_role_kind_2, inv_kind_name_2 in self.involv_table: if involved == involved_2 and occur_2 in occs \ and inv_role_kind_2.uid in subOutputUIDs: origin = 'box' break if origin == 'external': # Input comes from outside the sheet streamUID = involved.uid streamName = involved.name streamKind = inv_kind_name occIn[indexTo] += 1 occInUp[indexTo] += 1 strNr = strNr + 1 strID = str(strNr) endPt = midPts[indexTo][3] beginPt = [border, midPts[indexTo][3][1]] # Draw rhombus at x,y and determine its end points x = (beginPt[0] + endPt[0]) / 2 y = beginPt[1] rhombus = self.RhombusPolygon(x, y, strID, hor_size, vert_size) # Draw two straight lines from the left hand side to the rhombus # and from the rhombus to the box lConnPt = rhombus[3] rConnPt = rhombus[2] line1Pts = [beginPt, lConnPt] line2Pts = [rConnPt, endPt] line1 = gui.SvgLine(line1Pts[0][0], line1Pts[0][1], line1Pts[1][0], line1Pts[1][1]) line1.set_stroke(width=thickness, color='black') self.sheets[self.sheet_nr].append(line1) line2 = gui.SvgLine(line2Pts[0][0], line2Pts[0][1], line2Pts[1][0], line2Pts[1][1]) line2.set_stroke(width=thickness, color='black') self.sheets[self.sheet_nr].append(line2) lines_on_sheet.append(line1) lines_on_sheet.append(line2) # Add an arrow head to line2 head = SvgPolygon(4) arrow_height = 20 arrow_width = arrow_height / 3 recess = arrow_height / 5 head.add_arrow_coord(line2, arrow_height, arrow_width, recess) head.set_stroke(width=thickness, color='black') head.set_fill(color='blue') self.sheets[self.sheet_nr].append(head) # lines_on_sheet.append(head) # Record stream in left or right stream table values = [strID, streamName, streamUID, streamKind] table_row = gui.TableRow(style={'text-align': 'left'}) for field in values: item = gui.TableItem(text=field, style={ 'text-align': 'left', 'background-color': self.occ_color }) table_row.append(item) if left is True: # Debug print('Sheet nr:', self.sheet_nr) self.left_str_tables[self.sheet_nr].append(table_row) left = False else: self.right_str_tables[self.sheet_nr].append(table_row) left = True # Find streams per occurrence (box) on this sheet in involv_table # involv_table: occur_obj, involved_obj, role_obj (of invObj), invKindName. # Debug print('subI/O-UIDs:',occs[0].name, subInputUIDs, subOutputUIDs) for occ, involved, inv_role_kind, inv_kind_name in self.involv_table: # Debug print(' ioRow2:', occs[0].name, occ.name, involved.name, inv_role_kind.uid) occUIDTo = '0' # If outputStream from occurrence on this sheet, then if occ in occs and inv_role_kind.uid in subOutputUIDs: # Debug print('**outputStream:', involved.name, inv_role_kind.name) strNr = strNr + 1 strID = str(strNr) occUIDFrom = occ.uid streamUID = involved.uid streamName = involved.name streamKind = inv_kind_name # Verify if found streamUID is input in box on sheet. # If yes, then occUIDTo is known. for occ_2, involved_2, inv_role_kind_2, inv_kind_name_2 in self.involv_table: if streamUID == involved_2.uid and occ_2 in occs \ and inv_role_kind_2.uid in subInputUIDs: # Debug print('** inputStream:', occ_2.name, # inv_role_kind_2.name, inv_role_kind_2.name) occUIDTo = occ_2.uid # else occUIDTo remains '0' break # Determine index (in list of occs) of boxFrom and boxTo indexFrom = -1 indexTo = -1 for index in range(0, len(occs)): if occUIDFrom == occs[index].uid: indexFrom = index if occUIDTo == occs[index].uid: indexTo = index # Determine the sequenceNr of the input and output of the occurrence box # and adjust Yin and Yout accordingly. # Draw the stream line from box occUIDFrom to occUIDTo or to edge of sheet. if indexTo == -1: # No destination box, thus endPt is on rh side of the sheet. ddyFrom = (occOut[indexFrom]) * dy ddyTo = (occIn[indexTo]) * dy if occOut[indexFrom] == 0: # if not yet started downward, then middle becomes occupied. occOutUp[indexFrom] += 1 occOut[indexFrom] += 1 # occOut[indexTo] += 1 # indexTo == -1 # midPts(occNr, East, x / y) beginPt = [ midPts[indexFrom][2][0], midPts[indexFrom][2][1] + ddyFrom ] endPt = [self.screen_width - border, beginPt[1]] x = (beginPt[0] + endPt[0]) / 2 y = beginPt[1] # Rhombus on vertical line rhombus = self.RhombusPolygon(x, y, strID, hor_size, vert_size) lConnPt = rhombus[3] rConnPt = rhombus[2] line1Pts = [beginPt, lConnPt] line2Pts = [rConnPt, endPt] elif indexFrom + 1 < indexTo: # Destination box is behind next box. ddyFrom = (occOut[indexFrom]) * dy ddyTo = (occIn[indexTo]) * dy occOut[indexFrom] += 1 occOut[indexTo] += 1 beginPt = [ midPts[indexFrom][2][0], midPts[indexFrom][2][1] + ddyFrom ] endPt = [ midPts[indexTo][3][0], midPts[indexTo][3][1] + ddyTo ] mid1Pt = [ (beginPt[0] + midPts[indexFrom + 1][3][0]) / 2 - dxC, beginPt[1] ] mid2Pt = [(beginPt[0] + midPts[indexFrom + 1][3][0]) / 2, beginPt[1] + dyC] mid3Pt = [(beginPt[0] + midPts[indexFrom + 1][3][0]) / 2, endPt[1] - dyC] mid4Pt = [ (beginPt[0] + midPts[indexFrom + 1][3][0]) / 2 + dxC, endPt[1] ] x = mid2Pt[0] y = (mid2Pt[1] + mid3Pt[1]) / 2 rhombus = self.RhombusPolygon(x, y, strID, hor_size, vert_size) uConnPt = rhombus[0] lConnPt = rhombus[1] line1Pts = [beginPt, mid1Pt, mid2Pt, uConnPt] line2Pts = [lConnPt, mid3Pt, mid4Pt, endPt] elif indexFrom + 1 > indexTo: # Destination box id before source box (or the box itself). ddyUpFrom = (occOutUp[indexFrom]) * dy ddyUpTo = (occInUp[indexTo]) * dy occOutUp[indexFrom] += 1 occOutUp[indexTo] += 1 beginPt = [ midPts[indexFrom][2][0], midPts[indexFrom][2][1] - ddyUpFrom ] endPt = [ midPts[indexTo][3][0], midPts[indexTo][3][1] - ddyUpTo ] mid1Pt = [ (beginPt[0] + midPts[indexFrom + 1][3][0]) / 2 - dxC, beginPt[1] ] mid2Pt = [(beginPt[0] + midPts[indexFrom + 1][3][0]) / 2, beginPt[1] - dyC] mid3Pt = [(beginPt[0] + midPts[indexFrom + 1][3][0]) / 2, endPt[1] - box_height + dyC] mid4Pt = [ (beginPt[0] + midPts[indexFrom + 1][3][0]) / 2 - dxC, endPt[1] - box_height ] mid5Pt = [(endPt[0] - box_width / 2) + dxC, endPt[1] - box_height] mid6Pt = [(endPt[0] - box_width / 2), endPt[1] - box_height + dyC] mid7Pt = [(endPt[0] - box_width / 2), endPt[1] - dyC] mid8Pt = [(endPt[0] - box_width / 2) + dxC, endPt[1]] x = mid2Pt[0] y = (mid2Pt[1] + mid3Pt[1]) / 2 rhombus = self.RhombusPolygon(x, y, strID, hor_size, vert_size) uConnPt = rhombus[0] lConnPt = rhombus[1] line1Pts = [beginPt, mid1Pt, mid2Pt, lConnPt] line2Pts = [ uConnPt, mid3Pt, mid4Pt, mid5Pt, mid6Pt, mid7Pt, mid8Pt, endPt ] ## if mid5Pt[1] < 0: ## self.sheets[self.sheet_nr].yview_scroll(int(-mid5Pt[1]) + 20, 'units') else: # Destination box is next box ddyFrom = (occOut[indexFrom]) * dy ddyUpTo = (occIn[indexTo]) * dy occOut[indexFrom] += 1 occOutUp[indexTo] += 1 beginPt = [ midPts[indexFrom][2][0], midPts[indexFrom][2][1] + ddyFrom ] endPt = [ midPts[indexTo][3][0], midPts[indexTo][3][1] - ddyUpTo ] mid1Pt = [(beginPt[0] + endPt[0]) / 2 - dxC, beginPt[1]] mid2Pt = [(beginPt[0] + endPt[0]) / 2, beginPt[1] + dyC] mid3Pt = [(beginPt[0] + endPt[0]) / 2, endPt[1] - dyC] mid4Pt = [(beginPt[0] + endPt[0]) / 2 + dxC, endPt[1]] x = mid2Pt[0] y = (mid2Pt[1] + mid3Pt[1]) / 2 rhombus = self.RhombusPolygon(x, y, strID, hor_size, vert_size) uConnPt = rhombus[0] lConnPt = rhombus[1] line1Pts = [beginPt, mid1Pt, mid2Pt, uConnPt] line2Pts = [lConnPt, mid3Pt, mid4Pt, endPt] # Draw polyline 1 from box to rhombus and polyline 2 from rhombus to box # Debug print(' Stream:', indexFrom, indexTo, line1Pts) line1 = gui.SvgPolyline(_maxlen=4) for pt in line1Pts: line1.add_coord(pt[0], pt[1]) line1.set_stroke(width=thickness, color='black') self.sheets[self.sheet_nr].append(line1) line2 = gui.SvgPolyline(_maxlen=8) for pt in line2Pts: line2.add_coord(pt[0], pt[1]) line2.set_stroke(width=thickness, color='black') self.sheets[self.sheet_nr].append(line2) lines_on_sheet.append(line1) lines_on_sheet.append(line2) # Add an arrow head to line2 head2 = SvgPolygon(4) arrow_height = 20 arrow_width = arrow_height / 3 recess = arrow_height / 5 head2.add_arrow_coord(line2, arrow_height, arrow_width, recess) head2.set_stroke(width=thickness, color='black') head2.set_fill(color='blue') self.sheets[self.sheet_nr].append(head2) # Record stream in self.left_str_tables # or in self.right_str_tables[self.sheet_nr](s) values = [strID, streamName, streamUID, streamKind] table_row = gui.TableRow(style={'text-align': 'left'}) for field in values: item = gui.TableItem(text=field, style={ 'text-align': 'left', 'background-color': self.occ_color }) table_row.append(item) if left is True: self.left_str_tables[self.sheet_nr].append(table_row) left = False else: self.right_str_tables[self.sheet_nr].append(table_row) left = True self.lines.append(lines_on_sheet)
def __init__(self, epics_pv_name='', min_value=0, max_value=100, *args, **kwargs): w = kwargs.get("style", {}).get("width", kwargs.get("width", 100)) h = kwargs.get("style", {}).get("height", kwargs.get("height", 100)) if 'width' in kwargs.keys(): del kwargs["width"] if 'height' in kwargs.keys(): del kwargs["height"] default_style = {'position': 'absolute', 'left': '10px', 'top': '10px'} default_style.update(kwargs.get('style', {})) kwargs['style'] = default_style super(EPICSValueGaugeWidget, self).__init__(w, h, *args, **kwargs) self.epics_pv_name = epics_pv_name #the indicator self.indicator = gui.SvgPolygon(_maxlen=4) self.indicator.set_stroke(width=0.001, color='red') self.indicator.set_fill('red') indicator_pin_radius = 0.05 self.indicator_pin = gui.SvgCircle(0, 0.5, indicator_pin_radius) self.indicator_pin.set_fill('black') #the value signs scale = max_value - min_value radius_min = 0.4 radius_max = 0.5 for i in range(0, 10): angle = math.pi / 9 * i #sign = gui.SvgLine(math.cos(angle)*radius_min, radius_max-math.sin(angle)*radius_min, math.cos(angle)*radius_max, radius_max-math.sin(angle)*radius_max) sign = gui.SvgLine( math.cos(angle) * (radius_min - 0.01 + 0.1 * (i + 1) / 10), radius_max - math.sin(angle) * (radius_min - 0.01 + 0.1 * (i + 1) / 10), math.cos(angle) * radius_max, radius_max - math.sin(angle) * radius_max) sign.set_stroke(0.01, 'black') self.append(sign) #subindicators value signs scale = max_value - min_value radius_min = 0.4 radius_max = 0.5 for i in range(0, 100): angle = math.pi / 99 * i #sign = gui.SvgLine(math.cos(angle)*radius_min, radius_max-math.sin(angle)*radius_min, math.cos(angle)*radius_max, radius_max-math.sin(angle)*radius_max) sign = gui.SvgLine( math.cos(angle) * (radius_min - 0.01 + 0.1 * (i + 10) / 100), radius_max - math.sin(angle) * (radius_min - 0.01 + 0.1 * (i + 10) / 100), math.cos(angle) * radius_max, radius_max - math.sin(angle) * radius_max) sign.set_stroke(0.002, 'black') self.append(sign) font_size = 0.1 self.text_min_value = gui.SvgText(-radius_max, 0.5 + font_size + 0.01, str(min_value)) self.text_min_value.style['font-size'] = gui.to_pix(font_size) self.text_min_value.style['text-anchor'] = "start" self.text_max_value = gui.SvgText(radius_max, 0.5 + font_size + 0.01, str(max_value)) self.text_max_value.style['font-size'] = gui.to_pix(font_size) self.text_max_value.style['text-anchor'] = "end" self.text_actual_value = gui.SvgText( 0, 0.5 + indicator_pin_radius + font_size + 0.01, str(max_value)) self.text_actual_value.style['font-size'] = gui.to_pix(font_size) self.text_actual_value.style['text-anchor'] = "middle" self.text_actual_value.style['font-weight'] = 'bold' self.min_value = min_value self.max_value = max_value self.append([ self.indicator, self.indicator_pin, self.text_min_value, self.text_max_value, self.text_actual_value ]) self.set_viewbox(-0.5, 0, 1, 0.70) self.value = self.min_value
def Draw_a_drawing_of_one_sheet(self, nr_of_boxes, box_names): """ Draw a drawing with two boxes, each with a name inside and a polyline between the midpoints of the sides of the boxes, with half-way the polyline a rhombus with an id included. """ thickness = 2 # Line thickness center_x = [] # x of the center of box[i] on canvas center_y = [] # y of the center of box[i] on canvas mid_points = [] box_width = 100 # pixels box_height = 100 # pixels delta_x = self.screen_width / (nr_of_boxes + 1) delta_y = self.screen_height / (nr_of_boxes + 1) # Draw the boxes for box_nr in range(0, nr_of_boxes): center_x.append(delta_x + box_nr * delta_x) center_y.append(delta_y + box_nr * delta_y) name = box_names[box_nr] ident = str(box_nr + 1) # Draw one box at the specified location mid_points.append( self.box_type_1(center_x[box_nr], center_y[box_nr], name, ident, box_width, box_height)) # Draw a line with arrow head to the first box x2 = mid_points[0][3][0] y2 = mid_points[0][3][1] x1 = x2 - 150 y1 = y2 line_0 = gui.SvgLine(x1, y1, x2, y2) line_0.set_stroke(width=thickness, color='black') self.sheet.append(line_0) # Add an arrow head to line_0 head_0 = SvgPolygon(4) arrow_height = 20 arrow_width = arrow_height / 3 recess = arrow_height / 5 head_0.add_arrow_coord(line_0, arrow_height, arrow_width, recess) head_0.set_stroke(width=thickness, color='black') head_0.set_fill(color='blue') self.sheet.append(head_0) # Draw a rhombus polygon x = (center_x[0] + center_x[1]) / 2 y = (center_y[0] + center_y[1]) / 2 self.int_id += 1 str_id = str(self.int_id) hor_size = 15 # pixels vert_size = 25 # pixels rhombus = self.rhombus_polygon(x, y, str_id, hor_size, vert_size) # Determine points of the first polyline line_1_points = [] line_1_points.append(mid_points[0][2]) corner = [rhombus[0][0], mid_points[0][2][1]] line_1_points.append(corner) line_1_points.append(rhombus[0]) # Draw a polyline from box_1 to rhombus line1 = gui.SvgPolyline(_maxlen=4) for pt in line_1_points: line1.add_coord(*pt) line1.set_stroke(width=thickness, color='black') self.sheet.append(line1) # Determine points of the second polyline line_2_points = [] line_2_points.append(rhombus[1]) corner = [rhombus[1][0], mid_points[1][3][1]] line_2_points.append(corner) line_2_points.append(mid_points[1][3]) # Drawa polyline from rhombus to box_2 line2 = gui.SvgPolyline(_maxlen=4) for pt in line_2_points: line2.add_coord(pt[0], pt[1]) line2.set_stroke(width=thickness, color='black') self.sheet.append(line2) # Add an arrow head to line2 head = SvgPolygon(4) head.add_arrow_coord(line2, arrow_height, arrow_width, recess) head.set_stroke(width=thickness, color='black') head.set_fill(color='blue') self.sheet.append(head)