"""Fullscreen page"""
# Author(s): Davide.De-Marchi@ec.europa.eu
# Copyright © European Union 2022-2023
#
# Licensed under the EUPL, Version 1.2 or as soon they will be approved by
# the European Commission subsequent versions of the EUPL (the "Licence");
#
# You may not use this work except in compliance with the Licence.
#
# You may obtain a copy of the Licence at:
# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
# Unless required by applicable law or agreed to in writing, software
# distributed under the Licence is distributed on an "AS IS"
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied.
#
# See the Licence for the specific language governing permissions and
# limitations under the Licence.
# Imports
import ipyvuetify as v
try:
from . import settings
from . import dialogGeneric
from . import tooltip
except:
import settings
import dialogGeneric
import tooltip
#####################################################################################################################################################
# Open a page in fullscreen mode
#####################################################################################################################################################
[docs]
class page():
"""
Fullsceen page with title and footer bar.
Parameters
----------
appname : str
Name of the application. It will be displayed on the left side of the title bar
title : str
Title of the page
output : instance of widgets.Output() class
Output widget to be used for the opening of the fullscreen dialog that implements the page
onclose : function, optional
Python function to call when the user closes the page. The function will receive no parameters (default is None)
titlecolor : str, optional
Color to use for the title bar background (default is settings.color_first)
titledark : bool, optional
If True the text on the title bar will be displayed in white, otherwise in black color (defaul is True)
titleheight : int, optional
Height of the title bar in pixels (default is 54)
titleimageurl : str, optional
String containing the url of the title bar backbround image (default is '')
footercolor : str, optional
Color to use fir the footer bar background (default is settings.color_second)
footerdark : bool, optional
If True the text on the footer bar will be displayed in white, otherwise in black color (defaul is False)
footerheight : int, optional
Height of the footer bar in pixels (default is 30)
logoappurl : str, optional
String containing the url of the application logo, to be displayed on the left side of the title bar (default is '')
logowidth : int, optional
Width in pixels of the application logo button (default is 40)
on_logoapp : function, optional
Python function to call when the user clicks on the pplication logo. The function will receive no parameters (default is None)
copyrighttext : str, optional
Text to display as copyright message on the footer bar (default is '')
show_back : bool, optional
If True a "back" button is displayed in the title bar (default is True)
left_back : bool, optional
If True the "back" button is displayed on the left side of the title bar (default is False)
show_help : bool, optional
If True a "help" button is displayed on the right side of the title bar (default is True)
on_help : function, optional
Python function to call when the user clicks the help button. The function will receive no parameters (default is None)
logocreditsurl : str, optional
String containing the url of the credits logo, to be displayed on the right side of the title bar (default is ''). If no url is passed, the logo of the European Commission is displayed
show_credits : bool, optional
If True a "credits" button is displayed on the right side of the title bar (default is True)
on_credits : function, optional
Python function to call when the user clicks the credits button. The function will receive no parameters (default is None)
transition : str, optional
Transition to be used for display and hide of the page (default is 'dialog-bottom-transition'). See: https://vuetifyjs.com/en/styles/transitions/ for a list of available transitions (substitute 'v-' with 'dialog-')
persistent : bool, optional
If True the page will be persistent and not close at the hitting of the "ESC" key (default is False)
Examples
--------
Creation of an example page::
from vois.vuetify import page
from ipywidgets import widgets
from IPython.display import display
output = widgets.Output()
display(output)
def onclose():
pass
def on_click():
pass
p = page.page('Application XYZ', 'Map page', output, onclose=onclose,
titlecolor='#008800', titledark=True,
footercolor='#cccccc', footerdark=False,
logoappurl='https://jeodpp.jrc.ec.europa.eu/services/shared/pngs/BDAP_Logo1024transparent.png',
on_logoapp=on_click, copyrighttext='European Commission - Joint Research Centre',
show_back=True, show_help=True, on_help=on_click,
show_credits=True, on_credits=on_click)
card = p.create()
card.children = []
p.open()
.. figure:: figures/page.png
:scale: 100 %
:alt: page widget
Example of a page
"""
# Click on the APP logo
def click_on_logoapp(self, *args):
if not self.on_logoapp is None:
self.on_logoapp()
# Click on the back button
def click_on_back(self, *args):
try:
self.close()
except:
pass
# Click on the help button
def click_on_help(self, *args):
if not self.on_help is None:
self.on_help()
# Click on the credits button
def click_on_credits(self, *args):
if not self.on_credits is None:
self.on_credits()
# Internal method to create the childrens of the self.appbar instance
def _create_appbar_children(self):
textcolor = 'black'
if self._titledark:
textcolor = 'white'
children = []
if not self.logoapp is None:
btn_logo = v.Btn(text=True, rounded=False, ripple=False, style_='width: %dpx; height: 40px;'%self._logowidth, class_='pa-0 ma-0 ml-1', children=[self.logoapp])
btn_logo.on_event('click', self.click_on_logoapp)
if len(self._appname) > 0:
children.append(tooltip.tooltip("Info on %s"%self._appname, btn_logo))
else:
children.append(btn_logo)
self.toolbarTitle = None
if len(self._appname) > 0:
self.toolbarTitle = v.ToolbarTitle(children=['%s:'%self._appname], class_='pa-0 ma-0 mt-1 ml-1', style_='height: 30px; color: %s; font-size: 26;'%textcolor)
children.append(self.toolbarTitle)
self.toolbarSubtitle = None
if len(self._title) > 0:
self.toolbarSubtitle = v.ToolbarTitle(children=[self._title], class_='pa-0 ma-0 mt-1 ml-2', style_='height: 30px; color: %s; font-size: 26;'%textcolor)
children.append(self.toolbarSubtitle)
children.append(v.Spacer())
self.buttons = []
for cb in self.custom_buttons:
iconname,tooltiptext,callback = cb
btn = v.Btn(icon=True, class_="pa-0 ma-0 mt-1", dark=self._titledark, children=[v.Icon(children=[iconname])])
btn.on_event('click', callback)
self.buttons.append(btn)
children.append(tooltip.tooltip(tooltiptext, btn))
self.btn_back = None
if self._show_back:
self.btn_back = v.Btn(icon=True, class_="pa-0 ma-0 mt-1", dark=self._titledark, children=[v.Icon(children=['mdi-arrow-left'])])
self.btn_back.on_event('click', self.click_on_back)
elem = tooltip.tooltip("Close current page", self.btn_back)
if self._left_back:
children.insert(0, elem)
else:
children.append(elem)
self.btn_help = None
if self._show_help:
self.btn_help = v.Btn(icon=True, class_="pa-0 ma-0 mt-1 mr-3", dark=self._titledark, children=[v.Icon(children=['mdi-help'])])
self.btn_help.on_event('click', self.click_on_help)
children.append(tooltip.tooltip("Display application help", self.btn_help))
self.btn_credits = None
if self._show_credits:
self.btn_credits = v.Btn(text=True, rounded=False, ripple=False, style_='width: 170px; height: %dpx;'%(self._titleheight-4), class_='pa-0 ma-0 mr-1', children=[self.logoCredits])
self.btn_credits.on_event('click', self.click_on_credits)
children.append(tooltip.tooltip("Open credits info", self.btn_credits))
return children
# Create the page and returns the card widget where the content of the page must be displayed
def create(self):
self.appbar = v.AppBar(height=self._titleheight, min_height=self._titleheight, max_height=self._titleheight, color=self._titlecolor,
children=self._create_appbar_children())
if len(self._titleimageurl) > 0:
self.appbar.src = self._titleimageurl
# Content of the footer bar
textcolor = 'black'
if self._footerdark:
textcolor = 'white'
self.copyicon = v.Icon(class_="pa-0 ma-0 mr-2", small=True, color=textcolor, children=['mdi-copyright'])
self.ctext = v.Card(flat=True, color=self._footercolor, style_='color: %s;'%textcolor, children=[self._copyrighttext])
frow = v.Row(class_='pa-0 ma-0 mt-n2 mb-n3', justify="center", no_gutters=True, children=[self.copyicon,self.ctext])
self.footer = v.Footer(color=self._footercolor, padless=True, children=[frow], class_='pa-0 ma-0', rounded=False,
height=self._footerheight, max_height=self._footerheight, min_height=self._footerheight,
style_='height: %dpx; overflow: hidden; border-bottom-left-radius: 0; border-bottom-right-radius: 0;'%self._footerheight)
# Main content of the page: a card to be filled with custom content
self.height = 'calc(100vh - %dpx)'%(self._titleheight+self._footerheight)
self.card = v.Card(children=[], elevation=5,class_="pa-0 ma-0", style_='width: 100vw; max-width: 100vw; height: %s; max-height: %s;'%(self.height,self.height))
return self.card
# Open the dialog
def open(self):
self.dlg = dialogGeneric.dialogGeneric(title='', titleheight='0px', text='', show=True, no_click_animation=True,
addclosebuttons=False, persistent=self.persistent, transition=self._transition,
fullscreen=True, content=[self.appbar,self.card,self.footer], output=self.output)
# Close the dialog
def close(self):
try:
if not self.dlg is None:
self.dlg.close()
if not self.onclose is None:
self.onclose()
except:
pass
self.dlg = None
# Quick open and close of the page (to be called when the titleheight or the footerheight is changed)
def refresh(self):
if self.dlg is not None:
self.close()
oldtransition = self.transition
self.transition = 'dialog-top-transition'
self.open()
self.transition = oldtransition
# Add a custom buttom to the page (before the call to create!)
def customButtonAdd(self, iconname, tooltiptext, callback):
self.custom_buttons.append((iconname,tooltiptext,callback)) # Each item has an icon name, a tooltip string and a callback function
# Remove all custom buttons
def customButtonClear(self):
self.custom_buttons = []
#####################################################################################################################################################
# Properties
#####################################################################################################################################################
@property
def appname(self):
"""
Get/Set the name of the application (displayed on the left side of the title bar)
Returns
--------
name : str
Name of the application
Example
-------
Programmatically change the name of the application::
p.appname = 'New app name'
print(p.appname)
"""
return self._appname
@appname.setter
def appname(self, name):
self._appname = str(name)
self.appbar.children = self._create_appbar_children()
@property
def title(self):
"""
Get/Set the title of the page (displayed on the left side of the title bar)
Returns
--------
title : str
Title of the page
Example
-------
Programmatically change the title of the page::
p.title = 'New title'
print(p.title)
"""
return self._title
@title.setter
def title(self, title):
self._title = str(title)
self.appbar.children = self._create_appbar_children()
@property
def titlecolor(self):
"""
Get/Set the color of the title bar
Returns
--------
color : str
Color of the title bar
Example
-------
Programmatically change the color::
p.titlecolor = 'red'
print(p.titlecolor)
"""
return self._titlecolor
@titlecolor.setter
def titlecolor(self, color):
self._titlecolor = color
self.appbar.color = self._titlecolor
@property
def titledark(self):
"""
Get/Set the text color of the title bar
Returns
--------
flag : bool
If True the text on the title bar will be displayed in white, otherwise in black color
Example
-------
Programmatically change the text color::
p.titledark = True
print(p.titledark)
"""
return self._titledark
@titledark.setter
def titledark(self, flag):
self._titledark = flag
for btn in self.buttons:
btn.dark = self._titledark
if not self.btn_back is None:
self.btn_back.dark = self._titledark
if not self.btn_help is None:
self.btn_help.dark = self._titledark
textcolor = 'black'
if self._titledark:
textcolor = 'white'
if not self.toolbarTitle is None:
self.toolbarTitle.style_ = 'height: 30px; color: %s; font-size: 26;'%textcolor
if not self.toolbarSubtitle is None:
self.toolbarSubtitle.style_ = 'height: 30px; color: %s; font-size: 26;'%textcolor
@property
def titleheight(self):
"""
Get/Set the height of the title bar
Returns
--------
height : int
Height of the title bar in pixels
Example
-------
Programmatically change the title bar height::
p.titleheight = 80
print(p.titleheight)
"""
return self._titleheight
@titleheight.setter
def titleheight(self, height):
self._titleheight = height
if self._titleheight < 20: self._titleheight = 20
if self._titleheight > 200: self._titleheight = 200
self.appbar.height = self.appbar.min_height = self.appbar.max_height = self._titleheight
if not self.btn_credits is None:
self.btn_credits.style_ = 'width: 170px; height: %dpx;'%(self._titleheight-4)
self.height = 'calc(100vh - %dpx)'%(self._titleheight+self._footerheight)
self.card.style_ = 'width: 100vw; max-width: 100vw; height: %s; max-height: %s;'%(self.height,self.height)
@property
def titleimageurl(self):
"""
Get/Set the image to display on the title bar
Returns
--------
imageurl : str
String containing the url of the title bar backbround image
Example
-------
Programmatically change the title bar background image::
p.titleimageurl = 'https://.....'
print(p.titleimageurl)
"""
return self._titleimageurl
@titleimageurl.setter
def titleimageurl(self, imageurl):
self._titleimageurl = str(imageurl)
if len(self._titleimageurl) > 0:
self.appbar.src = self._titleimageurl
else:
self.appbar.src = None
@property
def footercolor(self):
"""
Get/Set the color of the footer bar
Returns
--------
color : str
Color of the footer bar
Example
-------
Programmatically change the color::
p.footercolor = 'red'
print(p.footercolor)
"""
return self._footercolor
@footercolor.setter
def footercolor(self, color):
self._footercolor = color
self.ctext.color = self._footercolor
self.footer.color = self._footercolor
@property
def footerdark(self):
"""
Get/Set the text color of the footer bar
Returns
--------
flag : bool
If True the text on the footer bar will be displayed in white, otherwise in black color
Example
-------
Programmatically change the text color::
p.footerdark = True
print(p.footerdark)
"""
return self._footerdark
@footerdark.setter
def footerdark(self, flag):
self._footerdark = flag
textcolor = 'black'
if self._footerdark:
textcolor = 'white'
self.copyicon.color = textcolor
self.ctext.style_ = 'color: %s;'%textcolor
@property
def footerheight(self):
"""
Get/Set the height of the footer bar
Returns
--------
height : int
Height of the footer bar in pixels
Example
-------
Programmatically change the footer bar height::
p.footerheight = 20
print(p.footerheight)
"""
return self._footerheight
@footerheight.setter
def footerheight(self, height):
self._footerheight = height
if self._footerheight < 20: self._footerheight = 16
if self._footerheight > 200: self._footerheight = 200
self.footer.height = self.footer.min_height = self.footer.max_height = self._footerheight
self.footer.style_ = 'height: %dpx; overflow: hidden; border-bottom-left-radius: 0; border-bottom-right-radius: 0;'%self._footerheight
self.height = 'calc(100vh - %dpx)'%(self._titleheight+self._footerheight)
self.card.style_ = 'width: 100vw; max-width: 100vw; height: %s; max-height: %s;'%(self.height,self.height)
@property
def copyrighttext(self):
"""
Get/Set the copyright text to display on the footer bar
Returns
--------
text : str
Text to display as copyright message on the footer bar
Example
-------
Programmatically change the copyright text::
p.copyrighttext = 'Founded by EU'
print(p.copyrighttext)
"""
return self._copyrighttext
@copyrighttext.setter
def copyrighttext(self, text):
self._copyrighttext = text
self.ctext.children = [self._copyrighttext]
@property
def show_back(self):
"""
Show or hide the back button in the title bar
Returns
--------
flag : bool
If True a "back" button is displayed in the title bar
Example
-------
Programmatically change the presence of the back button in the title bar::
p.show_back = False
print(p.show_back)
"""
return self._show_back
@show_back.setter
def show_back(self, flag):
self._show_back = flag
self.appbar.children = self._create_appbar_children()
@property
def left_back(self):
"""
Get/Set the flag that controls the position of the back button in the title bar
Returns
--------
flag : bool
If True the "back" button is displayed on the left side of the title bar
Example
-------
Programmatically change the position of the back button in the title bar::
p.left_back = False
print(p.left_back)
"""
return self._left_back
@left_back.setter
def left_back(self, flag):
self._left_back = flag
self.appbar.children = self._create_appbar_children()
@property
def show_help(self):
"""
Show or hide the help button in the title bar
Returns
--------
flag : bool
If True a "help" button is displayed in the title bar
Example
-------
Programmatically change the presence of the help button in the title bar::
p.show_help = False
print(p.show_help)
"""
return self._show_help
@show_help.setter
def show_help(self, flag):
self._show_help = flag
self.appbar.children = self._create_appbar_children()
@property
def show_credits(self):
"""
Show or hide the credits image in the title bar
Returns
--------
flag : bool
If True a "credits" button with an image is displayed in the title bar
Example
-------
Programmatically change the presence of the credits button in the title bar::
p.show_credits = False
print(p.show_credits)
"""
return self._show_credits
@show_credits.setter
def show_credits(self, flag):
self._show_credits = flag
self.appbar.children = self._create_appbar_children()
@property
def logoappurl(self):
"""
Get/Set the image to display as the application logo on the left side of the title bar
Returns
--------
imageurl : str
String containing the url of application logo image
Example
-------
Programmatically change the application logo in the title bar::
p.logoappurl = 'data:image/png;base64,...'
print(p.logoappurl)
"""
return self._logoappurl
@logoappurl.setter
def logoappurl(self, imageurl):
self._logoappurl = str(imageurl)
if len(self._logoappurl) > 0:
self.logoapp = v.Img(class_='pa-0 ma-0 mr-2', max_width=self._logowidth, src=self._logoappurl)
else:
self.logoapp = None
self.appbar.children = self._create_appbar_children()
@property
def logocreditsurl(self):
"""
Get/Set the image to display as the application credits on the right side of the title bar
Returns
--------
imageurl : str
String containing the url of application credits image
Example
-------
Programmatically change the application credits in the title bar::
p.logocreditsurl = 'data:image/png;base64,...'
print(p.logocreditsurl)
"""
return self._logocreditsurl
@logocreditsurl.setter
def logocreditsurl(self, imageurl):
self._logocreditsurl = str(imageurl)
if len(self._logocreditsurl) == 0:
self._logocreditsurl = 'https://jeodpp.jrc.ec.europa.eu/services/shared/pngs/EC-JRC-logo_horizontal_EN_neg_transparent-background.png'
self.logoCredits = v.Img(class_='pa-0 ma-0 mr-2', max_width=self._creditswidth, src=self._logocreditsurl)
self.appbar.children = self._create_appbar_children()
@property
def logowidth(self):
"""
Get/Set the width of the application logo button in the title bar
Returns
--------
width : int
Width of the application logo button in pixels
Example
-------
Programmatically change the application logo button width::
p.logowidth = 20
print(p.logowidth)
"""
return self._logowidth
@logowidth.setter
def logowidth(self, width):
self._logowidth = width
if len(self._logoappurl) > 0:
self.logoapp = v.Img(class_='pa-0 ma-0 mr-2', max_width=self._logowidth, src=self._logoappurl)
else:
self.logoapp = None
self.appbar.children = self._create_appbar_children()
@property
def creditswidth(self):
"""
Get/Set the width of the application credits button in the title bar
Returns
--------
width : int
Width of the application credits button in pixels
Example
-------
Programmatically change the application credits button width::
p.creditswidth = 20
print(p.creditswidth)
"""
return self._creditswidth
@creditswidth.setter
def creditswidth(self, width):
self._creditswidth = width
self.logoCredits = v.Img(class_='pa-0 ma-0 mr-2', max_width=self._creditswidth, src=self._logocreditsurl)
self.appbar.children = self._create_appbar_children()
@property
def transition(self):
"""
Get/Set the transition mode to use for the opening of the page. Possible values are: 'dialog-bottom-transition', 'dialog-top-transition' or 'dialog-transition'
Returns
--------
mode : str
Transition mode, one of 'dialog-bottom-transition', 'dialog-top-transition' or 'dialog-transition'
Example
-------
Programmatically change the transition mode::
p.transition = 'dialog-transition'
print(p.transition)
"""
return self._transition
@transition.setter
def transition(self, mode):
self._transition = mode
@property
def state(self):
"""
Get/Set the multiple properties of the page
Returns
--------
statusdict : dict
Dictionary containing one or more properties
Example
-------
Programmatically set some of the properties of a page::
p.state = {'transition': 'dialog-top-transition', 'title': 'new title'}
print(p.state)
"""
return {x: getattr(self, x) for x in ['appname',
'title',
'titlecolor',
'titledark',
'titleheight',
'titleimageurl',
'footercolor',
'footerdark',
'footerheight',
'copyrighttext',
'show_back',
'left_back',
'show_help',
'show_credits',
'logoappurl',
'logocreditsurl',
'logowidth',
'creditswidth',
'transition'
]}
@state.setter
def state(self, statusdict):
for key, value in statusdict.items():
if key != 'content':
setattr(self, key, value)
doRefresh = False
if 'titleheight' in statusdict:
if statusdict['titleheight'] != self.titleheight:
doRefresh = True
if 'footerheight' in statusdict:
if statusdict['footerheight'] != self.footerheight:
doRefresh = True
if doRefresh:
self.refresh()
#####################################################################################################################################################
# Initialization
#####################################################################################################################################################
def __init__(self,
appname,
title,
output,
onclose=None,
titlecolor=settings.color_first,
titledark=True,
titleheight=54,
titleimageurl='',
footercolor=settings.color_second,
footerdark=False,
footerheight=30,
logoappurl='',
logowidth=40,
on_logoapp=None,
copyrighttext='',
show_back=True,
left_back=False,
show_help=True,
on_help=None,
logocreditsurl='',
creditswidth=120,
show_credits=True,
on_credits=None,
transition='dialog-bottom-transition',
persistent=False):
self.dlg = None
self._appname = appname
self._title = title
self.output = output
self.onclose = onclose
self._titlecolor = titlecolor
self._titledark = titledark
self._titleheight = titleheight
self._titleimageurl = titleimageurl
self._footercolor = footercolor
self._footerdark = footerdark
self._footerheight = footerheight
self._copyrighttext = copyrighttext
self._show_back = show_back
self._left_back = left_back
self._show_help = show_help
self.on_help = on_help
self._show_credits = show_credits
self.on_credits = on_credits
self.on_logoapp = on_logoapp
self._transition = transition
self.persistent = persistent
self.custom_buttons = [] # Each item has an icon name, a tooltip string and a callback function
self._logowidth = logowidth
self._creditswidth = creditswidth
self._logoappurl = logoappurl
self._logocreditsurl = logocreditsurl
if len(self._logoappurl) > 0:
self.logoapp = v.Img(class_='pa-0 ma-0 mr-2', max_width=self._logowidth, src=self._logoappurl)
else:
self.logoapp = None
if len(self._logocreditsurl) == 0:
self._logocreditsurl = 'https://jeodpp.jrc.ec.europa.eu/services/shared/pngs/EC-JRC-logo_horizontal_EN_neg_transparent-background.png'
self.logoCredits = v.Img(class_='pa-0 ma-0 mr-2', max_width=self._creditswidth, src=self._logocreditsurl)