init python: # CONST PARAMS GALLERY_COLS = 3 PREFERRED_WIDTH = 432 #px (1920 * 0.225) PREFERRED_HEIGHT = 243 #px (1080 * 0.225) PREFERRED_ASPECT_RATIO = 16.0/9.0 # 1.7777.. DEFAULT_WIDTH_SCALE_RATIO = round(float(PREFERRED_WIDTH) / float(1920), 4) DEFAULT_HEIGHT_SCALE_RATIO = round(float(PREFERRED_HEIGHT) / float(1080), 4) NOT_UNLOCKED_COVER = im.FactorScale("gui/gallery/unlocked_cg_button_cover.png", DEFAULT_WIDTH_SCALE_RATIO, DEFAULT_HEIGHT_SCALE_RATIO) ACCEPTED_EXTENSIONS = ["jpg", "png"] CG_PATHS = "images/cgs/" # GALLERY ITEMS # Data structure that holds the data for each cg and button # item is the key in the Gallery # ext is the file extension # { item: string; cg: Displayable; ext: string }[] galleryItems = [] # Make a scaled cg button # (cg: string; ext: string; w: float; h: float def cg(fname, ext, w, h): wh = {'x': w, 'y': h} scale = box_ratio(wh) return im.FactorScale(fname, scale, scale, False) # Reads /images/cgs dir for all image files # Populates galleryItems # () -> None def loadGallery(): list_img = renpy.list_images() # Add each image to the gallery for str in list_img: _str = CG_PATHS+str+"."+ACCEPTED_EXTENSIONS[0] if renpy.loadable(_str): #brute force image = renpy.image_size(Image(_str)) #addGalleryItem(str, ACCEPTED_EXTENSIONS[0], image[0], image[1]) # Create an object in g:Gallery, add to galleryItems # (imageName: string; ext: string; w: float; h: float) -> None galleryItems.append({ "item": str, "fn": _str, "cg": cg(_str, ACCEPTED_EXTENSIONS[0], image[0], image[1]), "ext": ACCEPTED_EXTENSIONS[0] }) return # (xy) -> { x: float; y: float } # Biggest value gets % diff to preferred_ variable def box_ratio(xy): cent = 0 if xy['x'] > xy['y']: cent = PREFERRED_WIDTH * 100.0 / float(xy['x']) else: cent = PREFERRED_HEIGHT * 100.0 / float(xy['y']) cent /= 100.0 return cent # Call to loading the gallery loadGallery() """ CG Gallery screen - A screen that shows the image gallery Basically Gallery Object has terrible defaults, so I just wrote my own stuff """ screen cg_gallery(__yoffset = 0): style_prefix "game_menu" if main_menu: key "game_menu" action ShowMenu("main_menu") add gui.main_menu_background add gui.game_menu_background python: items = len(galleryItems) galleryRows = (items / GALLERY_COLS) + 1 extraSpaces = GALLERY_COLS - (items % GALLERY_COLS) item_counter = 0 tag menu frame: style "game_menu_outer_frame" viewport: yinitial __yoffset scrollbars "vertical" mousewheel True draggable True pagekeys True xpos 440 grid GALLERY_COLS galleryRows: for item in galleryItems: python: item_counter += 1 yoffset = item_counter / 3 * PREFERRED_HEIGHT * 1.15 yoffset = int( yoffset + (PREFERRED_HEIGHT * 1.15)) # should properly fix with actual margin difference but good enough or the actual position use flag_button(item, yoffset) for i in range(0, extraSpaces): null height 20 vbox: style_prefix "navigation" xpos gui.notMM_navigation_xpos yalign 0.5 spacing gui.navigation_spacing textbutton _("CG") textbutton _("NotForKids!") textbutton _("Animations") textbutton _("Return") action Return() if _in_replay: textbutton _("End Replay") action EndReplay(confirm=True) elif not main_menu: textbutton _("Main Menu") action MainMenu() label "Gallery" """ if/else flow control & extra parameters for Buttons """ screen flag_button(item, yoffset): python: flag = renpy.seen_image(item['item']) if flag: button: action ShowMenu('view_image', item['fn'], ShowMenu('cg_gallery', yoffset)) xcenter 0.5 ycenter 0.5 vbox: text item["item"] xalign 0.5 add item["cg"] fit 'contain' xcenter 0.5 ycenter 0.5 size (PREFERRED_WIDTH, PREFERRED_HEIGHT) else: vbox: ymaximum PREFERRED_HEIGHT xcenter 0.5 ycenter 0.5 text "? ? ?" xalign 0.5 add NOT_UNLOCKED_COVER """ view_image, Loads the image in fullscreen with viewport control. """ screen view_image(fn, origin): tag menu key "game_menu" action origin viewport: #Ren'Py is isn't smart enough to not edgescroll while pressed, so we'll have to disable this for mobile edgescroll (300, 800) draggable True arrowkeys True pagekeys True #edgescroll 1.0 add fn