class GridDisplay(object): def __init__(self, width, height, font): self.width = width self.height = height self.font = font # self.internal_cgrid = Cgrid(width=width, height=height) (self.cwidth, self.cheight) = font.size('@') # dim = (width * self.cwidth, height * self.cheight) self.screen = pygame.display.set_mode(dim) def update(self, cgrid): cur_dim = (self.internal_cgrid.width, self.internal_cgrid.height) new_dim = (cgrid.width, cgrid.height) if cur_dim != new_dim: self.internal_cgrid.set_dimensions(width=cgrid.width, height=cgrid.height) updates = [] o_spots = self.internal_cgrid.spots n_spots = cgrid.spots for idx, (o_spot, n_spot) in enumerate(zip(o_spots, n_spots)): if not o_spot.compare(n_spot): updates.append(idx) o_spot.mimic(n_spot) for idx in updates: spot = self.internal_cgrid.spots[idx] (font_fg, font_bg) = MAP_CONST_COLOURS_TO_CPAIR[spot.cpair] label = self.font.render(spot.c, 1, font_fg, font_bg) # drop_pixels = self.cwidth * int(idx % self.internal_cgrid.width) rest_pixels = self.cheight * int(idx / self.internal_cgrid.width) self.screen.blit(label, (drop_pixels, rest_pixels)) pygame.display.flip() def coords_from_mousepos(self, xpos, ypos): ''' From the supplied pixel dimensions, return the drop and rest of the selected grid reference. ''' rest = int(xpos / self.cwidth) drop = int(ypos / self.cheight) return (drop, rest)
class ImplGridConsole: def __init__(self): self.form = FormGridConsole(self) # clib = load_clib(self) # self.api = Ns() self.api.set_cc_log = init_ext_fn(None, clib.set_cc_log, [CC_LOG_T]) self.api.create_screen = init_ext_fn(None, clib.create_screen, [c_int, c_int]) self.api.process_windows_events = init_ext_fn( c_int, clib.process_windows_events, []) self.api.get_next_event = init_ext_fn(None, clib.get_next_event, [c_uint64_p]) self.api.set = init_ext_fn(None, clib.set, [c_int, c_int, c_int, c_int]) self.api.redraw = init_ext_fn(None, clib.redraw, []) self.api.close = init_ext_fn(None, clib.close, []) def zero(self, zero_h, cb_grid_console_splat, cb_grid_console_kevent, cb_grid_console_mevent, cb_grid_console_closed, engine, width, height): self.zero_h = zero_h self.cb_grid_console_splat = cb_grid_console_splat self.cb_grid_console_kevent = cb_grid_console_kevent self.cb_grid_console_mevent = cb_grid_console_mevent self.cb_grid_console_closed = cb_grid_console_closed self.engine = engine self.width = width self.height = height # if self.width > 200 or self.height > 100: # Note that width and height are by character, not by screen # dimension. log("Warning. Have seen crashes as screen dimensions become vast.") log('width %s %s' % (self.width, type(self.width))) log('height %s %s' % (self.height, type(self.height))) # self.cgrid = Cgrid(width=width, height=height) # # Emphasis: do not use named parameters for this, or the variable # holding the logger will get garbage-collected. You must directly # refer to cc_log. # xxx rename api to c_api self.api.set_cc_log(cc_log) # log('impl_grid_console w:%s h:%s' % (self.width, self.height)) self.api.create_screen(self.width, self.height) self.api.process_windows_events() # self.spin_windows_events = self.engine.init_spin( construct=SpinWindowsEvents, cb_windows_event_quit=self.cb_windows_event_quit, cb_windows_event_kevent=self.cb_windows_event_kevent, api=self.api) def cb_windows_event_quit(self, cs_windows_event_quit): zero_h = cs_windows_event_quit.zero_h # raise SolentQuitException() def cb_windows_event_kevent(self, cs_windows_event_kevent): zero_h = cs_windows_event_kevent.zero_h k = cs_windows_event_kevent.k # # xxx we will need to do some translation here from windows-style # keycodes to solent style. for the moment I am just passing back the # raw values. keycode = k self.form.call_grid_console_kevent(zero_h=self.zero_h, keycode=keycode) # def send(self, cgrid): cur_dim = (self.cgrid.width, self.cgrid.height) new_dim = (cgrid.width, cgrid.height) if cur_dim != new_dim: self.cgrid.set_dimensions(width=cgrid.width, height=cgrid.height) updates = [] o_spots = self.cgrid.spots n_spots = cgrid.spots for cgrid_idx, (o_spot, n_spot) in enumerate(zip(o_spots, n_spots)): if not o_spot.compare(n_spot): updates.append(cgrid_idx) o_spot.mimic(n_spot) log('send') for cgrid_idx in updates: spot = self.cgrid.spots[cgrid_idx] # drop = int(cgrid_idx / self.cgrid.width) rest = int(cgrid_idx % self.cgrid.width) c = ord(spot.c) o = 0 # xxx log('update %s %s %s %s' % (drop, rest, c, o)) self.api.set(drop, rest, c, o) self.api.redraw() def close(self): log('close') return self.api.close()