And of course I end up doing something new tonight AFTER I upload the above image!
Good news! I got the stock settings page items working.
They’re the ones featured in this promotional material on the top right two panels. (I have no idea where that Loading screen comes from - I’ve never seen it!)
Here are the details.
I was right, regarding referenced fonts not lining up.
Initially, what I tried was substituting the referenced font names with the stock font names of 0.5. The DEOT OS uses the Eurostile font a lot, whereas stock 0.5 doesn’t.
Needless to say, the launcher wouldn’t progress if any changes were made.
I didn’t want to touch the /home/cpi/launcher/sys.py/UI/skin_manager.py, since being within the launcher directory, it would get overwritten with the stock version upon updating, which would cause problems re: the launcher not loading.
But realistically, if the skin_manager.py was going to get updated/replaced with stock, chances are the /home/cpi/launcher/Menu/GameShell/10_Settings/ would also get completely overwritten, preventing the launcher freeze happening.
That and the fact that we haven’t seen a launcher update for a while. So I went ahead and modified the skin_manager.py file like this:
# -*- coding: utf-8 -*-
import pygame
import config
import ConfigParser
from util_funcs import FileExists
class CaseConfigParser(ConfigParser.SafeConfigParser):
def optionxform(self, optionstr):
return optionstr
class SkinManager(object):
"""
_HighColor = pygame.Color(51,166,255) # #33a6ff
_TextColor = pygame.Color(83,83,83) # #535353
_FrontColor = pygame.Color(131,199,219) ## light blue,#83c7db
_URLColor = pygame.Color(51,166,255) ## blue more #33a6ff
_LineColor = pygame.Color(169,169,169) # #a9a9a9
_TitleBgColor = pygame.Color(228,228,228) # #e4e4e4
_ActiveColor = pygame.Color(175,90,0) ## light brown #af5a00
"""
_Colors = {}
_Config = None
_Fonts = {}
DefaultSkin = "../skin/default"
def __init__(self):
self.Init()
def ConvertToRGB(self,hexstr):
h = hexstr.lstrip('#')
return tuple(int(h[i:i+2], 16) for i in (0, 2 ,4))
def Init(self):
if not SkinManager._Colors:
self.SetColors()
if not SkinManager._Fonts:
self.SetFonts()
def SetFonts(self):
if not pygame.font.get_init():
pygame.font.init()
skinpath = config.SKIN+"/truetype"
fonts_path = {}
fonts_path["varela"] = "%s/VarelaRound-Regular.ttf" % skinpath
print(fonts_path["varela"])
fonts_path["veramono"] = "%s/VeraMono.ttf" % skinpath
fonts_path["noto"] = "%s/NotoSansMono-Regular.ttf" % skinpath
fonts_path["notocjk"] = "%s/NotoSansCJK-Regular.ttf" % skinpath
fonts_path["Eurostile"] = "%s/EurostileMN-Medium.pfb.ttf" %skinpath
fonts_path["EurostileBold"] = "%s/EurostileMN-ExtendedBold.pfb.ttf" % skinpath
self._Fonts["EurostileBold13"] = pygame.font.Font(fonts_path["EurostileBold"],13)
self._Fonts["EurostileBold30"] = pygame.font.Font(fonts_path["EurostileBold"],30)
for i in range(10,29):
self._Fonts["varela%d"%i] = pygame.font.Font(fonts_path["Eurostile"],i)
self._Fonts["Eurostile34"] = pygame.font.Font(fonts_path["Eurostile"],34)
self._Fonts["Eurostile40"] = pygame.font.Font(fonts_path["Eurostile"],40)
self._Fonts["Eurostile120"] = pygame.font.Font(fonts_path["Eurostile"],120)
for i in range(10,29):
self._Fonts["varela%d"%i] = pygame.font.Font(fonts_path["varela"],i)
self._Fonts["varela34"] = pygame.font.Font(fonts_path["varela"],34)
self._Fonts["varela40"] = pygame.font.Font(fonts_path["varela"],40)
self._Fonts["varela120"] = pygame.font.Font(fonts_path["varela"],120)
for i in range(10,26):
self._Fonts["veramono%d"%i] = pygame.font.Font(fonts_path["veramono"],i)
for i in range(10,28):
self._Fonts["notosansmono%d"%i] = pygame.font.Font(fonts_path["noto"],i)
for i in range(10,28):
self._Fonts["notosanscjk%d"%i] = pygame.font.Font(fonts_path["notocjk"],i)
self._Fonts["arial"] = pygame.font.SysFont("arial",16)
def SetColors(self):
Colors = {}
Colors["High"] = pygame.Color(51, 166, 255)
Colors["Text"] = pygame.Color(83, 83, 83)
Colors["ReadOnlyText"] = pygame.Color(130,130,130)
Colors["Front"] = pygame.Color(131, 199, 219)
Colors["URL"] = pygame.Color(51, 166, 255)
Colors["Line"] = pygame.Color(169, 169, 169)
Colors["TitleBg"] = pygame.Color(228, 228, 228)
Colors["Active"] = pygame.Color(175, 90, 0)
Colors["Disabled"] = pygame.Color(204, 204, 204)
Colors["White"] = pygame.Color(255, 255, 255)
Colors["Black"] = pygame.Color(0, 0, 0)
SkinManager._Colors = Colors
self._Config = CaseConfigParser()
fname = config.SKIN+"/config.ini"
try:
self._Config.read(fname)
except Exception, e:
print("read skin config.cfg error %s" % str(e))
return
else:
if "Colors" in self._Config.sections():
colour_opts = self._Config.options("Colors")
# print(colour_opts)
for i in SkinManager._Colors:
if i in colour_opts:
try:
SkinManager._Colors[i] = self.ConvertToRGB(
self._Config.get("Colors", i))
except Exception, e:
print("error in ConvertToRGB %s" % str(e))
continue
def GiveFont(self,name):
return SkinManager._Fonts[name]
def GiveColor(self,name):
if name in SkinManager._Colors:
return SkinManager._Colors[name]
else:
return pygame.Color(255,0,0)
def GiveIcon(self,orig_file_or_dir): ## return is string,not Surface
#doing a wrapper for items under /home/cpi/apps/Menu/*, to be like Menu/GameShell/*
if orig_file_or_dir.startswith("/home/cpi/apps/Menu"):
orig_file_or_dir = orig_file_or_dir.replace("/home/cpi/apps/Menu/","../Menu/GameShell/")
if orig_file_or_dir.startswith(".."):
ret = orig_file_or_dir.replace("..",config.SKIN)
if FileExists(ret) == False:
ret = orig_file_or_dir.replace("..",self.DefaultSkin)
else:
ret = config.SKIN+"/sys.py/"+orig_file_or_dir
if FileExists(ret) == False:
ret = self.DefaultSkin+"/sys.py/"+orig_file_or_dir
if FileExists( ret ):
return ret
else: ## if not existed both in default or custom skin ,return where it is
return orig_file_or_dir
def GiveWallpaper(self,png_name):
#first SKIN/wallpapers/xxxx.png
#second ../skin/default/wallpapers/xxxx.png
#finnal gameshell/wallpaper/xxxx.png
#loading.png,seeyou.png,updating.png,gameover.png,desktopbg.png
wlp = "/wallpaper/"
if FileExists(config.SKIN+wlp+png_name):
return config.SKIN+wlp+png_name
elif FileExists(self.DefaultSkin+wlp+png_name):
return self.DefaultSkin+wlp+png_name
else:
return "gameshell/wallpaper/"+png_name
##global MySkinManager Handler
MySkinManager = None
def InitMySkinManager():
global MySkinManager
if MySkinManager == None:
MySkinManager = SkinManager()
InitMySkinManager()
I simply added more font choices, and reference names to the list, without removing anything.
This allows us to now use these customised settings menu items.
- Airplane
- Brightness
- Sound
- Storage
While I was at it, I removed LauncherGo entirely.
I removed the directory /home/cpi/launcher/Menu/GameShell/10_Settings/LauncherGo/ , and went ahead and removed /home/cpi/launchergo/
And then I commented out the entry within the settings menu like so:
# -*- coding: utf-8 -*-
import pygame
import sys
from libs.roundrects import aa_round_rect
## local UI import
from UI.constants import Width,Height
from UI.page import Page,PageSelector
from UI.label import Label
from UI.util_funcs import midRect,FileExists
from UI.keys_def import CurKeys, IsKeyStartOrA, IsKeyMenuOrB
from UI.scroller import ListScroller
from UI.skin_manager import MySkinManager
from UI.lang_manager import MyLangManager
from UI.info_page_selector import InfoPageSelector
from list_item import ListItem
import myvars
class ListPage(Page):
_Icons = {}
_Selector=None
_FootMsg = ["Nav","","","Back","Enter"]
_MyList = []
_ListFontObj = MyLangManager.TrFont("varela15")
_Scroller = None
def __init__(self):
Page.__init__(self)
self._Icons = {}
self._CanvasHWND = None
self._MyList = []
def Init(self):
self._PosX = self._Index * self._Screen._Width
self._Width = self._Screen._Width
self._Height = self._Screen._Height
self._CanvasHWND = self._Screen._CanvasHWND
ps = InfoPageSelector()
ps._Parent = self
ps._PosX = 2
self._Ps = ps
self._PsIndex = 0
# "" pkgname, label
alist = [["","Airplane","Airplane Mode"],
["","PowerOptions","Power Options"],
["","Wifi","Wi-Fi"],
["","Bluetooth","Bluetooth"],
["","Sound","Sound Volume"],
["","Brightness","BackLight Brightness"],
["","Storage",""],
["","Time","Timezone"],
["","Languages","Languages"],
["","Notification","Notification"],
["","Update", ""],
["","Cores", "Retroarch cores manager"],
["","About", "About"],
["","PowerOFF","Power OFF"],
["","ButtonsLayout","Buttons Layout"],
#["","LauncherGo","Switch to LauncherGo"],
["","Lima","GPU Driver Switch"],
["","GateWay","Network Gateway Switch"]]
start_x = 0
start_y = 0
sys.path.append(myvars.basepath)# add self as import path
for i,v in enumerate(alist):
li = ListItem()
li._Parent = self
li._PosX = start_x
li._PosY = start_y + i*ListItem._Height
li._Width = Width
li._Fonts["normal"] = self._ListFontObj
if v[2] != "":
li.Init(v[2])
else:
li.Init(v[1])
#if v[1] == "Wifi" or v[1] == "Sound" or v[1] == "Brightness" or v[1] == "Storage" or v[1] == "Update" or v[1] == "About" or v[1] == "PowerOFF" or v[1] == "HelloWorld":
if FileExists(myvars.basepath+"/"+ v[1]):
li._LinkObj = __import__(v[1])
init_cb = getattr(li._LinkObj,"Init",None)
if init_cb != None:
if callable(init_cb):
li._LinkObj.Init(self._Screen)
self._MyList.append(li)
self._Scroller = ListScroller()
self._Scroller._Parent = self
self._Scroller._PosX = self._Width - 10
self._Scroller._PosY = 2
self._Scroller.Init()
def Click(self):
cur_li = self._MyList[self._PsIndex]
if cur_li._LinkObj != None:
api_cb = getattr(cur_li._LinkObj,"API",None)
if api_cb != None:
if callable(api_cb):
cur_li._LinkObj.API(self._Screen)
def KeyDown(self,event):
if IsKeyMenuOrB(event.key):
self.ReturnToUpLevelPage()
self._Screen.Draw()
self._Screen.SwapAndShow()
if event.key == CurKeys["Up"]:
self.ScrollUp()
self._Screen.Draw()
self._Screen.SwapAndShow()
if event.key == CurKeys["Down"]:
self.ScrollDown()
self._Screen.Draw()
self._Screen.SwapAndShow()
if IsKeyStartOrA(event.key):
self.Click()
def Draw(self):
self.ClearCanvas()
if len(self._MyList) * ListItem._Height > self._Height:
self._Ps._Width = self._Width - 11
self._Ps.Draw()
for i in self._MyList:
i.Draw()
self._Scroller.UpdateSize( len(self._MyList)*ListItem._Height, self._PsIndex*ListItem._Height)
self._Scroller.Draw()
else:
self._Ps._Width = self._Width
self._Ps.Draw()
for i in self._MyList:
i.Draw()
We’re getting much closer to the DEOT settings! ALMOST. The settings pages for Airplane and Storage still causes the system to freeze. The Sound and Brightness pages however work beautifully!
Other things that were bugging me were the shapes of certain objects, such as the scroll bar, text highlighter and OSD of the volume bars. These are basically all contained in /home/cpi/launcher/sys.py.UI/ . For the most part, I just substituted the files from the DEOT stock image.
The scroller is controlled by scroller.py
I couldn’t work out the text highlighter. I tried slider.py, to no avail.
The OSD of the volume bars is controller by above_all_patch.py, however substituting it in prevents the launcher from progressing.
Anyway, that’s where I’m at. This could prove to be useful information for someone else wanting to modify the interface. I can possibly provide a script to allow people to try installing this. But really, this is just an aesthetic thing that serves no purpose, and something that could later on down the track break detrimentally. I’m going to test it A LOT!
Here’s a link to the files I replaced, along with backups of the original ones in case you want to try things out for yourself. The files with the asterisk next to them are the problematic items.
https://drive.google.com/open?id=1gf97OddpWn9JjSfM7A3UhxtN0tvYnWvQ