2021-06-12 19:50:48 +00:00
|
|
|
init python:
|
2021-06-16 19:54:10 +00:00
|
|
|
# CONST PARAMS
|
|
|
|
GALLERY_COLS = 3
|
2021-07-03 10:42:12 +00:00
|
|
|
PREFERRED_WIDTH = 432 #px (1920 * 0.225)
|
|
|
|
PREFERRED_HEIGHT = 243 #px (1080 * 0.225)
|
2021-07-17 02:46:42 +00:00
|
|
|
PREFERRED_ASPECT_RATIO = 16.0/9.0 # 1.7777..
|
2021-07-03 11:40:34 +00:00
|
|
|
DEFAULT_WIDTH_SCALE_RATIO = round(float(PREFERRED_WIDTH) / float(1920), 4)
|
|
|
|
DEFAULT_HEIGHT_SCALE_RATIO = round(float(PREFERRED_HEIGHT) / float(1080), 4)
|
2021-07-03 10:42:12 +00:00
|
|
|
NOT_UNLOCKED_COVER = im.FactorScale("gui/gallery/unlocked_cg_button_cover.png", DEFAULT_WIDTH_SCALE_RATIO, DEFAULT_HEIGHT_SCALE_RATIO)
|
2021-07-18 03:16:11 +00:00
|
|
|
ACCEPTED_EXTENSIONS = ["jpg", "webm"]
|
2021-07-17 05:53:20 +00:00
|
|
|
CG_PATHS = [
|
2021-07-17 21:55:49 +00:00
|
|
|
#CG doesn't really make sense
|
|
|
|
{ 'path': "images/cgs/", 'name': "CG", 'eval': None },
|
2021-07-18 03:16:11 +00:00
|
|
|
{ 'path': "images/animations/", 'name': "Animations", 'eval': None },
|
2021-07-17 05:53:20 +00:00
|
|
|
{ 'path': "images/NotForKids!/", 'name': "Lewd",
|
2021-07-18 02:10:58 +00:00
|
|
|
'eval': 'persistent.lewd == True'
|
2021-07-17 05:53:20 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
#path: folder, name: shows up in gallery, eval: runs eval() on string
|
|
|
|
|
|
|
|
"""
|
|
|
|
Data structure that holds the data for each cg and button
|
|
|
|
item is name, fn is fullpath
|
|
|
|
ext is the file extension
|
|
|
|
{ item: string; fn: string, cg: Displayable; ext: string }[]
|
2021-07-17 21:55:49 +00:00
|
|
|
(reference in this init python, actually used in screens)
|
2021-07-17 05:53:20 +00:00
|
|
|
"""
|
2021-07-17 21:55:49 +00:00
|
|
|
gallery_items = []
|
2021-06-12 19:50:48 +00:00
|
|
|
|
2021-07-17 05:53:20 +00:00
|
|
|
# key dict pair, cg <-> cgs' galleryitems []
|
|
|
|
gallery_dic = {} #
|
|
|
|
for cp in CG_PATHS:
|
|
|
|
gallery_dic[cp['name']] = [] #
|
|
|
|
|
2021-06-16 19:54:10 +00:00
|
|
|
# Make a scaled cg button
|
2021-07-17 02:46:42 +00:00
|
|
|
# (cg: string; ext: string; w: float; h: float
|
2021-07-11 05:10:52 +00:00
|
|
|
def cg(fname, ext, w, h):
|
2021-07-17 02:46:42 +00:00
|
|
|
wh = {'x': w, 'y': h}
|
2021-07-17 03:32:30 +00:00
|
|
|
scale = box_ratio(wh)
|
|
|
|
return im.FactorScale(fname, scale, scale, False)
|
2021-07-11 03:02:41 +00:00
|
|
|
|
2021-07-03 11:40:34 +00:00
|
|
|
# Reads /images/cgs dir for all image files
|
2021-07-17 04:43:15 +00:00
|
|
|
# Populates galleryItems
|
2021-07-03 12:33:50 +00:00
|
|
|
# () -> None
|
2021-06-16 19:54:10 +00:00
|
|
|
def loadGallery():
|
2021-06-12 19:50:48 +00:00
|
|
|
|
2021-07-11 00:37:33 +00:00
|
|
|
list_img = renpy.list_images()
|
|
|
|
|
2021-07-03 11:40:34 +00:00
|
|
|
# Add each image to the gallery
|
2021-07-11 00:37:33 +00:00
|
|
|
for str in list_img:
|
2021-07-17 05:53:20 +00:00
|
|
|
for cp in CG_PATHS:
|
2021-07-18 03:16:11 +00:00
|
|
|
for ext in ACCEPTED_EXTENSIONS:
|
|
|
|
path = cp['path']
|
|
|
|
_str = path+str+"."+ext
|
|
|
|
if renpy.loadable(_str): #brute force
|
|
|
|
image = renpy.image_size(Image(_str))
|
2021-07-17 05:53:20 +00:00
|
|
|
|
2021-07-18 03:16:11 +00:00
|
|
|
# Create an object in g:Gallery, add to galleryItems
|
|
|
|
# (imageName: string; ext: string; w: float; h: float) -> None
|
|
|
|
gallery_dic[cp['name']] += [{
|
|
|
|
"item": str,
|
|
|
|
"fn": _str,
|
|
|
|
"cg": cg(_str, ext, image[0], image[1]),
|
|
|
|
"ext": ext
|
|
|
|
}]
|
2021-07-11 03:02:41 +00:00
|
|
|
return
|
2021-06-14 19:27:30 +00:00
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
# (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'])
|
2021-07-11 03:02:41 +00:00
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
cent /= 100.0
|
2021-07-17 03:32:30 +00:00
|
|
|
return cent
|
2021-07-03 10:42:12 +00:00
|
|
|
|
2021-06-16 19:54:10 +00:00
|
|
|
# Call to loading the gallery
|
|
|
|
loadGallery()
|
2021-06-14 19:27:30 +00:00
|
|
|
|
2021-07-18 02:10:58 +00:00
|
|
|
#for zooming in and out
|
|
|
|
zoom_arr = []
|
|
|
|
for x in range(1,5):
|
|
|
|
_zoom = 1.0
|
|
|
|
_zoom *= 1+(x*0.25)
|
|
|
|
zoom_arr.append(_zoom)
|
|
|
|
|
|
|
|
for y in range(9,1,-1):
|
|
|
|
_zoom = 1.0
|
|
|
|
_zoom *= (y*0.125)
|
|
|
|
zoom_arr.append(_zoom)
|
|
|
|
|
|
|
|
zoom_arr.sort()
|
2021-07-17 21:55:49 +00:00
|
|
|
"""
|
|
|
|
'Recursive' / Loopable / Roundtrip Screens
|
|
|
|
_0 <-> _1
|
|
|
|
"""
|
2021-07-18 02:10:58 +00:00
|
|
|
#There is renpy.restart_interaction but since I wrote all this, it's too late
|
|
|
|
#screen cg_gallery(flag, __yoffset = 0, origin = 'CG'):
|
2021-07-17 21:55:49 +00:00
|
|
|
screen cg_gallery_0(__yoffset = 0, origin = 'CG'):
|
|
|
|
tag menu
|
|
|
|
use cg_gallery('1', __yoffset, origin)
|
|
|
|
screen cg_gallery_1( __yoffset = 0, origin = 'CG'):
|
|
|
|
tag menu
|
|
|
|
use cg_gallery('0', __yoffset, origin)
|
|
|
|
|
2021-07-18 02:10:58 +00:00
|
|
|
#screen view_image(fn, _origin, zoom=1):
|
|
|
|
screen view_image_a(fn, _origin, zoom):
|
|
|
|
tag menu
|
|
|
|
use view_image(fn, _origin, zoom, 'b')
|
|
|
|
screen view_image_b(fn, _origin, zoom):
|
|
|
|
tag menu
|
|
|
|
use view_image(fn, _origin, zoom, 'a')
|
2021-07-18 03:33:08 +00:00
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
"""
|
|
|
|
CG Gallery screen - A screen that shows the image gallery
|
|
|
|
Basically Gallery Object has terrible defaults, so I just wrote my own stuff
|
|
|
|
"""
|
2021-07-17 21:55:49 +00:00
|
|
|
screen cg_gallery(flag, __yoffset = 0, origin = 'CG'):
|
2021-07-17 04:21:24 +00:00
|
|
|
|
|
|
|
style_prefix "game_menu"
|
|
|
|
if main_menu:
|
2021-07-17 04:43:15 +00:00
|
|
|
key "game_menu" action ShowMenu("main_menu")
|
|
|
|
|
|
|
|
add gui.main_menu_background
|
|
|
|
add gui.game_menu_background
|
2021-07-17 04:21:24 +00:00
|
|
|
|
2021-07-17 21:55:49 +00:00
|
|
|
tag menu
|
|
|
|
|
2021-07-11 03:02:41 +00:00
|
|
|
python:
|
2021-07-17 21:55:49 +00:00
|
|
|
empty_spaces = gallery_rows = item_counter = 0
|
|
|
|
|
|
|
|
gallery_items = gallery_dic[origin]
|
|
|
|
items = len(gallery_items)
|
|
|
|
gallery_rows = (items / GALLERY_COLS) + 1
|
|
|
|
empty_spaces = GALLERY_COLS - (items % GALLERY_COLS)
|
2021-07-17 04:21:24 +00:00
|
|
|
|
|
|
|
frame:
|
2021-07-17 04:43:15 +00:00
|
|
|
|
2021-07-17 21:55:49 +00:00
|
|
|
style "game_menu_outer_frame"
|
2021-07-17 04:21:24 +00:00
|
|
|
viewport:
|
|
|
|
yinitial __yoffset
|
|
|
|
scrollbars "vertical"
|
|
|
|
mousewheel True
|
|
|
|
draggable True
|
|
|
|
pagekeys True
|
2021-07-18 03:33:08 +00:00
|
|
|
if renpy.variant("small"): #TODO: slightly overspills
|
|
|
|
xpos 490
|
|
|
|
else:
|
|
|
|
xpos 440
|
2021-07-17 04:21:24 +00:00
|
|
|
|
2021-07-17 21:55:49 +00:00
|
|
|
grid GALLERY_COLS gallery_rows:
|
|
|
|
for item in gallery_items:
|
2021-07-17 05:53:20 +00:00
|
|
|
# Should properly fix with actual margin difference but good
|
|
|
|
# enough or the actual position
|
2021-07-17 04:43:15 +00:00
|
|
|
python:
|
|
|
|
item_counter += 1
|
|
|
|
yoffset = item_counter / 3 * PREFERRED_HEIGHT * 1.15
|
|
|
|
yoffset = int( yoffset + (PREFERRED_HEIGHT * 1.15))
|
2021-07-17 04:21:24 +00:00
|
|
|
|
2021-07-17 21:55:49 +00:00
|
|
|
use flag_button(item, yoffset, origin)
|
2021-07-17 04:21:24 +00:00
|
|
|
|
2021-07-17 21:55:49 +00:00
|
|
|
for i in range(0, empty_spaces):
|
2021-07-17 04:21:24 +00:00
|
|
|
null height 20
|
|
|
|
|
2021-07-17 04:43:15 +00:00
|
|
|
vbox:
|
|
|
|
style_prefix "navigation"
|
|
|
|
xpos gui.notMM_navigation_xpos
|
|
|
|
yalign 0.5
|
|
|
|
|
|
|
|
spacing gui.navigation_spacing
|
|
|
|
|
2021-07-17 21:55:49 +00:00
|
|
|
for cp in CG_PATHS:
|
2021-07-18 02:10:58 +00:00
|
|
|
if cp['name'] == origin:
|
|
|
|
textbutton _(cp['name']) text_color gui.selected_color
|
2021-07-17 21:55:49 +00:00
|
|
|
else:
|
2021-07-18 02:10:58 +00:00
|
|
|
if cp['eval'] is None:
|
|
|
|
textbutton _(cp['name']) action ShowMenu('cg_gallery_'+flag, 0, cp['name'])
|
|
|
|
elif eval(cp['eval']):
|
|
|
|
textbutton _(cp['name']) action ShowMenu('cg_gallery_'+flag, 0, cp['name'])
|
|
|
|
else:
|
|
|
|
textbutton _(cp['name'])
|
2021-07-17 21:55:49 +00:00
|
|
|
textbutton _("Return") action ShowMenu('main_menu')
|
2021-07-17 04:43:15 +00:00
|
|
|
|
|
|
|
if _in_replay:
|
|
|
|
textbutton _("End Replay") action EndReplay(confirm=True)
|
|
|
|
elif not main_menu:
|
|
|
|
textbutton _("Main Menu") action MainMenu()
|
|
|
|
|
2021-07-17 04:21:24 +00:00
|
|
|
label "Gallery"
|
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
"""
|
2021-07-17 04:43:15 +00:00
|
|
|
if/else flow control & extra parameters for Buttons
|
2021-07-17 02:46:42 +00:00
|
|
|
"""
|
2021-07-17 21:55:49 +00:00
|
|
|
screen flag_button(item, yoffset, origin):
|
2021-07-17 02:46:42 +00:00
|
|
|
python:
|
|
|
|
flag = renpy.seen_image(item['item'])
|
2021-07-18 02:10:58 +00:00
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
if flag:
|
|
|
|
button:
|
2021-07-18 02:10:58 +00:00
|
|
|
action ShowMenu('view_image_a', item['fn'], ShowMenu('cg_gallery_0', yoffset, origin), 0.0)
|
2021-07-17 02:46:42 +00:00
|
|
|
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:
|
2021-07-17 04:21:24 +00:00
|
|
|
ymaximum PREFERRED_HEIGHT
|
2021-07-17 02:46:42 +00:00
|
|
|
xcenter 0.5 ycenter 0.5
|
|
|
|
text "? ? ?" xalign 0.5
|
|
|
|
add NOT_UNLOCKED_COVER
|
|
|
|
|
2021-07-18 03:33:08 +00:00
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
"""
|
2021-07-17 04:43:15 +00:00
|
|
|
view_image, Loads the image in fullscreen with viewport control.
|
2021-07-17 02:46:42 +00:00
|
|
|
"""
|
2021-07-18 02:10:58 +00:00
|
|
|
screen view_image(fn, _origin, zoom=0.0, flag='a'):
|
|
|
|
python:
|
|
|
|
if zoom == 0.0:
|
|
|
|
zoom = zoom_arr.index(1.0)
|
|
|
|
zoom_a = zoom+1
|
|
|
|
zoom_a_f = ShowMenu('view_image_'+flag, fn, _origin, zoom_a)
|
|
|
|
zoom_b = zoom-1
|
|
|
|
zoom_b_f = ShowMenu('view_image_'+flag, fn, _origin, zoom_b)
|
|
|
|
|
2021-07-17 02:46:42 +00:00
|
|
|
tag menu
|
2021-07-17 21:55:49 +00:00
|
|
|
key "game_menu" action _origin
|
2021-07-18 02:10:58 +00:00
|
|
|
|
|
|
|
# mousewheel & insert+delete
|
|
|
|
if zoom_a < len(zoom_arr):
|
|
|
|
key 'mousedown_4' action zoom_a_f
|
|
|
|
key 'K_INSERT' action zoom_a_f
|
|
|
|
if zoom_b > 0:
|
|
|
|
key 'mousedown_5' action zoom_b_f
|
|
|
|
key 'K_DELETE' action zoom_b_f
|
|
|
|
|
|
|
|
viewport id "vie":
|
2021-07-18 03:33:08 +00:00
|
|
|
#Ren'Py isn't smart enough to not edgescroll while pressed,
|
|
|
|
#so we'll have to disable this for mobile
|
|
|
|
if renpy.variant("pc"):
|
|
|
|
edgescroll (300, 1800)
|
2021-07-17 02:46:42 +00:00
|
|
|
draggable True
|
|
|
|
arrowkeys True
|
|
|
|
pagekeys True
|
2021-07-18 02:10:58 +00:00
|
|
|
add fn zoom zoom_arr[zoom] anchor (0.5, 0.5)
|
2021-07-18 03:33:08 +00:00
|
|
|
|
|
|
|
#Reuse quick buttons, Ren'Py handles touch input lazy, it doesn't have
|
|
|
|
#double finger pinch zoom, it translates taps as mouse events - have to use
|
|
|
|
#buttons
|
|
|
|
if renpy.variant("small"):
|
|
|
|
hbox:
|
|
|
|
style_prefix "quick"
|
|
|
|
xalign 0.5
|
|
|
|
yalign 0.975
|
|
|
|
use quick_buttons("gui/button/uioptionbuttons/template_idle.png", \
|
|
|
|
[
|
|
|
|
[ "+", zoom_a_f ],
|
|
|
|
[ "-", zoom_b_f ]
|
|
|
|
] )
|