bombsquad-plugin-manager/plugins/utilities/fileman.py
2025-08-10 16:01:28 +03:00

1771 lines
64 KiB
Python
Executable file

# Copyright 2025 - Solely by BrotherBoard
# Intended for personal use only
# Bug? Feedback? Telegram >> @BroBordd
"""
FileMan v1.0 - Advanced file manager
Adds a button to settings menu.
Experimental. Read code to know more.
"""
from babase import (
PluginSubsystem as SUB,
Plugin,
env
)
from bauiv1 import (
get_virtual_screen_size as res,
clipboard_set_text as COPY,
get_string_height as strh,
get_string_width as strw,
get_special_widget as zw,
get_replays_dir as rdir,
containerwidget as cw,
hscrollwidget as hsw,
screenmessage as SM,
buttonwidget as obw,
scrollwidget as sw,
SpecialChar as sc,
imagewidget as iw,
textwidget as tw,
gettexture as gt,
apptimer as teck,
AppTimer as tuck,
getsound as gs,
charstr as cs,
MainWindow,
open_url,
Call,
app
)
from os.path import (
basename,
getmtime,
splitext,
dirname,
getsize,
exists,
isfile,
isdir,
join,
sep
)
from os import (
listdir as ls,
getcwd,
rename,
remove,
access,
mkdir,
X_OK,
R_OK
)
from shutil import (
copytree,
rmtree,
copy,
move
)
from bascenev1 import new_replay_session as REP
from http.client import HTTPSConnection as GO
from datetime import datetime as DT
from mimetypes import guess_type
from random import uniform as UF
from threading import Thread
from pathlib import Path
class FileMan(MainWindow):
VER = '1.0'
INS = []
@classmethod
def resize(c):
c.clean()
[_.on_resize() for _ in c.INS]
@classmethod
def clean(c):
c.INS = [_ for _ in c.INS if not _.gn and _.p.exists()]
@classmethod
def loadc(c):
[setattr(c,f'COL{i}',_) for i,_ in enumerate(var('col'))]
def __del__(s):
s.__class__.clean()
def on_resize(s):
[_.delete() for _ in s.killme]
s.killme.clear()
c = s.uploadc
s.spyt = s.sharel = s.buf = s.uploadc = None
if c: c.close()
s.fresh()
def __init__(s,src):
s.__class__.clean()
s.__class__.INS.append(s)
s.wop()
s.url = s.urlo = var('cwd')
s.urlbln = s.dro = s.gn = s.rlyd = s.flon = False
s.amoled = sum(s.COL5)==0
s.pusho = s.sorti = 0
s.pushi = -0.1
s.sl = (None,None)
[setattr(s,_,None) for _ in ['pushe','eno','leno','clp','gab','clpm','rlydt','buf','uploadc','cursnd','rfl','rflo']]
[setattr(s,_,[]) for _ in ['trash','btns','secs','docs','drkids','drol','okes','fkids','ftrash','statkids','fcons','flkids','killme']]
s.pushq = ''
# root
s.p = cw(
background=False,
toolbar_visibility='menu_minimal'
)
s.rect = iw(
texture=gt('softRect'),
opacity=[0.3,0.85][s.amoled],
color=s.COL5,
parent=s.p
)
super().__init__(
root_widget=s.p,
transition='in_scale',
origin_widget=src
)
s.bg = iw(
texture=gt('white'),
parent=s.p,
position=(-2,0),
color=s.COL5
)
s.bg2 = bw(
bg='empty',
parent=s.p,
oac=s.bga
)
# dock
s.docs = [iw(
color=s.COL1,
parent=s.p,
texture=gt('white'),
opacity=0.5
) for _ in range(3)]
# sections
s.secs = [tw(
parent=s.p,
text=_,
h_align='center',
color=s.COL4,
scale=0.7
) for _ in ['Action','Extra','New']]
# actions
s.gab = bw(
parent=s.p,
oac=s.cancel,
size=(0,0),
selectable=False
)
r = []
for _ in range(6):
l = ['Copy','Move','Delete','Share','Rename','Open'][_]
r.append(bw(
parent=s.p,
label=l,
oac=Call(s.act,0,_)
))
s.btns.append(r)
# extra
r = []
for _ in range(4):
l = ['Star','Sort','Filter','Theme'][_]
r.append(bw(
parent=s.p,
label=l,
oac=Call(s.act,1,_)
))
s.btns.append(r)
s.fltxt = tw(
editable=True,
parent=s.p,
v_align='center',
glow_type='uniform',
allow_clear_button=False
)
s.flh = tw(
parent=s.p,
v_align='center',
color=s.COL0
)
s.gab2 = bw(
parent=s.p,
oac=s.unfl,
size=(0,0),
selectable=False
)
# new
r = []
for _ in range(2):
l = ['File','Folder'][_]
r.append(bw(
parent=s.p,
label=l,
oac=Call(s.act,2,_)
))
s.btns.append(r)
# back
s.bb = bw(
parent=s.p,
label=' '+cs(sc.BACK),
oac=s.bye
)
cw(s.p,cancel_button=s.bb)
# up
s.ub = bw(
parent=s.p,
label=cs(sc.SHIFT),
oac=s.up
)
# url
s.urlbg = bw(
parent=s.p,
oac=s.urled
)
s.urlt = tw(
color=s.COL2,
text=s.url,
v_align='center',
parent=s.p
)
s.urla = tw(
editable=True,
size=(0,0),
parent=s.p,
text=s.url
)
s.trash.append(tuck(0.01,s.urlspy,repeat=True))
s.trash.append(tuck(0.1,s.urlbl,repeat=True))
# rf
s.rfb = bw(
parent=s.p,
label=cs(sc.PLAY_BUTTON),
oac=s.rf
)
# pre
s.preb = bw(
parent=s.p,
label=cs(sc.LOGO_FLAT),
oac=s.pre
)
# yes
s.yesbg = iw(
parent=s.p,
texture=gt('white'),
color=s.COL1,
opacity=0.5,
position=(20,20)
)
s.yesbg2 = iw(
parent=s.p,
texture=gt('white'),
color=s.COL5,
opacity=0.3,
)
s.yesp1 = sw(
parent=s.p,
border_opacity=0,
position=(17,20)
)
s.yesp2 = cw(
parent=s.yesp1,
background=False
)
s.lmao = tw(
parent=s.yesp2,
text=''
)
# oke
s.okes = [tw(
parent=s.p,
text=_,
h_align='left',
color=s.COL4,
scale=0.7
) for _ in SRT()]
# drop
s.drbg = iw(
texture=gt('white'),
parent=s.p,
opacity=0.7,
color=s.COL5
)
s.drp1 = sw(
border_opacity=0,
parent=s.p
)
s.drp2 = cw(
background=False,
parent=s.drp1
)
# push
s.pushbg2 = iw(
color=s.COL5,
parent=s.p,
opacity=0,
texture=gt('softRect')
)
s.pushbg = iw(
color=s.COL1,
parent=s.p,
opacity=0,
texture=gt('white')
)
s.pusht = tw(
color=s.COL2,
parent=s.p,
h_align='center',
v_align='center'
)
s.trash.append(tuck(0.01,s.fpush,repeat=True))
# finally
s.fresh()
teck(0.5,lambda:s.push(f'FileMan v{s.VER} Ready!',du=1.5) if s.eno is None else 0)
def meh(s):
if s.sl[0] is None:
s.btw('Select something!')
return 1
if s.sl[1] == '..':
s.btw('What are you doing blud')
return 1
def btw(s,t,du=3):
s.snd('block')
s.push(t,color=s.COL3,du=du)
def act(s,i,j,gay=False):
if s.gn: return
w = s.btns[i][j]
match i:
case 0:
match j:
case 0:
if s.clp:
if s.clpm != j:
s.btw("You're already doing something else!")
return
c = var('cwd')
chk = join(c,basename(s.clp))
st1,st2 = splitext(chk)
nn = st1+'_copy'+st2 if exists(chk) else chk
if exists(nn):
s.btw('A copy of this '+['file','folder'][isdir(chk)]+' already exists!')
return
try: [copy,copytree][isdir(s.clp)](s.clp,nn)
except Exception as e:
s.btw(str(e))
return
else:
GUN()
s.push('Pasted!')
s.clp = None
s.fresh()
else:
if s.meh(): return
s.clp = s.sl[1]
s.clpm = j
s.push(f'Copied! Now go to destination.')
GUN()
s.fresh(skip=True)
case 1:
if s.clp:
if s.clpm != j:
s.btw("You are already doing something else!")
return
c = var('cwd')
chk = join(c,basename(s.clp))
if exists(chk):
s.btw('There is a '+['file','folder'][isdir(chk)]+' with the same name here.')
return
try: move(s.clp,c)
except Exception as e:
s.btw(str(e))
return
else:
GUN()
s.push('Pasted!')
s.clp = None
s.fresh()
else:
if s.meh(): return
s.clp = s.sl[1]
s.clpm = j
s.push(f'Now go to destination and paste.')
GUN()
s.fresh(skip=True)
case 2:
if s.clpm:
s.btw("Finish what you're doing first!")
return
if s.meh(): return
h = s.sl[1]
bn = basename(h)
if not s.rlyd:
s.beep(1,0)
s.push(f"Really delete "+["the file '"+bn+"'","the whole '"+bn+"' folder"][isdir(h)]+" forever? Press again to confirm.",du=3,color=s.COL3)
s.rlydt = tuck(2.9,Call(setattr,s,'rlyd',False))
s.rlyd = True
return
s.rlyd = False
s.rlydt = None
f = [remove,rmtree][isdir(h)]
try: f(h)
except Exception as e:
s.btw(str(e))
return
else:
GUN()
s.push('Deleted!')
s.sl = (None,None)
s.fresh()
case 3:
if s.meh(): return
f = s.sl[1]
if isdir(f):
s.btw("You can't share a folder!")
return
s.wop()
o = w.get_screen_space_center()
xs,ys = 400,170
p = s.uploadp = cw(
parent=zw('overlay_stack'),
scale_origin_stack_offset=o,
stack_offset=o,
size=(xs,ys),
background=False,
transition='in_scale'
)
s.killme.append(p)
iw(
parent=p,
size=(xs*1.2,ys*1.2),
texture=gt('softRect'),
opacity=[0.2,0.55][s.amoled],
position=(-xs*0.1,-ys*0.1),
color=s.COL5
)
iw(
parent=p,
texture=gt('white'),
color=s.COL1,
opacity=0.7,
size=(xs,ys)
)
bw(
parent=p,
label='Back',
oac=s.cupload,
position=(30,15),
size=(xs-60,30)
)
s.cpsharelb = bw(
parent=p,
label='...',
oac=s.cpsharel,
position=(30,50),
size=(xs-60,30)
)
s.opsharelb = bw(
parent=p,
label='...',
oac=s.opsharel,
position=(30,85),
size=(xs-60,30)
)
bw(
parent=p,
label='Upload to bashupload.com',
oac=s.upload,
position=(30,120),
size=(xs-60,30)
)
case 4:
if s.meh(): return
t = s.fkids[s.sl[0]]
fp = s.sl[1]
if s.clp == j:
q = tw(query=t)
try:
if sep in q: raise ValueError("You can't use directory separator in filename!")
Path(q)
except Exception as e:
s.btw(str(e) or 'Invalid filename!')
return
else:
if (basename(fp) == q) and not gay:
s.btw("Write a new name blud")
return
chk = join(var('cwd'),q)
if exists(chk):
s.btw(f"There is a {['file','folder'][isdir(chk)]} with this name already!")
return
else:
nfp = join(dirname(fp),q)
try:
rename(fp,nfp)
except PermissionError:
if exists(nfp): pass
else:
s.push('Permission denied!')
return
except Exception as e:
s.btw(str(e))
return
else:
s.push('Renamed!')
s.clp = None
GUN()
s.fresh(sl=nfp)
else:
if s.clpm:
s.btw("You didn't paste yet blud")
return
tw(t,editable=True,color=s.COL7)
cw(s.yesp2,visible_child=t)
s.clpm = s.clp = j
s.push('Now edit the filename, then press Done.')
if s.flon and s.rfl:
[_.delete() for _ in s.flkids[s.sl[0]]]
GUN()
s.fresh(skip=True)
case 5:
if s.meh(): return
if s.clpm:
s.btw("Press again when you're free!")
return
h = s.sl[1]
bn = basename(h)
if isdir(h):
s.cd(h)
s.snd('deek')
return
s.stat = 1000
s.wop()
k = s.fkids[s.sl[0]] if gay else w
gcen = lambda: ((o:=k.get_screen_space_center()),(o[0]-s.size[0]/5,o[1]) if gay else o)[1]
o = gcen()
xs,ys = [_*0.6 for _ in s.size]
p = cw(
parent=zw('overlay_stack'),
scale_origin_stack_offset=o,
size=(xs,ys),
background=False,
transition='in_scale'
)
s.killme.append(p)
iw(
parent=p,
size=(xs*1.2,ys*1.2),
texture=gt('softRect'),
opacity=[0.3,0.7][s.amoled],
position=(-xs*0.1,-ys*0.1),
color=s.COL5
)
iw(
parent=p,
texture=gt('white'),
color=s.COL5,
opacity=0.7,
size=(xs,ys)
)
b = bw(
parent=p,
position=(20,ys-70),
label=' '+cs(sc.BACK),
size=(50,50),
oac=Call(s.statbye,p,gcen)
)
cw(p,cancel_button=b)
ix = xs-250
iw(
parent=p,
texture=gt('white'),
color=s.COL1,
position=(90,ys-72),
size=(ix,54),
opacity=0.5
)
tw(
parent=p,
h_align='center',
v_align='center',
position=(xs/2-60,ys-60),
text=basename(h),
maxwidth=ix-100
)
iw(
parent=p,
texture=gt('white'),
color=s.COL1,
opacity=0.5,
position=(20,20),
size=(xs-40,ys-110)
)
bw(
parent=p,
label=cs(sc.REWIND_BUTTON),
position=(xs-141,ys-70),
size=(50,50),
oac=Call(s.stata,-1),
repeat=True
)
bw(
parent=p,
label=cs(sc.FAST_FORWARD_BUTTON),
position=(xs-71,ys-70),
size=(50,50),
oac=Call(s.stata,1),
repeat=True
)
s.oops = 0
try:
with open(h,'r') as f:
da = f.read()
except Exception as ex:
da = ''
s.oops = 1
if isinstance(ex,PermissionError): kek = 'Permission denied!'
elif isinstance(ex,UnicodeDecodeError): kek = 'No preview avaiable'
else: kek = str(ex)
else:
if not da:
s.oops = 1
kek = 'No data'
if not s.oops:
fxs = xs-40
fys = ys-110
s.statsz = (fxs,fys)
p0 = s.statp0 = sw(
parent=p,
position=(20,20),
size=(fxs,fys),
border_opacity=0,
capture_arrows=True
)
s.statda = da
s.statp = 0
s.statl = []
s.itw()
else:
ty = s.gtype(h)
if ty == 'Replay':
tw(
parent=p,
position=(xs/2-20,ys-150),
text='Press start to preview replay.\nKeep in mind that this will destroy the current FileMan session.',
h_align='center',
color=s.COL4,
maxwidth=xs-60
)
bw(
parent=p,
label='Start',
oac=lambda:(b.activate(),teck(0.1,s.bye),teck(0.3,Call(REP,h))),
position=(xs/2-75,ys/2-135),
size=(150,40)
)
elif ty == 'Texture' and bn in TEX():
wd = min(xs-80,ys-150)
tex = gt(splitext(bn)[0])
iw(
parent=p,
texture=tex,
size=(wd,wd),
position=(xs/2-wd/2,40)
)
elif ty == 'Audio' and bn in AUDIO():
tw(
parent=p,
position=(xs/2-20,ys-150),
text=f'Sound is recognized by filename, not data.\nPress the buttons below to play/pause',
h_align='center',
color=s.COL4,
maxwidth=xs-60
)
bw(
parent=p,
label=cs(sc.PLAY_BUTTON),
oac=lambda:(getattr(s.cursnd,'stop',lambda:0)(),setattr(s,'cursnd',gs(splitext(bn)[0])),s.cursnd.play()),
position=(xs/2-30,ys/2-135),
size=(40,40)
)
bw(
parent=p,
label=cs(sc.PAUSE_BUTTON),
oac=lambda:getattr(s.cursnd,'stop',lambda:0)(),
position=(xs/2+30,ys/2-135),
size=(40,40)
)
else:
tw(
parent=p,
text=kek,
position=(xs/2-25,ys/2-35),
h_align='center',
v_align='center',
maxwidth=xs-100
)
case 1:
match j:
case 0:
star = var('star')
c = var('cwd')
if c in star:
star.remove(c)
s.push('Unstarred!')
else:
star.append(c)
s.push('Starred! (bomb top right)')
var('star',star)
GUN()
s.fresh(skip=True)
case 1:
xs,ys = 200,230
s.wop()
gcen = lambda: ((o:=w.get_screen_space_center()),(o[0]-s.size[0]/5,o[1]) if gay else o)[1]
o = gcen()
p = cw(
parent=zw('overlay_stack'),
scale_origin_stack_offset=o,
size=(xs,ys),
background=False,
transition='in_scale',
stack_offset=(o[0],o[1]),
on_outside_click_call=lambda:(cw(p,transition='out_scale'),s.laz())
)
s.killme.append(p)
iw(
parent=p,
size=(xs*1.2,ys*1.2),
texture=gt('softRect'),
opacity=[0.3,0.7][s.amoled],
position=(-xs*0.1,-ys*0.1),
color=s.COL5
)
iw(
parent=p,
texture=gt('white'),
color=s.COL5,
opacity=0.7,
size=(xs,ys)
)
by = 40
srt = SRT()
for _ in range(4):
bw(
position=(20,ys-20-by-(by+10)*_),
size=(xs-40,by),
label=srt[_],
oac=Call(s.surt,_,p),
parent=p
)
case 2:
s.flon = True
s.snd('deek')
s.fresh(skip=True)
case 3:
ox, oy = s.size
xs = ys = min(ox / 2, oy / 2)
xs *= 1.3
s.wop()
s.push('FileMan uses 12 main colors. Tap on a color to edit it. Press outside to cancel.',du=6)
o = w.get_screen_space_center()
def nuke():
cw(p,transition='out_scale')
s.laz()
s.push('Cancelled! Nothing was saved')
p = cw(parent=zw('overlay_stack'), scale_origin_stack_offset=o, size=(xs, ys), stack_offset=(-100,0), background=False, transition='in_scale',on_outside_click_call=nuke)
bw(parent=p,size=(xs+200,ys),bg='empty')
s.killme.append(p)
iw(parent=p, size=(xs * 1.2, ys * 1.2), texture=gt('softRect'), opacity=[0.3,0.7][s.amoled], position=(-xs * 0.1, -ys * 0.1), color=s.COL5)
iw(parent=p, texture=gt('white'), color=s.COL5, opacity=0.7, size=(xs + 200, ys))
temp_colors, scl, sl = [getattr(s, f'COL{i}') for i in range(12)], [0, 0, 0, 0], 0
kids, nubs, grad = [], [], []
def save():
if var('col') == temp_colors:
s.btw('At least change a color blud')
return
var('col',temp_colors)
GUN()
cw(p,transition='out_scale')
s.__class__.loadc()
s.bye()
SM('Reopen FileMan to see changes!')
def update_previews():
f3()
f4()
c = temp_colors[sl]
obw(kids[sl], color=c, textcolor=INV(c))
def f3():
[iw(l, position=(xs + scl[k] * ps - 16, 39 + qs * 5 - (qs) * k)) for k, l in enumerate(nubs)]
def f4():
c = temp_colors[sl]
[obw(l, color=(c[0] * (k / 19), c[1] * (k / 19), c[2] * (k / 19))) for k, l in enumerate(grad)]
def f2(k, l):
nonlocal scl
scl[k] = l
val = l / 19.0
if k < 3:
c_list = list(temp_colors[sl])
c_list[k] = val
temp_colors[sl] = new_color = tuple(c_list)
scl[3] = int(max(new_color) * 19)
elif k == 3:
c = temp_colors[sl]
current_max = max(c)
if current_max > 0:
scale = val / current_max
temp_colors[sl] = new_color = (c[0] * scale, c[1] * scale, c[2] * scale)
scl[:3] = [int(x * 19) for x in new_color]
update_previews()
def f(z, sh=0):
nonlocal sl, scl
[obw(_, label='') for _ in kids]
obw(kids[z], label=cs(sc.DPAD_CENTER_BUTTON))
sl = z
if not sh: s.snd('deek')
c = temp_colors[sl]
scl[:3] = [int(x * 19) for x in c]
scl[3] = int(max(c) * 19) if any(c) else 0
update_previews()
bs, qs, ps = (ys - 60) / 3, (ys - 60) / 6, 9
for k in range(4):
for l in range(20):
ah = l / 19.0
b = obw(
parent=p, position=(xs + l * ps, 47 + qs * 5 - qs * k), size=(ps + 2, qs / 2), label='', texture=gt('white'), enable_sound=False, on_activate_call=Call(f2, k, l),
color=( (ah, 0, 0) if k < 1 else (0, ah, 0) if k < 2 else (0, 0, ah) if k < 3 else (ah, ah, ah) )
)
if k == 3: grad.append(b)
nubs = [iw(parent=p, size=(35, 35), texture=gt('nub'), color=(10, 10, 10), opacity=0.4) for _ in range(4)]
for x in range(4):
for y in range(3):
z = x * 3 + y
c = temp_colors[z]
kids.append(bw(parent=p, position=(20 + (bs + 10) * x, 20 + (bs + 10) * y), size=(bs, bs), color=c, textcolor=INV(c), oac=Call(f, z)))
bw(parent=p, position=(xs + 5, 24 + qs), size=(172, qs - 2), label='Save', oac=save)
def reset():
mem = COL()
if mem == temp_colors:
s.btw("Reset what? It's already at default")
return
for i,m in enumerate(mem):
temp_colors[i] = m
update_previews()
GUN()
s.push('Restored default colors! now press save')
bw(parent=p, position=(xs + 5, 18.5), size=(172, qs - 3), label='Reset', oac=reset)
f(0, sh=1)
case 2:
match j:
case 0:
if s.clpm:
s.btw("You're already in the middle of something")
return
c = var('cwd')
n = join(c,'new_file')
while exists(n): n+='_again'
try: Path(n).touch()
except PermissionError:
s.btw('Permission denied!')
return
except Exception as ex:
s.btw(str(ex))
return
s.fresh(sl=n)
# rename
s.act(0,4,gay=True)
case 1:
if s.clpm:
s.btw("You're already in the middle of something")
return
c = var('cwd')
n = join(c,'new_folder')
while exists(n): n+='_again'
try: mkdir(n)
except PermissionError:
s.btw('Permission denied!')
return
except Exception as ex:
s.btw(str(ex))
return
s.fresh(sl=n)
# rename
s.act(0,4)
def surt(s,_,p):
if _ == s.sorti:
s.btw('Already sorted by '+SRT()[_]+'!')
return
s.sorti = _
GUN()
cw(p,transition='out_scale')
s.fresh(sl=s.sl[1])
def statbye(s,p,gcen):
try: cen = gcen()
except: p.delete()
else: cw(p,transition='out_scale',scale_origin_stack_offset=cen)
s.laz()
s.statda = None
s.statl = []
s.statp = 0
def itw(s):
PYTHON_KEYWORDS = {
'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def',
'del', 'elif', 'else', 'except', 'False', 'finally', 'for', 'from',
'global', 'if', 'import', 'in', 'is', 'lambda', 'None', 'nonlocal',
'not', 'or', 'pass', 'raise', 'return', 'True', 'try', 'while', 'with', 'yield'
}
PYTHON_BUILTINS = {
'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
'chr', 'classmethod', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod',
'enumerate', 'eval', 'exec', 'filter', 'float', 'format', 'frozenset', 'getattr',
'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance',
'issubclass', 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview',
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted',
'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip'
}
OPERATORS = {'+', '-', '*', '/', '%', '=', '!', '<', '>', '&', '|', '^', '~'}
BRACKETS = {'(', ')', '{', '}', '[', ']', ':', ',', '.'}
s.COL_KEYWORD = getattr(s, 'COL_KEYWORD', (1.5, 0.9, 0.4))
s.COL_BUILTIN = getattr(s, 'COL_BUILTIN', (0.7, 1.2, 1.8))
s.COL_STRING = getattr(s, 'COL_STRING', (0.5, 1.5, 0.5))
s.COL_NUMBER = getattr(s, 'COL_NUMBER', (1.2, 1.2, 0.5))
s.COL_OPERATOR = getattr(s, 'COL_OPERATOR', (1.5, 1.5, 1.5))
s.COL_BRACKET = getattr(s, 'COL_BRACKET', (0.9, 0.9, 0.9))
s.COL_END_MARKER = getattr(s, 'COL_END_MARKER', (1.8, 0.6, 0.6)) # Neon Red for the marker
da = s.statda
end_marker = f'[End of chunk | Press {cs(sc.FAST_FORWARD_BUTTON)}]'
if len(da) > s.stat:
if len(da) > s.statp + int(s.stat / 2):
da = da[s.statp:s.stat + s.statp] + end_marker
else:
da = da[s.statp:s.stat + s.statp]
az = sum(s.statl)
lines = [_.replace('\\n','\\'+"~"+"n") for _ in da.splitlines()]
zc = len(str(az + len(lines)))
da = '\\n'.join([f"{str(i+1+az).zfill(zc)} | {_}" for i, _ in enumerate(lines)])
z = len(da)
p0 = s.statp0
fxs, fys = s.statsz
[_.delete() for _ in s.statkids]
s.statkids.clear()
hh = 35
m = max(da.replace('\\n', '') or ' ', key=GSW)
l = GSW(str(m)) / 1.5
l = max(15,l)
l = min(l,20)
das = da.split('\\n')
mm = len(max(das, key=len) or '')
ldas = len(das)
s.statl.append(ldas)
rxs = max(l * mm + 30, fxs)
rys = max(hh * ldas, fys - 15)
pos = (0, rys - 40)
po = list(pos)
q0 = cw(parent=p0, size=(fxs, rys), background=False)
p1 = hsw(parent=q0, size=(fxs, rys), border_opacity=0)
q1 = cw(parent=p1, background=False, size=(rxs, fys))
s.statkids += [q0, p1, q1]
# --- Main Rendering Loop ---
i = 0
nc = 0
in_triple_comment = False
triple_quote_char = None
is_first_char_offset_applied = False # Flag for the critical offset
off = zc + 3
try:
mud = int(da[off] == '#')
except IndexError:
mud = 0
while i < z:
# -- Priority 1: The End Marker --
if not in_triple_comment and not mud and da.startswith(end_marker, i):
if not is_first_char_offset_applied:
po[0] -= l * 1.5; is_first_char_offset_applied = True
for c in end_marker:
big = nc < zc
po[0] += l
s.statkids.append(tw(text=c, position=(po[0], po[1] - (3 if big else 0)), h_align='center', v_align='top', parent=q1, big=big, color=s.COL_END_MARKER))
nc += 1
i += len(end_marker)
continue
# -- Priority 2: Multi-line comment delimiters --
if i + 2 < z and da[i:i+3] in ('"'*3, "'"*3):
chunk = da[i:i+3]
if not in_triple_comment or chunk == triple_quote_char * 3:
if not is_first_char_offset_applied:
po[0] -= l * 1.5; is_first_char_offset_applied = True
if not in_triple_comment:
in_triple_comment = True; triple_quote_char = chunk[0]
else:
in_triple_comment = False; triple_quote_char = None
for _ in range(3):
big = nc < zc; po[0] += l
s.statkids.append(tw(text=da[i], position=(po[0], po[1] - (3 if big else 0)), h_align='center', v_align='top', parent=q1, big=big, color=s.COL3 if big else s.COL0))
nc += 1; i += 1
continue
# -- Priority 3: Newlines --
if i + 1 < z and da[i:i+2] == '\\n':
po[0] = pos[0]-l*1.5; po[1] -= hh; nc = 0
try:
mud = int(da[i + 2 + off] == '#' and not in_triple_comment)
except IndexError:
mud = 0
i += 2
continue
# -- Priority 4: Render based on state (comment or code) --
# Apply the critical offset before rendering the first character
if not is_first_char_offset_applied:
po[0] -= l * 1.5; is_first_char_offset_applied = True
if in_triple_comment or mud:
big = nc < zc
color = (s.COL0 if big else s.COL3) if in_triple_comment else (s.COL10 if big else s.COL11)
po[0] += l
s.statkids.append(tw(text=da[i], position=(po[0], po[1] - (3 if big else 0)), h_align='center', v_align='top', parent=q1, big=big, color=color))
nc += 1; i += 1
continue
# -- Priority 5: Python Syntax Highlighting --
char = da[i]; token = char; token_color = s.COL2
if char in ("'", '"'):
k = i + 1
while k < z and (da[k] != char or da[k-1] == '\\'): k += 1
token = da[i:k+1]; token_color = s.COL_STRING
elif char.isdigit() or (char == '.' and i + 1 < z and da[i+1].isdigit()):
k = i
while k < z and (da[k].isdigit() or da[k] == '.'): k += 1
token = da[i:k]; token_color = s.COL_NUMBER
elif char.isalpha() or char == '_':
k = i
while k < z and (da[k].isalnum() or da[k] == '_'): k += 1
token = da[i:k]
if token in PYTHON_KEYWORDS: token_color = s.COL_KEYWORD
elif token in PYTHON_BUILTINS: token_color = s.COL_BUILTIN
elif char in OPERATORS: token_color = s.COL_OPERATOR
elif char in BRACKETS: token_color = s.COL_BRACKET
for c in token:
big = nc < zc; po[0] += l
s.statkids.append(tw(text=c, position=(po[0], po[1] - (3 if big else 0)), h_align='center', v_align='top', parent=q1, big=big, color=token_color))
nc += 1
i += len(token)
cw(q0,visible_child=tw(parent=q0, text='', position=(0,rys)))
cw(q1,visible_child=tw(parent=q1, text='', position=(0,rys)))
def stata(s,i):
if not s.oops:
n = s.statp + s.stat*i
ok = len(s.statda)
if ok <= n:
s.btw('Reached EOF!',du=1)
return
if n < 0:
s.btw('Already at first chunk!',du=1)
return
s.snd('deek')
s.statp = n
if i<0: [s.statl.pop(-1) for _ in [0,0]]
s.itw()
else:
s.btw('No more open file buffers!')
def cpsharel(s):
l = s.vsharel()
if not l: return
COPY(str(l))
s.ding(1,1)
s.push(f"Copied '{l}' to clipboard!")
def opsharel(s):
l = s.vsharel()
if not l: return
s.snd('deek')
open_url(l)
def vsharel(s):
l = getattr(s,'sharel',0)
if not l:
s.btw("Upload first!")
return
return l
def cupload(s):
c = s.uploadc
s.spyt = s.sharel = s.buf = s.uploadc = None
if c:
c.close()
s.ding(0,0)
s.push('Cancelled!')
else: s.laz()
cw(s.uploadp,transition='out_scale')
def upload(s):
f = s.sl[1]
s.ding(1,0)
s.push('Uploading...')
Thread(target=Call(s._upload,f)).start()
s.spyt = tuck(0.2,Call(s.spy,s.on_upload),repeat=True)
def _upload(s, l):
try:
c = s.uploadc = GO('bashupload.com')
filename = basename(l)
url_path = '/' + filename
with open(l, 'rb') as f: body = f.read()
headers = {'Content-Type': 'application/octet-stream'}
c.request('POST', url_path, body=body, headers=headers)
s.buf = c.getresponse().read().decode()
except Exception:
if s.uploadc: s.buf = ''
finally:
if s.uploadc:
s.uploadc.close()
s.uploadc = s.sharel = None
def on_upload(s,t):
if not t:
s.btw("Couldn't upload")
return
s.sharel = t.splitlines()[5][5:]+'?download=1'
s.ding(0,1)
s.push('Success!')
obw(s.cpsharelb,label='Copy Direct URL')
obw(s.opsharelb,label=s.sharel)
def ding(s,i,j):
a = ['Small','']
x,y = a[i],a[j]
s.snd('ding'+x)
teck(0.1,gs('ding'+y).play)
def beep(s,i,j):
s.snd(f'raceBeep{str(i+1)}')
teck(0.1,gs(f'raceBeep{str(j+1)}').play)
def spy(s,f):
if s.buf is None: return
b = s.buf
s.buf = None
f(b)
s.spyt = None
def cancel(s):
c = s.clp
s.clp = None
s.push('Cancelled!')
s.snd('deek')
s.fresh(skip=c!=4)
def fresh(s,skip=False,sl=None):
if s.gn: return
rx,ry = res()
z = s.size = (rx*0.8,ry*0.8)
x,y = z
# root
cw(s.p,size=z)
iw(s.bg,size=z)
obw(s.bg2,size=z)
iw(s.rect,size=(x*1.2,y*1.2),position=(-x*0.1,-y*0.1))
# docks, secs, btns
h = (x-80)
f = y-191
v = 18
for i in range(3):
e = h/[2,3,6][i]
iw(s.docs[i],size=(e,100),position=(v,f))
tw(s.secs[i],position=(v+e/2-23,f+1))
a = s.btns[i]; l = int(len(a)/2)
bh = (e-[6,5,4][i]*10-(l-1)*10)/l
for j in range(l):
for k in [0,l]:
zz = bh
of = 20
ga = (
(i == k == 0 and s.clpm == j)
or
(i == 0 and j == 1 and k == 3 and s.clpm == 4)
)
if ga and s.clp:
zz -= 40
of -= 2
po = v+of+(bh+20)*j,f+60-30*bool(k)
ww = a[j+k]
obw(ww,position=po,size=(zz,25))
if not ga:
if i == 1 and j == k == 0:
obw(ww,label=['Star','Unstar'][var('cwd') in var('star')])
elif i == 1 and j == 0 and k:
tw(s.fltxt,position=(po[0]-2,po[1]-2))
tw(s.flh,position=(po[0],po[1]-2),max_height=37,maxwidth=zz-42)
obw(s.gab2,position=(po[0]+zz-32,po[1]))
if s.flon:
obw(ww,size=(0,0),label='')
tw(s.fltxt,size=(zz-38,27))
tw(s.flh,text='' if s.rfl else 'Write something...')
obw(s.gab2,size=(bh-(zz-38),25),label='X')
if not s.fltk:
s.rflo = s.fltk = ''
s.fltk = tuck(0.1,s.onfl,repeat=True)
else:
obw(ww,size=(zz,25),label='Filter')
tw(s.fltxt,size=(0,0),text='')
tw(s.flh,text='')
obw(s.gab2,size=(0,0),label='')
s.rfl = s.rflo = s.fltk = None
continue
he = bool(s.clp)
obw(s.gab,position=(po[0]+zz+11,po[1]),size=(bh-3-zz,25),label=['','X'][he],selectable=he)
obw(ww,label=[['Copy','Move',0,0,'Rename'][s.clpm],['Paste','Done'][s.clpm==4]][he])
if not he: s.clpm = None
v += e+20
# back
f = y-70
obw(s.bb,position=(20,f),size=(50,50))
# up
obw(s.ub,position=(90,f),size=(50,50))
# url
e = x - 398
obw(s.urlbg,size=(e,50),position=(195,f))
tw(s.urlt,position=(180,y-60),maxwidth=x-370)
# rf
obw(s.rfb,position=(251+e,f),size=(50,50))
# pre
obw(s.preb,position=(323+e,f),size=(50,50))
# skip the rest
if skip: return
# drop
s.droc()
# oke
fly = 35
sx,sy = x-37,y-230
h = sx/6
v = 30
rat = [3,1,1,1]
for i,_ in enumerate(s.okes):
j = rat[i]
tw(_,position=(v+[30,0][i!=0],sy-15))
v += h*j
# push
s.rpush()
# files
p = s.yesp2
[_.delete() for _ in s.fkids]
s.fkids.clear()
[_.delete() for _ in s.ftrash]
s.ftrash.clear()
[_.delete() for _ in s.fcons]
s.fcons.clear()
[[i.delete() for i in j] for j in s.flkids]
s.flkids.clear()
fl = s.gfull()
u = s.rfl
if s.flon and s.rfl:
fl = [_ for _ in fl if (_ == '..') or (u in basename(_))]
cur = s.sl[1]
if cur:
if cur in fl: sl = cur
else: s.sl = (None,None)
# yes
rsy = len(fl)*fly
sw(s.yesp1,size=(sx,sy-40))
cw(s.yesp2,size=(sx,rsy))
tw(s.lmao,position=(0,rsy))
iw(s.yesbg,size=(sx,sy))
iw(s.yesbg2,size=(sx,40),position=(20,sy-20))
# files
for i,_ in enumerate(fl):
if _ == sl:
s.sl = (i,_)
v = 15
hm = s.gdata(_)
for k in range(4):
j = rat[k]
e = h*j
ee = [30,0][k!=0]
po = (v+ee,rsy-fly-fly*i)
t = tw(
parent=p,
size=(e-15-ee,fly),
position=po,
text=hm[k],
maxwidth=e-15-ee,
v_align='center',
selectable=True,
click_activate=True,
on_activate_call=Call(s._sl,i,_,fl),
glow_type='uniform',
allow_clear_button=False
)
if s.flon and u and not k:
ci = 0
bn = basename(_)
ret = []
while True:
nxt = bn.find(u,ci)
if nxt == -1: break
bf = bn[:nxt]
ret.append(tw(
parent=p,
text=u,
position=(po[0]+GSW(bf),po[1]+3),
v_align='center'
))
ci = nxt + len(u)
s.flkids.append(ret)
if ee:
s.fcons.append(iw(
position=(po[0]-ee-8,po[1]+1),
texture=s.gtex(_),
size=(ee+1,ee+1),
parent=p
))
v += e
if k: s.ftrash.append(t)
else: s.fkids.append(t)
if _ == sl:
cw(s.yesp2,visible_child=t)
s.slco(fl)
def onfl(s):
s.rfl = tw(query=s.fltxt)
if s.rfl != s.rflo:
s.rflo = s.rfl
s.fresh(sl=s.sl[1])
def unfl(s):
s.flon = False
s.snd('deek')
s.fresh(sl=s.sl[1])
def gtex(s,_):
ty = s.gtype(_)
t = (
'replayIcon' if _ == '..' else
'folder' if isdir(_) else
'tv' if ty == 'Replay' else
'audioIcon' if ty == 'Audio' else
'graphicsIcon' if ty == 'Texture' else
'star' if ty == 'Mesh' else
'achievementOutline' if ty == 'Font' else
'file'
)
return gt(t)
def slco(s,fl):
# cancel rename
if s.clp == 4: s.cancel()
sli = s.sl[0]
for i,g in enumerate(zip(fl,s.fkids,s.fcons)):
_,w,r = g
c = [(s.COL10,s.COL11),(s.COL8,s.COL9)][isdir(_)][sli == i]
tw(w,color=c,editable=False)
iw(r,color=c)
for i,z in enumerate(s.flkids):
for j in z:
tw(j,color=[s.COL0,s.COL3][sli==i])
def _sl(s,i,_,fl):
if s.sl[0] == i:
if isdir(_): s.cd(_)
else: s.act(0,5,gay=True)
return
s.sl = (i,_)
s.slco(fl)
def gdata(s,_):
b = isdir(_)
try: mt = DT.fromtimestamp(getmtime(_)).strftime('%m/%d/%Y %I:%M %p')
except: mt = '?'
try: sz = FMT(getsize(_))
except: sz = '?'
return (
basename(_),
s.gtype(_),
'' if b else mt,
'' if b else sz
)
def gtype(s,_):
if isdir(_): return ['Folder','Parent'][_=='..']
f = 'File'
h = guess_type(_)[0] or f
if not '.' in _: return h.title()
if h == f:
return {
'brp':'Replay',
'bob':'Mesh',
'cob':'Mesh',
'ogg':'Audio',
'ktx':'Texture',
'fdata':'Font'
}.get(_.split('.')[-1],f)
else: return h.title()
def gfull(s):
c = var('cwd')
h = []
if dirname(c) != c: h = ['..']
if not access(c, R_OK): return h
items = [join(c,_) for _ in ls(c)]
da = {}
for item in items:
name, item_type, date_modified_str, _ = s.gdata(item)
try:
date_sortable = DT.strptime(date_modified_str, '%m/%d/%Y %I:%M %p') if date_modified_str else DT.min
except: date_sortable = DT.min
try: mt = getmtime(item)
except: mt = 0
da[item] = (basename(item).lower(), item_type.lower(), date_sortable, mt, isdir(item))
return h + sorted(items, key=lambda i: (
not da[i][4],
da[i][0] if s.sorti == 0 else
da[i][1] if s.sorti == 1 else
da[i][2] if s.sorti == 2 else
da[i][3]
))
def pre(s):
s.wop()
r = s._pre()
xs = 200
ys = 160
pc = s.preb.get_screen_space_center()
p = s.prep = cw(
parent=zw('overlay_stack'),
background=False,
transition='in_scale',
scale_origin_stack_offset=pc,
on_outside_click_call=lambda:(cw(p,transition='out_scale'),s.laz()),
size=(xs,ys),
stack_offset=(pc[0]-xs/2+27,pc[1]-ys/2+27)
)
s.killme.append(p)
iw(
parent=p,
size=(xs*1.2,ys*1.2),
texture=gt('softRect'),
opacity=[0.2,0.55][s.amoled],
position=(-xs*0.1,-ys*0.1),
color=s.COL5
)
iw(
parent=p,
size=(xs,ys),
texture=gt('white'),
color=s.COL1,
opacity=0.7
)
p2 = sw(
parent=p,
size=(xs,ys)
)
rys = 30*len(r)
p3 = cw(
parent=p2,
size=(xs,max(ys,rys)),
background=False
)
for i,_ in enumerate(r):
j,k = _
tw(
parent=p3,
size=(xs,30),
position=(0,rys-30-30*i),
maxwidth=xs-20,
text=j,
click_activate=True,
selectable=True,
glow_type='uniform',
on_activate_call=Call(s.pres,k)
)
def pres(s,k):
GUN()
cw(s.prep,transition='out_scale')
s.cd(k)
def _pre(s):
e = app.env
c = e.cache_directory
d = dirname
f = join(d(c),'ballistica_files','ba_data')
g = cs(sc.LOGO_FLAT)+' '
return [
*[(cs(sc.DPAD_CENTER_BUTTON)+' '+(basename(_) or _),_) for _ in var('star')],
(g+'Mods',e.python_directory_user),
(g+'Replays',rdir()),
(g+'Config',e.config_directory),
(g+'Cache',c),
(g+'Files',f),
(g+'Python',join(f,'python')),
(g+'Meshes',join(f,'meshes')),
(g+'Audio',join(f,'audio')),
(g+'Textures',join(f,'textures'))
]
def rf(s):
s.snd('ding')
s.fresh()
c = var('cwd')
s.push('Refreshed '+(basename(c) or c))
def up(s):
o = var('cwd')
n = dirname(o)
if o == n:
s.eno = 2
s.nah()
s.snd('block')
return
s.cd(n)
s.snd('deek')
def glike(s):
c = var('cwd')
if not access(c,R_OK):
s.eno = not access(c,X_OK)
s.nah()
return []
a = ls(c)
f = []
for _ in a:
j = join(c,_)
if isdir(j): f.append(j)
r = [_ for _ in f if _.startswith(s.url)]
return r
def nah(s):
if s.eno == s.leno: return
s.leno = s.eno
s.push([
"I can't list files here! Write next folder name manually.",
"I can't even enter there! Select another folder.",
"Already reached root!"
][s.eno],color=s.enoc(),du=[3,3,2][s.eno])
def enoc(s):
return [
s.COL7,
s.COL4,
s.COL2
][s.eno]
def drop(s,i):
if s.gn: return
s.dro = i>0
s.droc()
def droc(s):
s.drol = s.glike()
s.rdrop()
def rdrop(s):
if s.gn: return
[_.delete() for _ in s.drkids]
s.drkids.clear()
l = len(s.drol)
if not s.dro or not s.drol or (l==1 and s.drol[0] == s.url):
iw(s.drbg,size=(0,0))
sw(s.drp1,size=(0,0))
return
x,y = s.size
of = 20
ys = 30*l+of
fys = min(300,ys)
yp = y-71-fys
xs = x-325
xp = 160
iw(s.drbg,size=(xs,fys),position=(xp,yp))
sw(s.drp1,size=(xs,fys),position=(xp,yp))
cw(s.drp2,size=(xs,ys-of))
for i,_ in enumerate(s.drol):
p = (0,ys-30-30*i-of)
s.drkids.append(tw(
parent=s.drp2,
position=p,
text=_,
color=s.COL9,
selectable=True,
click_activate=True,
glow_type='uniform',
on_activate_call=Call(s.cd,_),
size=(GSW(_),30)
))
s.drkids.append(tw(
parent=s.drp2,
position=p,
text=s.url,
color=s.COL4,
))
def push(s,t,color=None,du=2):
if s.gn: return
s.rly = False
s.rlydt = None
tw(s.pusht,color=color or s.COL2)
s.pushe = tuck(du,s.upush)
s.pushi = 0.05
s.pushq = t
s.rpush()
def upush(s):
if s.gn: return
s.pushi = -abs(s.pushi)
s.pushq = ''
s.rpush(1)
def rpush(s,mode=0):
if s.gn: return
if mode:
tw(s.pusht,text=s.pushq,color=s.COL2)
return
x = s.size[0]
t = s.pushq
w = GSW(t+' '*3)
iw(s.pushbg,size=(w,30),position=(x/2-w/2,40))
iw(s.pushbg2,size=(w*1.1,30*1.2),position=((x/2-w/2)-w*0.05,(40)-30*0.1))
tw(s.pusht,text=t,maxwidth=w*0.95,position=(x/2-25,40))
def fpush(s):
if s.gn: return
n = s.pusho + s.pushi
if not (1 >= n >= 0): return
s.pusho = n
iw(s.pushbg,opacity=n)
iw(s.pushbg2,opacity=[n*0.4,n][s.amoled])
def urlbl(s):
if s.gn: return
if s.p.get_selected_child() not in [s.ub,s.drp2,s.drp1,s.urlbg]+s.drkids:
s.urlbln = False
if s.dro: s.drop(-1)
return
s.urlbln = not s.urlbln
if not s.dro: s.drop(1)
def urlspy(s):
if s.gn: return
s.url = tw(query=s.urla)
b1 = exists(s.url)
b2 = isdir(s.url)
g1 = access(var('cwd'),R_OK)
g2 = access(s.url,X_OK)
b = b1 and b2 and g1 and g2
av = not b1 and g1 and not g2 and s.drol
if b or av: s.eno = None
q = s.url != s.urlo
if q: s.droc()
lurl = var('cwd')
can = b1 and b2 and s.url != lurl
if can: s.cd(s.url); lurl = s.url
co = (
s.COL2 if b else
s.COL3 if av else
s.COL6 if not b1 else
s.enoc()
)
tw(s.urlt,text=s.url+[' ','|'][s.urlbln or q],color=co)
s.urlo = s.url
if can or isdir(s.url): return
# complete
f = dirname(s.url)
if not exists(f): return
if f == lurl: return
s.cd(f,dry=True)
def cd(s,t,dry=False):
if t == '..': t = dirname(var('cwd'))
s.sl = (None,None)
if s.flon and s.rfl:
s.push("Filter is active! Press 'X' to cancel.",du=1.2,color=s.COL3)
var('cwd',t)
if s.eno != 1 and not access(t,X_OK):
s.eno = 1
s.nah()
0 if dry else tw(s.urla,text=t)
cw(s.yesp2,visible_child=s.lmao)
s.fresh()
def urled(s):
if s.gn: return
s.snd('deek')
s.urla.activate()
def wop(s):
s.snd('powerup01')
def laz(s):
s.snd('laser')
def bye(s):
s.gn = True
s.trash.clear()
s.laz()
s.main_window_back()
s.__class__.clean()
del s
def snd(s,t):
s.sn = gs(t)
s.sn.play()
teck(UF(0.13,0.15),s.sn.stop)
def bga(s):
s.urlbln = False
# Tools and Resources
# Lambda means it won't be stored in memory unless called
UI = lambda: app.ui_v1
SCL = lambda a,b,c=None: [a,b,c][UI().uiscale.value] or b
GSW = lambda t: strw(t,suppress_warning=True)
GSH = lambda t: strh(t,suppress_warning=True)
FMT = lambda size: (
f"{size / 1024**3:.1f} GB" if size >= 1024**3 else (
f"{size / 1024**2:.1f} MB" if size >= 1024**2 else (
f"{size / 1024:.1f} KB" if size >= 1024 else f"{size} B"))
)
GUN = lambda: gs('gunCocking').play()
BASE = lambda: join(dirname(app.env.cache_directory),'ballistica_files','ba_data')
AUDIO = lambda: ls(join(BASE(),'audio'))
TEX = lambda: ls(join(BASE(),'textures'))
SRT = lambda: ['Name','Type','Date Modifed','Size']
INV = lambda c: ((1-c[0])*2,(1-c[1])*2,(1-c[2])*2)
COL = lambda: [
(0.5,0.5,0),
(0.17,0.17,0.17),
(1,1,1),
(1,1,0),
(0.6,0.6,0.6),
(0,0,0),
(1,0,0),
(1,0,1),
(0.5,0.25,0),
(1,0.5,0),
(0,0.5,0.5),
(0,1,1)
]
# Config
def var(s,v=None):
cfg = app.config; s = 'fm_'+s
return cfg.get(s,v) if v is None else (cfg.__setitem__(s,v),cfg.commit())
def con(v,t):
if var(v) is None: var(v,t)
# Default
con('cwd',getcwd())
con('star',[])
con('col',COL())
# Patches
f = SUB.on_screen_size_change; SUB.on_screen_size_change = lambda *a,**k: (FileMan.resize(),f(*a,**k))
bw = lambda *a,color=None,textcolor=None,oac=None,bg='white',label='',**k: obw(
*a,
on_activate_call=oac,
texture=gt(bg),
label=label,
enable_sound=False,
color=color or FileMan.COL1,
textcolor=textcolor or FileMan.COL2,
**k
)
# brobord collide grass
# ba_meta require api 9
# ba_meta export babase.Plugin
class byBordd(Plugin):
def on_app_running(s):
FileMan.loadc()
teck(0.1,s.kang)
def kang(s):
from bauiv1lib.settings.allsettings import AllSettingsWindow as m
i = '__init__'
o = getattr(m,i)
setattr(m,i,lambda z,*a,**k:(o(z,*a,**k),s.mk(z))[0])
def fix(s,p):
m = __import__('logging')
i = 'exception'
o = getattr(m,i)
setattr(m,i,lambda *a,**k:0 if s.b == p.get_selected_child() else o(*a,**k))
def mk(s,z):
s.fix(z._root_widget)
x,y = SCL((1000,800),(900,450))
s.b = obw(
position=(x*0.7,y*SCL(0.5,0.9)),
parent=z._root_widget,
icon=gt('folder'),
size=(100,30),
button_type='square',
label='Man',
enable_sound=False,
color=FileMan.COL1,
textcolor=FileMan.COL2,
on_activate_call=lambda:s.run(z)
)
def run(s,z):
z.main_window_replace(new_window=FileMan(s.b))