1import sys 2import time 3 4from arcade.glui.dialog import Dialog 5from arcade.glui.opengl import gl 6from arcade.glui.render import Render 7from arcade.glui.state import State 8from arcade.resources import resources 9 10MAX_LINE = 30 11 12 13def show_exception(): 14 import traceback 15 16 backtrace = traceback.format_exc() 17 State.get().dialog = ErrorDialog(sys.exc_info()[1], backtrace) 18 show_error_state = {"stop": False} 19 while not show_error_state["stop"]: 20 21 def input_func(button): 22 if button == "BACK": 23 show_error_state["stop"] = True 24 25 # FIXME 26 from arcade.glui.window import main_loop_iteration 27 28 if main_loop_iteration(input_func=input_func): 29 break 30 State.get().dialog.destroy() 31 State.get().dialog = None 32 33 34class ErrorDialog(Dialog): 35 def __init__(self, message, backtrace=None): 36 Dialog.__init__(self) 37 self.width = 16 / 9 * 2 38 self.height = 2.0 39 self.message = message 40 self.backtrace = backtrace 41 self.splitted = self.backtrace.split("\n") 42 if not self.splitted[-1]: 43 self.splitted = self.splitted[:-1] 44 45 self.background_color = (0.0, 0.0, 0.0, 1.0) 46 liberation_mono_bold = resources.resource_filename( 47 "LiberationMono-Regular.ttf" 48 ) 49 self.detail_font = pygame.font.Font( 50 liberation_mono_bold, int(0.021 * Render.get().display_height) 51 ) 52 self.guru_font = pygame.font.Font( 53 liberation_mono_bold, int(0.03 * Render.get().display_height) 54 ) 55 self.start_time = time.time() 56 57 def render_content(self): 58 Render.get().dirty = True 59 60 # #x1 = -16 / 9 + 0.1 61 # x1 = 0.1 62 # #x2 = 16 / 9 - 0.1 63 # x2 = self.width - 0.1 64 # #y1 = 0.7 65 # #y2 = 0.9 66 # y1 = 1.6 67 # y2 = 1.9 68 x1 = 0 69 x2 = self.width 70 y1 = 1.7 71 y2 = 2.0 72 w = 0.03 73 74 # t = (pygame.time.get_ticks() - self.start_time) // 1000 75 alert_color = (1.0, 0.8, 0.0) 76 t = int((time.time() - self.start_time * 1.6)) 77 if t % 2 == 0: 78 gl.glBegin(gl.GL_QUADS) 79 gl.glColor3f(*alert_color) 80 gl.glVertex2f(x1, y1) 81 gl.glVertex2f(x2, y1) 82 gl.glVertex2f(x2, y2) 83 gl.glVertex2f(x1, y2) 84 gl.glColor3f(0.0, 0.0, 0.0) 85 gl.glVertex2f(x1 + w, y1 + w) 86 gl.glVertex2f(x2 - w, y1 + w) 87 gl.glVertex2f(x2 - w, y2 - w) 88 gl.glVertex2f(x1 + w, y2 - w) 89 gl.glEnd() 90 91 text = "Software Failure. Press BACKSPACE or back button to continue." 92 Render.get().text(text, self.guru_font, 0.2, 1.85, color=alert_color) 93 text = self.splitted[-1] 94 text = "Guru Meditation #{0}".format(text) 95 Render.get().text(text, self.guru_font, 0.2, 1.77, color=alert_color) 96 97 x = 0.2 98 y = 0.15 99 100 tw, th = Render.get().measure_text("M", self.detail_font) 101 y += th 102 lines = [] 103 max_line_size = 129 104 for line in self.splitted: 105 line = line.rstrip() 106 while len(line) > max_line_size: 107 lines.append(line[:max_line_size]) 108 line = line[max_line_size:] 109 lines.append(line) 110 111 for i, line in enumerate(reversed(lines)): 112 if i == MAX_LINE: 113 break 114 s = (MAX_LINE - i) / MAX_LINE 115 tw, th = Render.get().text( 116 line, self.detail_font, x, y, color=(s, s, s, 1.0) 117 ) 118 y += th 119