# # Copyright (C) 2015 vmware inc. # # Author: Mahmoud Bassiouny import curses from actionresult import ActionResult from action import Action class Window(Action): def __init__(self, height, width, maxy, maxx, title, can_go_back, action_panel=None, items=None, menu_helper=None, position=0, tab_enabled=True, can_go_next=False, read_text=False): self.can_go_back = can_go_back self.can_go_next = can_go_next self.height = height self.width = width self.y = (maxy - height) // 2 self.x = (maxx - width) // 2 title = ' ' + title + ' ' self.contentwin = curses.newwin(height - 1, width -1) self.contentwin.bkgd(' ', curses.color_pair(2)) #Default Window color self.contentwin.erase() self.contentwin.box() self.tab_enabled = tab_enabled self.read_text = read_text self.position = position if items: self.items = items else: self.items = [] self.menu_helper = menu_helper self.contentwin.addstr(0, (width - 1 - len(title)) // 2, title)# newy = 5 if self.can_go_back: self.contentwin.addstr(height - 3, 5, '') if self.can_go_next and self.can_go_back: self.update_next_item() self.dist = 0 if len(self.items) > 0: #To select items, we need to identify up left right keys self.dist = self.width-11 self.dist -= len('') count = 0 for item in self.items: self.dist -= len(item[0]) count += 1 self.dist = self.dist // count self.contentwin.keypad(1) newy += len('') newy += self.dist for item in self.items: self.contentwin.addstr(height - 3, newy, item[0]) newy += len(item[0]) newy += self.dist self.textwin = curses.newwin(height - 5, width - 5) self.textwin.bkgd(' ', curses.color_pair(2)) #Default Window color self.shadowwin = curses.newwin(height - 1, width - 1) self.shadowwin.bkgd(' ', curses.color_pair(0)) #Default shadow color self.contentpanel = curses.panel.new_panel(self.contentwin) self.textpanel = curses.panel.new_panel(self.textwin) self.shadowpanel = curses.panel.new_panel(self.shadowwin) self.action_panel = action_panel self.refresh(0, True) self.hide_window() def update_next_item(self): self.position = 1 self.items.append(('', self.next_function, False)) self.tab_enabled = False def next_function(self, params): return ActionResult(True, None) def set_action_panel(self, action_panel): self.action_panel = action_panel def update_menu(self, action_result): if (action_result.result and 'goNext' in action_result.result and action_result.result['goNext']): return ActionResult(True, None) if self.position == 0: self.contentwin.addstr(self.height - 3, 5, '') self.contentwin.refresh() self.hide_window() self.action_panel.hide() return ActionResult(False, None) else: if (action_result.result != None and 'diskIndex' in action_result.result): params = action_result.result['diskIndex'] if self.menu_helper: self.menu_helper(params) result = self.items[self.position-1][1](None) if result.success: self.hide_window() self.action_panel.hide() return result else: if 'goBack' in result.result and result.result['goBack']: self.contentwin.refresh() self.hide_window() self.action_panel.hide() return ActionResult(False, None) def do_action(self): self.show_window() if self.tab_enabled: self.refresh(0, False) else: self.refresh(0, True) action_result = self.action_panel.do_action() if action_result.success: if (action_result.result and 'goNext' in action_result.result and action_result.result['goNext']): return ActionResult(True, None) if self.position != 0: #saving the disk index self.items[self.position-1][1](None) if self.items: return self.update_menu(action_result) self.hide_window() return action_result else: if (not self.tab_enabled and action_result.result != None and 'direction' in action_result.result): self.refresh(action_result.result['direction'], True) if (action_result.result != None and 'goBack' in action_result.result and action_result.result['goBack']): self.hide_window() self.action_panel.hide() return action_result else: #highlight the GoBack and keep going self.refresh(0, True) while action_result.success == False: if self.read_text: is_go_back = self.position == 0 action_result = self.action_panel.do_action(returned=True, go_back=is_go_back) if action_result.success: if self.items: return self.update_menu(action_result) self.hide_window() return action_result else: if (action_result.result != None and 'goBack' in action_result.result and action_result.result['goBack']): self.hide_window() self.action_panel.hide() return action_result if action_result.result and 'direction' in action_result.result: self.refresh(action_result.result['direction'], True) else: key = self.contentwin.getch() if key in [curses.KEY_ENTER, ord('\n')]: #remove highlight from Go Back if self.position == 0: self.contentwin.addstr(self.height - 3, 5, '') self.contentwin.refresh() self.hide_window() self.action_panel.hide() return ActionResult(False, None) else: if (action_result.result != None and 'diskIndex' in action_result.result): params = action_result.result['diskIndex'] if self.menu_helper: self.menu_helper(params) result = self.items[self.position-1][1](None) if result.success: self.hide_window() self.action_panel.hide() return result else: if 'goBack' in result.result and result.result['goBack']: self.contentwin.refresh() self.hide_window() self.action_panel.hide() return ActionResult(False, None) elif key in [ord('\t')]: if not self.tab_enabled: continue #remove highlight from Go Back self.refresh(0, False) # go do the action inside the panel action_result = self.action_panel.do_action() if action_result.success: self.hide_window() return action_result else: #highlight the GoBack and keep going self.refresh(0, True) elif key == curses.KEY_UP or key == curses.KEY_LEFT: if key == curses.KEY_UP and self.tab_enabled == False: self.action_panel.navigate(-1) action_result = self.action_panel.do_action() if action_result.success: if self.items: return self.update_menu(action_result) self.hide_window() return action_result else: if 'direction' in action_result.result: #highlight the GoBack and keep going self.refresh(action_result.result['direction'], True) else: self.refresh(-1, True) elif key == curses.KEY_DOWN or key == curses.KEY_RIGHT: if key == curses.KEY_DOWN and self.tab_enabled == False: self.action_panel.navigate(1) action_result = self.action_panel.do_action() if action_result.success: if self.items: return self.update_menu(action_result) self.hide_window() return action_result else: if 'direction' in action_result.result: #highlight the GoBack and keep going self.refresh(action_result.result['direction'], True) else: self.refresh(1, True) def refresh(self, n, select): if not self.can_go_back: return self.position += n if self.position < 0: self.position = 0 elif self.items and self.position > len(self.items): #add 1 for the self.position = len(self.items) if not self.items and not self.can_go_next: self.position = 0 #add the highlight newy = 5 if self.position == 0: #go back if select: self.contentwin.addstr(self.height - 3, 5, '', curses.color_pair(3)) elif self.items: #show user the last selected items self.contentwin.addstr(self.height - 3, 5, '', curses.color_pair(1)) else: #if Go back is the only one shown, do not highlight at all self.contentwin.addstr(self.height - 3, 5, '') newy += len('') newy += self.dist if self.items: for item in self.items: self.contentwin.addstr(self.height - 3, newy, item[0]) newy += len(item[0]) newy += self.dist else: self.contentwin.addstr(self.height - 3, 5, '') newy += len('') newy += self.dist index = 1 for item in self.items: if index == self.position: if select: self.contentwin.addstr(self.height - 3, newy, item[0], curses.color_pair(3)) else: self.contentwin.addstr(self.height - 3, newy, item[0], curses.color_pair(1)) else: self.contentwin.addstr(self.height - 3, newy, item[0]) newy += len(item[0]) newy += self.dist index += 1 self.contentwin.refresh() def show_window(self): y = self.y x = self.x self.shadowpanel.top() self.contentpanel.top() self.textpanel.top() self.shadowpanel.move(y + 1, x + 1) self.contentpanel.move(y, x) self.textpanel.move(y + 2, x + 2) self.shadowpanel.show() self.contentpanel.show() self.textpanel.show() curses.panel.update_panels() curses.doupdate() if self.can_go_next: self.position = 1 def hide_window(self): self.shadowpanel.hide() self.contentpanel.hide() self.textpanel.hide() curses.panel.update_panels() curses.doupdate() def addstr(self, y, x, str, mode=0): self.textwin.addstr(y, x, str, mode) def adderror(self, str): self.textwin.addstr(self.height - 7, 0, str, curses.color_pair(4)) self.textwin.refresh() def clearerror(self): spaces = ' ' * (self.width - 6) self.textwin.addstr(self.height - 7, 0, spaces) self.textwin.refresh() def content_window(self): return self.textwin