def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) ## ## Fixed position objects ## self.path = os.path.dirname( os.path.abspath(inspect.getfile( inspect.currentframe()))) # script directory self.objects = { 'titleimage': LCARSImage(pygame.Rect(width / 2, height * 3 / 5, 0, 0), self.path + LOGO_PATH, True), } ## ## Import standard objects self.objects.update(self.border.get_border()) ## ## Position-dependant objects ## self.set_intro_text("Searching for remote database...", Colours.FG) self.set_intro_text_2("Don't have a card? Seeing error messages?", Colours.FG) self.set_intro_text_3("Pop money in the pot instead!", Colours.FG)
def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) border = Border(width, height) self.buttons = Enum("BARCODE", "DESCRIPTION", "PRICE", "DONE", "CANCEL") # # # # Fixed position objects # # minx = border.inner_x() + 4 * Widths.BORDER maxx = width - Widths.BORDER miny = border.inner_y() + 4 * Widths.BORDER maxy = height - Widths.BORDER buttonh = 50 buttonw = 100 fullwidth = maxx - minx self.default_text = { self.buttons.BARCODE: "1. Scan an item", self.buttons.DESCRIPTION: "2. Type a description", self.buttons.PRICE: "3. Set a price", } self.objects = { self.buttons.BARCODE: LCARSCappedBar(pygame.Rect(minx, miny, fullwidth, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "1. Scan an item", Colours.ENTRY, Colours.BG, True), self.buttons.DESCRIPTION: LCARSCappedBar( pygame.Rect(minx, miny + (2 * buttonh), fullwidth, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "2. Type a description", Colours.ERR, Colours.BG, True), self.buttons.PRICE: LCARSCappedBar( pygame.Rect(minx, miny + (4 * buttonh), fullwidth, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "3. Set a price", Colours.ERR, Colours.BG, True), self.buttons.DONE: LCARSCappedBar(pygame.Rect(minx, maxy - buttonh, buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, True), self.buttons.CANCEL: LCARSCappedBar( pygame.Rect(maxx - buttonw, maxy - buttonh, buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), } # # # # Import standard objects # # self.objects.update(border.get_border())
def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) ## ## Fixed position objects ## self.path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory self.objects = { 'titleimage' : LCARSImage(pygame.Rect(width/2, height*3/5, 0, 0), self.path + LOGO_PATH, True), } ## ## Import standard objects self.objects.update(self.border.get_border()) ## ## Position-dependant objects ## self.set_intro_text("Searching for remote database...", Colours.FG) self.set_intro_text_2("Don't have a card? Seeing error messages?", Colours.FG) self.set_intro_text_3("Pop money in the pot instead!", Colours.FG)
def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) border = Border(width, height) self.buttons = Enum("BARCODE", "DESCRIPTION", "PRICE", "DONE", "CANCEL") # # # # Fixed position objects # # minx = border.inner_x() + 4 * Widths.BORDER maxx = width - Widths.BORDER miny = border.inner_y() + 4 * Widths.BORDER maxy = height - Widths.BORDER buttonh = 50 buttonw = 100 fullwidth = maxx - minx self.default_text = { self.buttons.BARCODE : "1. Scan an item", self.buttons.DESCRIPTION : "2. Type a description", self.buttons.PRICE : "3. Set a price", } self.objects = { self.buttons.BARCODE : LCARSCappedBar(pygame.Rect(minx, miny, fullwidth, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "1. Scan an item", Colours.ENTRY, Colours.BG, True), self.buttons.DESCRIPTION : LCARSCappedBar(pygame.Rect(minx, miny + (2 * buttonh), fullwidth, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "2. Type a description", Colours.ERR, Colours.BG, True), self.buttons.PRICE : LCARSCappedBar(pygame.Rect(minx, miny + (4 * buttonh), fullwidth, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "3. Set a price", Colours.ERR, Colours.BG, True), self.buttons.DONE : LCARSCappedBar(pygame.Rect(minx, maxy - buttonh, buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, True), self.buttons.CANCEL : LCARSCappedBar(pygame.Rect(maxx - buttonw, maxy - buttonh, buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), } # # # # Import standard objects # # self.objects.update(border.get_border())
def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) # Object constant definitions # Reverse draw order - 0 drawn last self.ids = Enum("DONE", "CANCEL", "PAY", "TOPBAR", "AMOUNT", "UP", "DOWN", "PRODUCT", "REMOVE") self.limits = Const() self.limits.screen_products = 5 self.limits.objects_per_product_row = 3 self.logger = logging.getLogger("MainScreen.GUI") self.product_displays = ProductDisplayCollection(self.limits.screen_products) # # # # Fixed position objects # # self.layout = MainScreenLayout(width, height, self.border) self.objects = { self.ids.DONE: LCARSCappedBar( self.layout.get_done_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, False), self.ids.PAY:LCARSCappedBar( self.layout.get_pay_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Pay debt", Colours.FG, Colours.BG, False), self.ids.CANCEL:LCARSCappedBar( self.layout.get_cancel_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), self.ids.TOPBAR:LCARSCappedBar( self.layout.get_top_bar_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "User: <No user scanned>", Colours.FG, Colours.BG, True), self.ids.UP: LCARSCappedBar( self.layout.get_up_scroll_rect(), CapLocation.CAP_TOP, "UP", Colours.FG, Colours.BG, False), self.ids.DOWN: LCARSCappedBar( self.layout.get_down_scroll_rect(), CapLocation.CAP_BOTTOM, "DN", Colours.FG, Colours.BG, False), self.ids.AMOUNT:LCARSCappedBar( self.layout.get_amount_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Total Spend: \xA30.00", Colours.FG, Colours.BG, True) } # # # # Import standard objects # # self.objects.update(self.border.get_border())
def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) border = Border(width, height) ## ## Fixed position objects ## buttonw = 100 largebuttonw = buttonw * 2 amountentryw = (buttonw * 4) + (Widths.BORDER * 4) ## Column and row x, y locations cx = [0, 0, 0, 0] #pylint: disable=C0103 cx[0] = 200 cx[1] = cx[0] + buttonw + Widths.BORDER cx[2] = cx[1] + buttonw + Widths.BORDER cx[3] = cx[2] + buttonw + Widths.BORDER + Widths.BORDER buttonh = 50 amountentryh = buttonh * 1.5 ry = [0, 0, 0, 0] #pylint: disable=C0103 ry[0] = 125 ry[1] = ry[0] + amountentryh + Widths.BORDER ry[2] = ry[1] + buttonh + Widths.BORDER ry[3] = ry[2] + buttonh + Widths.BORDER r5y = ry[3] + buttonh + Widths.BORDER r6y = r5y + buttonh + Widths.BORDER cancelbuttonx = cx[ 3] + buttonw - largebuttonw #Right align the "cancel" button self.keys = Enum("KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6", "KEY7", "KEY8", "KEY9", "FIVEPOUNDS", "TENPOUNDS", "TWENTYPOUNDS", "DONE", "CANCEL", "AMOUNT") self.objects = { self.keys.AMOUNT: LCARSCappedBar( pygame.Rect(cx[0], ry[0], amountentryw, amountentryh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "\xA30.00", Colours.FG, Colours.BG, True), self.keys.KEY0: LCARSCappedBar(pygame.Rect(cx[0], r5y, buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "0", Colours.FG, Colours.BG, True), self.keys.KEY1: LCARSCappedBar(pygame.Rect(cx[0], ry[3], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "1", Colours.FG, Colours.BG, True), self.keys.KEY2: LCARSCappedBar(pygame.Rect(cx[1], ry[3], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "2", Colours.FG, Colours.BG, True), self.keys.KEY3: LCARSCappedBar(pygame.Rect(cx[2], ry[3], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "3", Colours.FG, Colours.BG, True), self.keys.KEY4: LCARSCappedBar(pygame.Rect(cx[0], ry[2], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "4", Colours.FG, Colours.BG, True), self.keys.KEY5: LCARSCappedBar(pygame.Rect(cx[1], ry[2], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "5", Colours.FG, Colours.BG, True), self.keys.KEY6: LCARSCappedBar(pygame.Rect(cx[2], ry[2], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "6", Colours.FG, Colours.BG, True), self.keys.KEY7: LCARSCappedBar(pygame.Rect(cx[0], ry[1], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "7", Colours.FG, Colours.BG, True), self.keys.KEY8: LCARSCappedBar(pygame.Rect(cx[1], ry[1], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "8", Colours.FG, Colours.BG, True), self.keys.KEY9: LCARSCappedBar(pygame.Rect(cx[2], ry[1], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "9", Colours.FG, Colours.BG, True), self.keys.FIVEPOUNDS: LCARSCappedBar(pygame.Rect(cx[3], ry[1], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, u"\xA35", Colours.FG, Colours.BG, True), self.keys.TENPOUNDS: LCARSCappedBar(pygame.Rect(cx[3], ry[2], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, u"\xA310", Colours.FG, Colours.BG, True), self.keys.TWENTYPOUNDS: LCARSCappedBar(pygame.Rect(cx[3], ry[3], buttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, u"\xA320", Colours.FG, Colours.BG, True), self.keys.DONE: LCARSCappedBar(pygame.Rect(cx[0], r6y, largebuttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, True), self.keys.CANCEL: LCARSCappedBar( pygame.Rect(cancelbuttonx, r6y, largebuttonw, buttonh), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), } ## ## Import standard objects self.objects.update(border.get_border())
class IntroScreenGUI(ScreenGUI): """ Describes the graphical elements of the intro screen and provides methods for setting introduction text """ def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) ## ## Fixed position objects ## self.path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory self.objects = { 'titleimage' : LCARSImage(pygame.Rect(width/2, height*3/5, 0, 0), self.path + LOGO_PATH, True), } ## ## Import standard objects self.objects.update(self.border.get_border()) ## ## Position-dependant objects ## self.set_intro_text("Searching for remote database...", Colours.FG) self.set_intro_text_2("Don't have a card? Seeing error messages?", Colours.FG) self.set_intro_text_3("Pop money in the pot instead!", Colours.FG) def set_intro_text(self, text, color): """ The intro text is positioned centrally between the sweep and image """ text_y_position = (self.border.inner_y() + self.objects['titleimage'].t()) / 2 self.objects['introtext'] = LCARSText((self.width/2, text_y_position), text, 36, TextAlign.XALIGN_CENTRE, color, Colours.BG, True) def set_intro_text_2(self, text, color): """ The intro text is positioned between the image and the base """ text_y_position = (self.objects['titleimage'].b() + self.border.bottom()) / 2 text_y_position = text_y_position - 30 self.objects['introtext2'] = LCARSText((self.width/2, text_y_position), text, 36, TextAlign.XALIGN_CENTRE, color, Colours.BG, True) def set_intro_text_3(self, text, color): """ The intro text is positioned between the image and the base """ text_y_position = self.objects['introtext2'].t() + 80 self.objects['introtext3'] = LCARSText((self.width/2, text_y_position), text, 36, TextAlign.XALIGN_CENTRE, color, Colours.BG, True) def draw(self, window): """ Draw the screen objects on the supplied window """ window.fill(Colours.BG) for draw_obj in self.objects.values(): draw_obj.draw(window) #Ensure text is drawn on top self.objects['introtext'].draw(window) self.objects['introtext2'].draw(window) self.objects['introtext3'].draw(window) if self.banner is not None: self.banner.draw(window) pygame.display.flip()
class MainScreenGUI(ScreenGUI): """ Describes the graphical elements of the main screen and provides methods for adding and remove products """ def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) # Object constant definitions # Reverse draw order - 0 drawn last self.ids = Enum("DONE", "CANCEL", "PAY", "TOPBAR", "AMOUNT", "UP", "DOWN", "PRODUCT", "REMOVE") self.limits = Const() self.limits.screen_products = 5 self.limits.objects_per_product_row = 3 self.logger = logging.getLogger("MainScreen.GUI") self.product_displays = ProductDisplayCollection(self.limits.screen_products) # # # # Fixed position objects # # self.layout = MainScreenLayout(width, height, self.border) self.objects = { self.ids.DONE: LCARSCappedBar( self.layout.get_done_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, False), self.ids.PAY:LCARSCappedBar( self.layout.get_pay_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Pay debt", Colours.FG, Colours.BG, False), self.ids.CANCEL:LCARSCappedBar( self.layout.get_cancel_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), self.ids.TOPBAR:LCARSCappedBar( self.layout.get_top_bar_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "User: <No user scanned>", Colours.FG, Colours.BG, True), self.ids.UP: LCARSCappedBar( self.layout.get_up_scroll_rect(), CapLocation.CAP_TOP, "UP", Colours.FG, Colours.BG, False), self.ids.DOWN: LCARSCappedBar( self.layout.get_down_scroll_rect(), CapLocation.CAP_BOTTOM, "DN", Colours.FG, Colours.BG, False), self.ids.AMOUNT:LCARSCappedBar( self.layout.get_amount_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Total Spend: \xA30.00", Colours.FG, Colours.BG, True) } # # # # Import standard objects # # self.objects.update(self.border.get_border()) def add_to_product_display(self, product): """ Add a new product to the list """ self.product_displays.add(product) def update_total(self): """ Update the total spend value """ self.objects[self.ids.AMOUNT].setText("Total Spend: \xA3%.2f" % (self.owner.total_price() / 100)) def _remove_button_width(self): """ The width of the remove button depends on whether the up/dn buttons are displayed """ removew = self.width - self.layout.product_entries.remove_x - Widths.BORDER if self._test_display_down_button() or self._test_display_up_button(): removew -= (self.layout.scroll.width + Widths.BORDER) return removew def get_object_id(self, pos): """ Returns the ID of the object at the given position """ object_id = ScreenGUI.get_object_id(self, pos) if object_id == -1: # Try searching remove buttons if self.product_displays.collide_on_remove(pos) is not None: object_id = self.ids.REMOVE return object_id def set_unknown_user(self): """ Indicate that an unknown card was scanned """ self.objects[self.ids.TOPBAR].setText("User: <Unknown card>") def set_user(self, name, balance, credit): """ Set the current username """ if balance >= 0: text = u"%s (Balance: \xA3%.2f" % (name, balance / 100) else: text = u"%s (Balance: -\xA3%.2f" % (name, -balance / 100) if credit > 0: text += u", Pending Credit: \xA3%.2f" % (credit / 100) text += ")" self.objects[self.ids.TOPBAR].setText(text) def _test_display_up_button(self): """ Returns TRUE if the up button should be displayed """ return (self.product_displays.top_index > 0) def _test_display_down_button(self): """ Returns TRUE if the down button should be displayed """ return (self.product_displays.top_index + self.limits.screen_products) < len(self.product_displays) def clear_products(self): """ Reset the products list to nothing """ self.product_displays.clear() def draw(self, window): """ Redraw the main screen """ window.fill(Colours.BG) self._set_show_hide_products() self._draw_products(window) self._draw_static_objects(window) pygame.display.flip() def _set_show_hide_products(self): """ Scan down the product list and set the visible state of the product objects """ visible_count = 0 for (counter, product) in enumerate(self.product_displays): if (counter < self.product_displays.top_index): # Hide all the products above the list product top product.set_visible(False) elif visible_count < self.limits.screen_products: # Show screen products based on their quantity product.visible = True visible_count += 1 else: # Hide products below list bottom product.set_visible(False) def _draw_products(self, window): """ Draw all visible product objects on the window """ # Iterate over all products in list index = 0 for product in self.product_displays: if product.visible: product.draw(self.layout, index, self._remove_button_width(), window) index += 1 def _draw_static_objects(self, window): """ Draw all the static objects on the window """ self.update_total() ## Draw border for draw_object in self.border.get_border().values(): draw_object.draw(window) # Draw the fixed objects static_objs = [ self.objects[self.ids.TOPBAR], self.objects[self.ids.PAY], self.objects[self.ids.CANCEL], self.objects[self.ids.DONE], self.objects[self.ids.AMOUNT], self.objects[self.ids.UP], self.objects[self.ids.DOWN] ] # Decide which objects should be shown if self.owner.user is not None: self.objects[self.ids.PAY].visible = self.owner.user.credit_allowed() self.objects[self.ids.DONE].visible = self.owner.user.has_added_credit() or (len(self.product_displays) > 0) self.objects[self.ids.UP].visible = self._test_display_up_button() self.objects[self.ids.DOWN].visible = self._test_display_down_button() for static_obj in static_objs: static_obj.draw(window) if self.banner is not None: self.banner.draw(window) def active(self): """ Abstraction for the active state of the screen """ return self.owner.active
class IntroScreenGUI(ScreenGUI): """ Describes the graphical elements of the intro screen and provides methods for setting introduction text """ def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) ## ## Fixed position objects ## self.path = os.path.dirname( os.path.abspath(inspect.getfile( inspect.currentframe()))) # script directory self.objects = { 'titleimage': LCARSImage(pygame.Rect(width / 2, height * 3 / 5, 0, 0), self.path + LOGO_PATH, True), } ## ## Import standard objects self.objects.update(self.border.get_border()) ## ## Position-dependant objects ## self.set_intro_text("Searching for remote database...", Colours.FG) self.set_intro_text_2("Don't have a card? Seeing error messages?", Colours.FG) self.set_intro_text_3("Pop money in the pot instead!", Colours.FG) def set_intro_text(self, text, color): """ The intro text is positioned centrally between the sweep and image """ text_y_position = (self.border.inner_y() + self.objects['titleimage'].t()) / 2 self.objects['introtext'] = LCARSText( (self.width / 2, text_y_position), text, 36, TextAlign.XALIGN_CENTRE, color, Colours.BG, True) def set_intro_text_2(self, text, color): """ The intro text is positioned between the image and the base """ text_y_position = (self.objects['titleimage'].b() + self.border.bottom()) / 2 text_y_position = text_y_position - 30 self.objects['introtext2'] = LCARSText( (self.width / 2, text_y_position), text, 36, TextAlign.XALIGN_CENTRE, color, Colours.BG, True) def set_intro_text_3(self, text, color): """ The intro text is positioned between the image and the base """ text_y_position = self.objects['introtext2'].t() + 80 self.objects['introtext3'] = LCARSText( (self.width / 2, text_y_position), text, 36, TextAlign.XALIGN_CENTRE, color, Colours.BG, True) def draw(self, window): """ Draw the screen objects on the supplied window """ window.fill(Colours.BG) for draw_obj in self.objects.values(): draw_obj.draw(window) #Ensure text is drawn on top self.objects['introtext'].draw(window) self.objects['introtext2'].draw(window) self.objects['introtext3'].draw(window) if self.banner is not None: self.banner.draw(window) pygame.display.flip()
def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) # Object constant definitions # Reverse draw order - 0 drawn last self.ids = Enum("DONE", "CANCEL", "PAY", "TOPBAR", "AMOUNT", "UP", "DOWN", "PRODUCT", "REMOVE") self.limits = Const() self.limits.screen_products = 5 self.limits.objects_per_product_row = 3 self.logger = logging.getLogger("MainScreen.GUI") self.product_displays = ProductDisplayCollection( self.limits.screen_products) # # # # Fixed position objects # # self.layout = MainScreenLayout(width, height, self.border) self.objects = { self.ids.DONE: LCARSCappedBar(self.layout.get_done_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, False), self.ids.PAY: LCARSCappedBar(self.layout.get_pay_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Pay debt", Colours.FG, Colours.BG, False), self.ids.CANCEL: LCARSCappedBar(self.layout.get_cancel_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), self.ids.TOPBAR: LCARSCappedBar(self.layout.get_top_bar_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "User: <No user scanned>", Colours.FG, Colours.BG, True), self.ids.UP: LCARSCappedBar(self.layout.get_up_scroll_rect(), CapLocation.CAP_TOP, "UP", Colours.FG, Colours.BG, False), self.ids.DOWN: LCARSCappedBar(self.layout.get_down_scroll_rect(), CapLocation.CAP_BOTTOM, "DN", Colours.FG, Colours.BG, False), self.ids.AMOUNT: LCARSCappedBar(self.layout.get_amount_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Total Spend: \xA30.00", Colours.FG, Colours.BG, True) } # # # # Import standard objects # # self.objects.update(self.border.get_border())
class MainScreenGUI(ScreenGUI): """ Describes the graphical elements of the main screen and provides methods for adding and remove products """ def __init__(self, width, height, owner): ScreenGUI.__init__(self, width, height, owner) self.border = Border(width, height) # Object constant definitions # Reverse draw order - 0 drawn last self.ids = Enum("DONE", "CANCEL", "PAY", "TOPBAR", "AMOUNT", "UP", "DOWN", "PRODUCT", "REMOVE") self.limits = Const() self.limits.screen_products = 5 self.limits.objects_per_product_row = 3 self.logger = logging.getLogger("MainScreen.GUI") self.product_displays = ProductDisplayCollection( self.limits.screen_products) # # # # Fixed position objects # # self.layout = MainScreenLayout(width, height, self.border) self.objects = { self.ids.DONE: LCARSCappedBar(self.layout.get_done_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Done", Colours.FG, Colours.BG, False), self.ids.PAY: LCARSCappedBar(self.layout.get_pay_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Pay debt", Colours.FG, Colours.BG, False), self.ids.CANCEL: LCARSCappedBar(self.layout.get_cancel_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Cancel", Colours.FG, Colours.BG, True), self.ids.TOPBAR: LCARSCappedBar(self.layout.get_top_bar_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "User: <No user scanned>", Colours.FG, Colours.BG, True), self.ids.UP: LCARSCappedBar(self.layout.get_up_scroll_rect(), CapLocation.CAP_TOP, "UP", Colours.FG, Colours.BG, False), self.ids.DOWN: LCARSCappedBar(self.layout.get_down_scroll_rect(), CapLocation.CAP_BOTTOM, "DN", Colours.FG, Colours.BG, False), self.ids.AMOUNT: LCARSCappedBar(self.layout.get_amount_rect(), CapLocation.CAP_LEFT + CapLocation.CAP_RIGHT, "Total Spend: \xA30.00", Colours.FG, Colours.BG, True) } # # # # Import standard objects # # self.objects.update(self.border.get_border()) def add_to_product_display(self, product): """ Add a new product to the list """ self.product_displays.add(product) def update_total(self): """ Update the total spend value """ self.objects[self.ids.AMOUNT].setText("Total Spend: \xA3%.2f" % (self.owner.total_price() / 100)) def _remove_button_width(self): """ The width of the remove button depends on whether the up/dn buttons are displayed """ removew = self.width - self.layout.product_entries.remove_x - Widths.BORDER if self._test_display_down_button() or self._test_display_up_button(): removew -= (self.layout.scroll.width + Widths.BORDER) return removew def get_object_id(self, pos): """ Returns the ID of the object at the given position """ object_id = ScreenGUI.get_object_id(self, pos) if object_id == -1: # Try searching remove buttons if self.product_displays.collide_on_remove(pos) is not None: object_id = self.ids.REMOVE return object_id def set_unknown_user(self): """ Indicate that an unknown card was scanned """ self.objects[self.ids.TOPBAR].setText("User: <Unknown card>") def set_user(self, name, balance, credit): """ Set the current username """ if balance >= 0: text = u"%s (Balance: \xA3%.2f" % (name, balance / 100) else: text = u"%s (Balance: -\xA3%.2f" % (name, -balance / 100) if credit > 0: text += u", Pending Credit: \xA3%.2f" % (credit / 100) text += ")" self.objects[self.ids.TOPBAR].setText(text) def _test_display_up_button(self): """ Returns TRUE if the up button should be displayed """ return (self.product_displays.top_index > 0) def _test_display_down_button(self): """ Returns TRUE if the down button should be displayed """ return (self.product_displays.top_index + self.limits.screen_products) < len(self.product_displays) def clear_products(self): """ Reset the products list to nothing """ self.product_displays.clear() def draw(self, window): """ Redraw the main screen """ window.fill(Colours.BG) self._set_show_hide_products() self._draw_products(window) self._draw_static_objects(window) pygame.display.flip() def _set_show_hide_products(self): """ Scan down the product list and set the visible state of the product objects """ visible_count = 0 for (counter, product) in enumerate(self.product_displays): if (counter < self.product_displays.top_index): # Hide all the products above the list product top product.set_visible(False) elif visible_count < self.limits.screen_products: # Show screen products based on their quantity product.visible = True visible_count += 1 else: # Hide products below list bottom product.set_visible(False) def _draw_products(self, window): """ Draw all visible product objects on the window """ # Iterate over all products in list index = 0 for product in self.product_displays: if product.visible: product.draw(self.layout, index, self._remove_button_width(), window) index += 1 def _draw_static_objects(self, window): """ Draw all the static objects on the window """ self.update_total() ## Draw border for draw_object in self.border.get_border().values(): draw_object.draw(window) # Draw the fixed objects static_objs = [ self.objects[self.ids.TOPBAR], self.objects[self.ids.PAY], self.objects[self.ids.CANCEL], self.objects[self.ids.DONE], self.objects[self.ids.AMOUNT], self.objects[self.ids.UP], self.objects[self.ids.DOWN] ] # Decide which objects should be shown if self.owner.user is not None: self.objects[ self.ids.PAY].visible = self.owner.user.credit_allowed() self.objects[ self.ids.DONE].visible = self.owner.user.has_added_credit( ) or (len(self.product_displays) > 0) self.objects[self.ids.UP].visible = self._test_display_up_button() self.objects[self.ids.DOWN].visible = self._test_display_down_button() for static_obj in static_objs: static_obj.draw(window) if self.banner is not None: self.banner.draw(window) def active(self): """ Abstraction for the active state of the screen """ return self.owner.active