many small improvements
This commit is contained in:
parent
95c4319340
commit
cf144e5b28
2
build.sh
2
build.sh
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
rm -rf ./dist/
|
#rm -rf ./dist/
|
||||||
python setup.py bdist_wheel
|
python setup.py bdist_wheel
|
||||||
|
|
||||||
wheel_files=( dist/*whl )
|
wheel_files=( dist/*whl )
|
||||||
|
BIN
dist/pyscript_bootstrap_templates-0.2.0-py3-none-any.whl
vendored
Normal file
BIN
dist/pyscript_bootstrap_templates-0.2.0-py3-none-any.whl
vendored
Normal file
Binary file not shown.
@ -20,6 +20,8 @@ toast_container.position_end = 0
|
|||||||
|
|
||||||
|
|
||||||
def onclick(_):
|
def onclick(_):
|
||||||
|
# NOTE: you can also use app.toast(...) and app.alert_success(...) to show toasts
|
||||||
|
# and alerts at the default bottom right position
|
||||||
alert = bHTML.AlertSuccess("You clicked me!", parent=app.main)
|
alert = bHTML.AlertSuccess("You clicked me!", parent=app.main)
|
||||||
alert.w = 25
|
alert.w = 25
|
||||||
toast = bHTML.Toast("You clicked me!", parent=toast_container)
|
toast = bHTML.Toast("You clicked me!", parent=toast_container)
|
||||||
@ -27,4 +29,3 @@ def onclick(_):
|
|||||||
toast.show()
|
toast.show()
|
||||||
|
|
||||||
btn.onclick = onclick
|
btn.onclick = onclick
|
||||||
|
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
const pwa_version = "01_hello_world_202306031006"
|
const pwa_version = "01_hello_world_202306041650"
|
||||||
const assets = ["./index.html",
|
const assets = ["./index.html",
|
||||||
"./main.py",
|
"./main.py",
|
||||||
"./resources/bootstrap.css",
|
"./resources/bootstrap.css",
|
||||||
@ -48,4 +48,15 @@ self.addEventListener('fetch', event => {
|
|||||||
return response;
|
return response;
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keyList) => {
|
||||||
|
return Promise.all(keyList.map((key) => {
|
||||||
|
if(key !== pwa_version) {
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
const pwa_version = "02_image_filter_202306031006"
|
const pwa_version = "02_image_filter_202306041650"
|
||||||
const assets = ["./index.html",
|
const assets = ["./index.html",
|
||||||
"./main.py",
|
"./main.py",
|
||||||
"./resources/bootstrap.css",
|
"./resources/bootstrap.css",
|
||||||
@ -48,4 +48,15 @@ self.addEventListener('fetch', event => {
|
|||||||
return response;
|
return response;
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keyList) => {
|
||||||
|
return Promise.all(keyList.map((key) => {
|
||||||
|
if(key !== pwa_version) {
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
const pwa_version = "03_numpy_grid_demo_202306031006"
|
const pwa_version = "03_numpy_grid_demo_202306041650"
|
||||||
const assets = ["./index.html",
|
const assets = ["./index.html",
|
||||||
"./main.py",
|
"./main.py",
|
||||||
"./resources/bootstrap.css",
|
"./resources/bootstrap.css",
|
||||||
@ -48,4 +48,15 @@ self.addEventListener('fetch', event => {
|
|||||||
return response;
|
return response;
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keyList) => {
|
||||||
|
return Promise.all(keyList.map((key) => {
|
||||||
|
if(key !== pwa_version) {
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -9,13 +9,13 @@ import numpy as np
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
import cv2
|
import cv2
|
||||||
|
|
||||||
loaded_img = None
|
loaded_img:np.ndarray = None
|
||||||
|
|
||||||
app = bootstrap_templates.PyScriptBootstrapDashboard(parent_element="pyscript_app", brand_name="Pyscript Cell Detector")
|
app = bootstrap_templates.PyScriptBootstrapDashboard(parent_element="pyscript_app", brand_name="Pyscript Cell Colony Detector")
|
||||||
|
|
||||||
main_div = bHTML.BootstrapContainer(parent=app.main)
|
main_div = bHTML.BootstrapContainer(parent=app.main)
|
||||||
main_div.w = 100
|
main_div.w = 100
|
||||||
result_div = bHTML.BootstrapContainer(parent=main_div)
|
result_div = bHTML.BootstrapContainer (parent=main_div)
|
||||||
|
|
||||||
|
|
||||||
def process_image(image,
|
def process_image(image,
|
||||||
@ -24,13 +24,20 @@ def process_image(image,
|
|||||||
hough_param2 = 500,
|
hough_param2 = 500,
|
||||||
minRadius = 100,
|
minRadius = 100,
|
||||||
maxRadius=500,
|
maxRadius=500,
|
||||||
inner_hough_circles=True):
|
inner_hough_param1 = 25,
|
||||||
|
inner_hough_param2 = 50,
|
||||||
|
inner_hough_circles=True,
|
||||||
|
cell_colony_color_channel:int = None):
|
||||||
|
|
||||||
for child in result_div.children:
|
for child in result_div.children:
|
||||||
child.destroy()
|
child.destroy()
|
||||||
#image = cv2.imread(str(test_img_path), cv2.IMREAD_COLOR)
|
|
||||||
# Convert the image to grayscale
|
# Convert the image to grayscale
|
||||||
|
if cell_colony_color_channel is None:
|
||||||
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||||
|
else:
|
||||||
|
gray = image.astype(float)[...,cell_colony_color_channel]
|
||||||
|
gray = (255 * gray / gray.max()).astype(np.uint8)
|
||||||
|
|
||||||
# Use median blur to reduce noise
|
# Use median blur to reduce noise
|
||||||
gray = cv2.medianBlur(gray, 5)
|
gray = cv2.medianBlur(gray, 5)
|
||||||
@ -46,7 +53,7 @@ def process_image(image,
|
|||||||
maxRadius=maxRadius)
|
maxRadius=maxRadius)
|
||||||
|
|
||||||
if circles is None:
|
if circles is None:
|
||||||
bHTML.AlertDanger("No cell areas detected in image", parent=app.main)
|
app.alert_danger("No cell areas detected in image")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Convert to integers
|
# Convert to integers
|
||||||
@ -84,7 +91,14 @@ def process_image(image,
|
|||||||
|
|
||||||
for well, well_gray in zip(first_wells, first_wells_gray):
|
for well, well_gray in zip(first_wells, first_wells_gray):
|
||||||
|
|
||||||
circles = cv2.HoughCircles(well_gray, cv2.HOUGH_GRADIENT, 1, minDist=hough_min_dist, param1=50, param2=50, minRadius=(well.shape[0] // 2) - 50, maxRadius=(well.shape[0] // 2) - 10)
|
circles = cv2.HoughCircles(well_gray,
|
||||||
|
cv2.HOUGH_GRADIENT,
|
||||||
|
1,
|
||||||
|
minDist=hough_min_dist,
|
||||||
|
param1=inner_hough_param1,
|
||||||
|
param2=inner_hough_param2,
|
||||||
|
minRadius=int((min(well.shape[0],well.shape[1]) // 2)*0.79),
|
||||||
|
maxRadius=int((min(well.shape[0],well.shape[1]) // 2)*0.95))
|
||||||
if circles is not None:
|
if circles is not None:
|
||||||
circles = np.uint16(np.around(circles))
|
circles = np.uint16(np.around(circles))
|
||||||
i = circles[0,:][0]
|
i = circles[0,:][0]
|
||||||
@ -109,9 +123,11 @@ def process_image(image,
|
|||||||
second_wells = first_wells
|
second_wells = first_wells
|
||||||
second_wells_gray = first_wells_gray
|
second_wells_gray = first_wells_gray
|
||||||
|
|
||||||
|
tabs = {}
|
||||||
|
|
||||||
for well, well_gray in zip(second_wells, second_wells_gray):
|
for well in second_wells:
|
||||||
|
|
||||||
|
well_gray = cv2.cvtColor(well, cv2.COLOR_BGR2GRAY)
|
||||||
_, binary = cv2.threshold(255 - well_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
_, binary = cv2.threshold(255 - well_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||||||
|
|
||||||
|
|
||||||
@ -120,29 +136,37 @@ def process_image(image,
|
|||||||
cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
|
cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
|
||||||
|
|
||||||
|
|
||||||
radius = well.shape[0] // 2 -1
|
radius = min(well.shape[0], well.shape[1]) // 2 -1
|
||||||
# Now clear all pixels outside the circular well.
|
# Now clear all pixels outside the circular well.
|
||||||
# We do this by creating a mask for the well and applying it to the image.
|
# We do this by creating a mask for the well and applying it to the image.
|
||||||
well_mask = np.zeros_like(cleaned, dtype=np.uint8)
|
well_mask = np.zeros_like(cleaned, dtype=np.uint8)
|
||||||
cv2.circle(well_mask, (radius, radius), radius, 1, thickness=-1)
|
cv2.circle(well_mask, (well.shape[1] // 2, well.shape[0] // 2), radius, 1, thickness=-1)
|
||||||
cleaned = cleaned * well_mask
|
cleaned = cleaned * well_mask
|
||||||
|
|
||||||
circle = well_mask > 0
|
circle = well_mask > 0
|
||||||
|
|
||||||
# now create an image overlay to display
|
# now create an image overlay to display
|
||||||
ratio = np.sum((cleaned > 0).astype(int)) / np.sum(circle.astype(int))
|
ratio = np.sum((cleaned > 0).astype(int)) / np.sum(circle.astype(int))
|
||||||
div_result = bHTML.BootstrapContainer(f"ratio: {ratio * 100}%", parent=result_div)
|
div_result = bHTML.BootstrapContainer(f"ratio: {ratio * 100}%")
|
||||||
div_result.shadow = bHTML.Shadow.LARGE
|
div_result.shadow = bHTML.Shadow.LARGE
|
||||||
div_result.rounded = True
|
div_result.rounded = True
|
||||||
div_result.w = 50
|
div_result.w = 75
|
||||||
|
div_result.h = 75
|
||||||
|
div_result.rounded_size = 50
|
||||||
|
div_result.p = 3
|
||||||
|
|
||||||
|
well = well.copy()
|
||||||
well[cleaned > 0,0] = 255
|
well[cleaned > 0,0] = 255
|
||||||
final_img = bHTML.Image.from_numpy_array(well, parent=div_result)
|
final_img = bHTML.Image.from_numpy_array(well, parent=div_result)
|
||||||
final_img.rounded = True
|
final_img.rounded = True
|
||||||
final_img.rounded_size = 10
|
final_img.rounded_size = 50
|
||||||
final_img.shadow = bHTML.Shadow.LARGE
|
final_img.shadow = bHTML.Shadow.LARGE
|
||||||
final_img.w = 100
|
final_img.w = 100
|
||||||
|
|
||||||
|
tabs[f"Well #{len(tabs) + 1}"] = div_result
|
||||||
|
|
||||||
|
tabs = bHTML.Tabs(tabs, parent=result_div)
|
||||||
|
tabs.w = 100
|
||||||
|
|
||||||
|
|
||||||
div = bHTML.BootstrapContainer("Controls", parent=app.sidebar)
|
div = bHTML.BootstrapContainer("Controls", parent=app.sidebar)
|
||||||
@ -150,55 +174,117 @@ div.font_size = 4
|
|||||||
|
|
||||||
image_input = bInputs.InputFile(label_text="choose image file", parent=app.sidebar)
|
image_input = bInputs.InputFile(label_text="choose image file", parent=app.sidebar)
|
||||||
|
|
||||||
i_hough_min_dist = bInputs.InputInt("hough min distance [px]", parent=app.sidebar)
|
|
||||||
i_hough_min_dist.value = 500
|
|
||||||
|
|
||||||
i_hough_param1 = bInputs.InputInt("hough param1", parent=app.sidebar)
|
|
||||||
i_hough_param1.value = 80
|
|
||||||
|
|
||||||
i_hough_param2 = bInputs.InputInt("hough param2", parent=app.sidebar)
|
|
||||||
i_hough_param2.value = 500
|
|
||||||
|
|
||||||
i_hough_min_radius = bInputs.InputInt("hough min radius [px]", parent=app.sidebar)
|
|
||||||
i_hough_min_radius.value = 100
|
|
||||||
|
|
||||||
i_hough_max_radius = bInputs.InputInt("hough max radius [px]", parent=app.sidebar)
|
|
||||||
i_hough_max_radius.value = 500
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
btn = bHTML.ButtonPrimary("Process", parent=app.sidebar)
|
btn = bHTML.ButtonPrimary("Process", parent=app.sidebar)
|
||||||
btn.w = 100
|
btn.w = 100
|
||||||
|
btn.mt = 3
|
||||||
|
btn.mb = 3
|
||||||
|
btn.ml = 4
|
||||||
|
btn.mr = 4
|
||||||
|
|
||||||
|
i_hough_min_dist = bInputs.InputInt("hough min distance [px]",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="minimal distance between wells in pixels")
|
||||||
|
i_hough_min_dist.value = 500
|
||||||
|
|
||||||
|
i_hough_param1 = bInputs.InputInt("hough param1",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="parameter for canny edge detector")
|
||||||
|
i_hough_param1.value = 80
|
||||||
|
|
||||||
|
i_hough_param2 = bInputs.InputInt("hough param2",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="increase this value to prevent false circle detection")
|
||||||
|
i_hough_param2.value = 500
|
||||||
|
|
||||||
|
i_hough_min_radius = bInputs.InputInt("hough min radius [px]",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="min radius for circle detection")
|
||||||
|
i_hough_min_radius.value = 100
|
||||||
|
|
||||||
|
i_hough_max_radius = bInputs.InputInt("hough max radius [px]",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="max radius for circle detection")
|
||||||
|
i_hough_max_radius.value = 500
|
||||||
|
|
||||||
|
i_inner_hough = bInputs.InputCheckboxSingle("nested hough transform?",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="if set, circle detection will be applied twice on detected wells")
|
||||||
|
i_inner_hough.value = True
|
||||||
|
i_inner_hough.m = 3
|
||||||
|
|
||||||
|
i_inner_hough_param1 = bInputs.InputInt("inner hough param1", parent=app.sidebar)
|
||||||
|
i_inner_hough_param1.value = 25
|
||||||
|
|
||||||
|
i_inner_hough_param2 = bInputs.InputInt("inner hough param2", parent=app.sidebar)
|
||||||
|
i_inner_hough_param2.value = 50
|
||||||
|
|
||||||
|
i_use_color_channel = bInputs.InputSelect(["all",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"blue"],
|
||||||
|
label_text="cell colony color channel",
|
||||||
|
parent=app.sidebar,
|
||||||
|
help_text="if cells are more present in a specific channel, select it here")
|
||||||
|
i_use_color_channel.value = "blue"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def on_image_change(f, *args):
|
def on_image_change(f, *args):
|
||||||
|
|
||||||
|
try:
|
||||||
global loaded_img
|
global loaded_img
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
img = np.array(Image.open(f))
|
img = np.array(Image.open(f))
|
||||||
for child in result_div.children:
|
for child in result_div.children:
|
||||||
child.destroy()
|
child.destroy()
|
||||||
|
|
||||||
|
bHTML.BootstrapContainer("input image:", parent=result_div)
|
||||||
output = bHTML.Image.from_numpy_array(img, parent=result_div)
|
output = bHTML.Image.from_numpy_array(img, parent=result_div)
|
||||||
output.rounded = True
|
output.rounded = True
|
||||||
output.rounded_size = 10
|
output.rounded_size = 10
|
||||||
output.shadow = bHTML.Shadow.LARGE
|
output.shadow = bHTML.Shadow.LARGE
|
||||||
output.w=50
|
output.width = "100%"
|
||||||
|
output.height = "100%"
|
||||||
|
|
||||||
loaded_img = img
|
loaded_img = img
|
||||||
|
|
||||||
|
app.toast("successfully loaded image", "info")
|
||||||
|
#toast = bHTML.Toast("successfully loaded image", title="info", parent=toast_container)
|
||||||
|
#toast.animation = True
|
||||||
|
#toast.show()
|
||||||
|
except Exception as e:
|
||||||
|
for child in result_div.children:
|
||||||
|
child.destroy()
|
||||||
|
bHTML.AlertDanger(f"error while loading image: {str(e)}", parent=alert_container)
|
||||||
|
|
||||||
|
|
||||||
image_input.onchange = on_image_change
|
image_input.onchange = on_image_change
|
||||||
|
|
||||||
def on_click(*args, **kwargs):
|
def on_click(*args, **kwargs):
|
||||||
if loaded_img is None:
|
if loaded_img is None:
|
||||||
bHTML.AlertDanger("No image loaded", parent=app.main)
|
app.alert_danger("No image loaded")
|
||||||
return
|
return
|
||||||
|
for child in result_div.children:
|
||||||
|
child.destroy()
|
||||||
|
|
||||||
|
try:
|
||||||
h_min_dist = int(i_hough_min_dist.value)
|
h_min_dist = int(i_hough_min_dist.value)
|
||||||
h_param1 = int(i_hough_param1.value)
|
h_param1 = int(i_hough_param1.value)
|
||||||
h_param2 = int(i_hough_param2.value)
|
h_param2 = int(i_hough_param2.value)
|
||||||
|
h_inner_param1 = int(i_inner_hough_param1.value)
|
||||||
|
h_inner_param2 = int(i_inner_hough_param2.value)
|
||||||
h_min_radius = int(i_hough_min_radius.value)
|
h_min_radius = int(i_hough_min_radius.value)
|
||||||
h_max_radius = int(i_hough_max_radius.value)
|
h_max_radius = int(i_hough_max_radius.value)
|
||||||
|
inner_hough = bool(i_inner_hough.value)
|
||||||
|
color_channel = {
|
||||||
|
"all": None,
|
||||||
|
"red": 0,
|
||||||
|
"green": 1,
|
||||||
|
"blue": 2
|
||||||
|
}[i_use_color_channel.value]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
process_image(loaded_img,
|
process_image(loaded_img,
|
||||||
@ -207,7 +293,16 @@ def on_click(*args, **kwargs):
|
|||||||
hough_param2=h_param2,
|
hough_param2=h_param2,
|
||||||
minRadius=h_min_radius,
|
minRadius=h_min_radius,
|
||||||
maxRadius=h_max_radius,
|
maxRadius=h_max_radius,
|
||||||
inner_hough_circles=True)
|
inner_hough_param1=h_inner_param1,
|
||||||
|
inner_hough_param2=h_inner_param2,
|
||||||
|
inner_hough_circles=inner_hough,
|
||||||
|
cell_colony_color_channel=color_channel)
|
||||||
|
app.toast("successfully processed image", title="info")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
for child in result_div.children:
|
||||||
|
child.destroy()
|
||||||
|
app.alert_danger(f"error while processing image: {str(e)}")
|
||||||
|
|
||||||
btn.onclick = on_click
|
btn.onclick = on_click
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
const pwa_version = "04_cell_detector_202306031006"
|
const pwa_version = "04_cell_detector_202306041650"
|
||||||
const assets = ["./index.html",
|
const assets = ["./index.html",
|
||||||
"./main.py",
|
"./main.py",
|
||||||
"./resources/bootstrap.css",
|
"./resources/bootstrap.css",
|
||||||
@ -48,4 +48,15 @@ self.addEventListener('fetch', event => {
|
|||||||
return response;
|
return response;
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keyList) => {
|
||||||
|
return Promise.all(keyList.map((key) => {
|
||||||
|
if(key !== pwa_version) {
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -68,6 +68,7 @@ class Element(object):
|
|||||||
self._display = self.element.style.display
|
self._display = self.element.style.display
|
||||||
self.element.style.display = "none"
|
self.element.style.display = "none"
|
||||||
|
|
||||||
|
|
||||||
def show(self) -> None:
|
def show(self) -> None:
|
||||||
if self._display is None:
|
if self._display is None:
|
||||||
return
|
return
|
||||||
@ -210,6 +211,27 @@ class Element(object):
|
|||||||
def write(self, object):
|
def write(self, object):
|
||||||
self.element.write(self.id, object) # type: ignore
|
self.element.write(self.id, object) # type: ignore
|
||||||
|
|
||||||
|
def set_style(self, property_name: str, value: str) -> None:
|
||||||
|
"""Set a CSS style property on this element."""
|
||||||
|
setattr(self._element.style, property_name, value)
|
||||||
|
|
||||||
|
def get_style(self, property_name: str) -> str:
|
||||||
|
"""Get the value of a CSS style property on this element."""
|
||||||
|
try:
|
||||||
|
return getattr(self._element.style, property_name)
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def remove_style(self, property_name: str) -> None:
|
||||||
|
"""Remove a CSS style property from this element."""
|
||||||
|
setattr(self._element.style, property_name, None)
|
||||||
|
|
||||||
|
def set_styles(self, **styles) -> None:
|
||||||
|
"""Set multiple CSS style properties on this element."""
|
||||||
|
for property_name, value in styles.items():
|
||||||
|
self.set_style(property_name, value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class A(Element):
|
class A(Element):
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -796,16 +796,22 @@ class Col(BootstrapContainer):
|
|||||||
class_name: str = None,
|
class_name: str = None,
|
||||||
parent: HTML.Element = None,
|
parent: HTML.Element = None,
|
||||||
col: int = None,
|
col: int = None,
|
||||||
|
col_xs: int = None,
|
||||||
col_sm: int = None,
|
col_sm: int = None,
|
||||||
col_md: int = None,
|
col_md: int = None,
|
||||||
col_lg: int = None,
|
col_lg: int = None,
|
||||||
col_xl: int = None,
|
col_xl: int = None,
|
||||||
col_xxl: int = None) -> None:
|
col_xxl: int = None) -> None:
|
||||||
|
|
||||||
|
|
||||||
|
super().__init__(inner_html, id, class_name, parent)
|
||||||
|
|
||||||
|
|
||||||
if col is not None:
|
if col is not None:
|
||||||
self.col = col
|
self.col = col
|
||||||
|
|
||||||
super().__init__(inner_html, id, class_name, parent)
|
if col_xs is not None:
|
||||||
|
self.col_xs = col_xs
|
||||||
|
|
||||||
if col_sm is not None:
|
if col_sm is not None:
|
||||||
self.col_sm = col_sm
|
self.col_sm = col_sm
|
||||||
@ -1110,6 +1116,9 @@ class NavbarBrand(HTML.A, BootstrapContainer):
|
|||||||
parent=parent)
|
parent=parent)
|
||||||
|
|
||||||
self.set_attribute("href", href)
|
self.set_attribute("href", href)
|
||||||
|
self.ms = 3
|
||||||
|
self.me = 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Navbar(BootstrapContainer):
|
class Navbar(BootstrapContainer):
|
||||||
|
@ -315,6 +315,15 @@ class BootstrapContainer(HTML.Div):
|
|||||||
self._set_enum_property(
|
self._set_enum_property(
|
||||||
value=value, prefix="text-", enum_class=TextAlign, enum_values=_TEXT_ALIGNS)
|
value=value, prefix="text-", enum_class=TextAlign, enum_values=_TEXT_ALIGNS)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def text_align_xs(self) -> Union[TextAlign, None]:
|
||||||
|
return self._get_enum_property(prefix="text-", enum_class=TextAlign, enum_values=_TEXT_ALIGNS, breakpoint="xs")
|
||||||
|
|
||||||
|
@text_align_xs.setter
|
||||||
|
def text_align_xs(self, value: Union[TextAlign, None]):
|
||||||
|
self._set_enum_property(value=value, prefix="text-",
|
||||||
|
enum_class=TextAlign, enum_values=_TEXT_ALIGNS, breakpoint="xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def text_align_sm(self) -> Union[TextAlign, None]:
|
def text_align_sm(self) -> Union[TextAlign, None]:
|
||||||
return self._get_enum_property(prefix="text-", enum_class=TextAlign, enum_values=_TEXT_ALIGNS, breakpoint="sm")
|
return self._get_enum_property(prefix="text-", enum_class=TextAlign, enum_values=_TEXT_ALIGNS, breakpoint="sm")
|
||||||
@ -559,6 +568,15 @@ class BootstrapContainer(HTML.Div):
|
|||||||
self._set_enum_property(
|
self._set_enum_property(
|
||||||
value=value, prefix="d-", enum_class=DisplayProperty, enum_values=_DISPLAY_PROPERTIES)
|
value=value, prefix="d-", enum_class=DisplayProperty, enum_values=_DISPLAY_PROPERTIES)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_property_xs(self) -> Union[DisplayProperty, None]:
|
||||||
|
return self._get_enum_property(prefix="d-", enum_class=DisplayProperty, enum_values=_DISPLAY_PROPERTIES, breakpoint="xs")
|
||||||
|
|
||||||
|
@display_property_xs.setter
|
||||||
|
def display_property_xs(self, value: Union[DisplayProperty, None]):
|
||||||
|
self._set_enum_property(value=value, prefix="d-", enum_class=DisplayProperty,
|
||||||
|
enum_values=_DISPLAY_PROPERTIES, breakpoint="xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def display_property_sm(self) -> Union[DisplayProperty, None]:
|
def display_property_sm(self) -> Union[DisplayProperty, None]:
|
||||||
return self._get_enum_property(prefix="d-", enum_class=DisplayProperty, enum_values=_DISPLAY_PROPERTIES, breakpoint="sm")
|
return self._get_enum_property(prefix="d-", enum_class=DisplayProperty, enum_values=_DISPLAY_PROPERTIES, breakpoint="sm")
|
||||||
@ -1113,6 +1131,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def p(self, value: Union[int, str, None]):
|
def p(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("p-", value)
|
self._set_css_param_number("p-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def p_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's padding for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("p-", "xs")
|
||||||
|
|
||||||
|
@p_xs.setter
|
||||||
|
def p_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("p-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def p_sm(self) -> Union[int, str, None]:
|
def p_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1179,6 +1208,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def px(self, value: Union[int, str, None]):
|
def px(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("px-", value)
|
self._set_css_param_number("px-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def px_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's horizontal padding for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("px-", "xs")
|
||||||
|
|
||||||
|
@px_xs.setter
|
||||||
|
def px_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("px-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def px_sm(self) -> Union[int, str, None]:
|
def px_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1245,6 +1285,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def py(self, value: Union[int, str, None]):
|
def py(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("py-", value)
|
self._set_css_param_number("py-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def py_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's vertical padding for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("py-", "xs")
|
||||||
|
|
||||||
|
@py_xs.setter
|
||||||
|
def py_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("py-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def py_sm(self) -> Union[int, str, None]:
|
def py_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1311,6 +1362,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def pt(self, value: Union[int, str, None]):
|
def pt(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("pt-", value)
|
self._set_css_param_number("pt-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pt_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's top padding for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("pt-", "xs")
|
||||||
|
|
||||||
|
@pt_xs.setter
|
||||||
|
def pt_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("pt-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pt_sm(self) -> Union[int, str, None]:
|
def pt_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1377,6 +1439,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def pb(self, value: Union[int, str, None]):
|
def pb(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("pb-", value)
|
self._set_css_param_number("pb-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pb_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's bottom padding for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("pb-", "xs")
|
||||||
|
|
||||||
|
@pb_xs.setter
|
||||||
|
def pb_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("pb-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pb_sm(self) -> Union[int, str, None]:
|
def pb_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1443,6 +1516,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def ps(self, value: Union[int, str, None]):
|
def ps(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("ps-", value)
|
self._set_css_param_number("ps-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ps_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's start padding (left for LTR languages) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("ps-", "xs")
|
||||||
|
|
||||||
|
@ps_xs.setter
|
||||||
|
def ps_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("ps-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ps_sm(self) -> Union[int, str, None]:
|
def ps_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1509,6 +1593,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def pe(self, value: Union[int, str, None]):
|
def pe(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("pe-", value)
|
self._set_css_param_number("pe-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pe_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's end padding (right for LTR languages) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("pe-", "xs")
|
||||||
|
|
||||||
|
@pe_xs.setter
|
||||||
|
def pe_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("pe-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pe_sm(self) -> Union[int, str, None]:
|
def pe_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1577,6 +1672,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def m(self, value: Union[int, str, None]):
|
def m(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("m-", value)
|
self._set_css_param_number("m-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def m_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's margin for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("m-", "xs")
|
||||||
|
|
||||||
|
@m_xs.setter
|
||||||
|
def m_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("m-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def m_sm(self) -> Union[int, str, None]:
|
def m_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1643,6 +1749,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def mx(self, value: Union[int, str, None]):
|
def mx(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("mx-", value)
|
self._set_css_param_number("mx-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mx_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's margin-left and margin-right for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("mx-", "xs")
|
||||||
|
|
||||||
|
@mx_xs.setter
|
||||||
|
def mx_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("mx-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mx_sm(self) -> Union[int, str, None]:
|
def mx_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1709,6 +1826,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def my(self, value: Union[int, str, None]):
|
def my(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("my-", value)
|
self._set_css_param_number("my-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def my_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's margin-top and margin-bottom for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("my-", "xs")
|
||||||
|
|
||||||
|
@my_xs.setter
|
||||||
|
def my_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("my-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def my_sm(self) -> Union[int, str, None]:
|
def my_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1775,6 +1903,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def mt(self, value: Union[int, str, None]):
|
def mt(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("mt-", value)
|
self._set_css_param_number("mt-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mt_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's margin-top for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("mt-", "xs")
|
||||||
|
|
||||||
|
@mt_xs.setter
|
||||||
|
def mt_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("mt-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mt_sm(self) -> Union[int, str, None]:
|
def mt_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1841,6 +1980,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def mb(self, value: Union[int, str, None]):
|
def mb(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("mb-", value)
|
self._set_css_param_number("mb-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mb_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's margin-bottom for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("mb-", "xs")
|
||||||
|
|
||||||
|
@mb_xs.setter
|
||||||
|
def mb_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("mb-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mb_sm(self) -> Union[int, str, None]:
|
def mb_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1907,6 +2057,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def ms(self, value: Union[int, str, None]):
|
def ms(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("ms-", value)
|
self._set_css_param_number("ms-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ms_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's start margin (left for LTR languages) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("ms-", "xs")
|
||||||
|
|
||||||
|
@ms_xs.setter
|
||||||
|
def ms_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("ms-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ms_sm(self) -> Union[int, str, None]:
|
def ms_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -1973,6 +2134,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def me(self, value: Union[int, str, None]):
|
def me(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("me-", value)
|
self._set_css_param_number("me-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def me_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
element's end margin (right for LTR languages) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5,auto
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("me-", "xs")
|
||||||
|
|
||||||
|
@me_xs.setter
|
||||||
|
def me_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("me-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def me_sm(self) -> Union[int, str, None]:
|
def me_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -2041,6 +2213,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def g(self, value: Union[int, str, None]):
|
def g(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("g-", value)
|
self._set_css_param_number("g-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def g_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
gutter (gutters are the space between the element and its content) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("g-", "xs")
|
||||||
|
|
||||||
|
@g_xs.setter
|
||||||
|
def g_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("g-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def g_sm(self) -> Union[int, str, None]:
|
def g_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -2107,6 +2290,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def gx(self, value: Union[int, str, None]):
|
def gx(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("gx-", value)
|
self._set_css_param_number("gx-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gx_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
horizontal gutter (gutters are the space between the element and its content) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("gx-", "xs")
|
||||||
|
|
||||||
|
@gx_xs.setter
|
||||||
|
def gx_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("gx-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gx_sm(self) -> Union[int, str, None]:
|
def gx_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -2173,6 +2367,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def gy(self, value: Union[int, str, None]):
|
def gy(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("gy-", value)
|
self._set_css_param_number("gy-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gy_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
vertical gutter (gutters are the space between the element and its content) for small screens. By default, bootstrap defines the values 0,1,2,3,4,5
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("gy-", "xs")
|
||||||
|
|
||||||
|
@gy_xs.setter
|
||||||
|
def gy_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("gy-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gy_sm(self) -> Union[int, str, None]:
|
def gy_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
@ -2241,6 +2446,17 @@ class BootstrapContainer(HTML.Div):
|
|||||||
def col(self, value: Union[int, str, None]):
|
def col(self, value: Union[int, str, None]):
|
||||||
self._set_css_param_number("col-", value)
|
self._set_css_param_number("col-", value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def col_xs(self) -> Union[int, str, None]:
|
||||||
|
"""
|
||||||
|
column class for very small screens. By default, bootstrap defines the values 1,2,3,4,5,6,7,8,9,10,11,12
|
||||||
|
"""
|
||||||
|
return self._get_css_param_number("col-", "xs")
|
||||||
|
|
||||||
|
@col_xs.setter
|
||||||
|
def col_xs(self, value: Union[int, str, None]):
|
||||||
|
self._set_css_param_number("col-", value, "xs")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def col_sm(self) -> Union[int, str, None]:
|
def col_sm(self) -> Union[int, str, None]:
|
||||||
"""
|
"""
|
||||||
|
@ -10,20 +10,112 @@ class PyScriptBootstrapApp(object):
|
|||||||
self._main_div.vh_100 = True
|
self._main_div.vh_100 = True
|
||||||
|
|
||||||
self._main_div.p = 0
|
self._main_div.p = 0
|
||||||
|
self._main_div.m = 0
|
||||||
|
|
||||||
|
self._main_div.col_xs = 12
|
||||||
|
self._main_div.col = 12
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self._parent_element = document.getElementById(parent_element)
|
self._parent_element = document.getElementById(parent_element)
|
||||||
self._parent_element.appendChild(self._main_div.element)
|
self._parent_element.appendChild(self._main_div.element)
|
||||||
|
|
||||||
|
self._toast_container = bHTML.ToastContainer(parent=self._main_div)
|
||||||
|
self._toast_container.position_end = 0
|
||||||
|
self._toast_container.position_bottom = 0
|
||||||
|
|
||||||
|
self._alert_container = bHTML.BootstrapContainer(parent=self._main_div)
|
||||||
|
self._alert_container.position_end = 0
|
||||||
|
self._alert_container.position_bottom = 0
|
||||||
|
self._alert_container.position = bHTML.Position.ABSOLUTE
|
||||||
|
|
||||||
|
def _alert(self, message: str, alert_class: type):
|
||||||
|
return alert_class(message, parent=self._alert_container)
|
||||||
|
bHTML.Al
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def main(self) -> HTML.Div:
|
def main(self) -> HTML.Div:
|
||||||
return self._main_div
|
return self._main_div
|
||||||
|
|
||||||
|
@property
|
||||||
|
def toast_container(self) -> bHTML.ToastContainer:
|
||||||
|
return self._toast_container
|
||||||
|
|
||||||
|
@property
|
||||||
|
def alert_container(self) -> bHTML.BootstrapContainer:
|
||||||
|
return self._alert_container
|
||||||
|
|
||||||
|
def toast(self, message: str, title: str, animation: bool = True, show: bool = True) -> bHTML.Toast:
|
||||||
|
"""
|
||||||
|
show a toast on the default toast location (bottom right)
|
||||||
|
"""
|
||||||
|
toast = bHTML.Toast(inner_html=message, title=title, parent=self._toast_container)
|
||||||
|
toast.animation = animation
|
||||||
|
if show:
|
||||||
|
toast.show()
|
||||||
|
return toast
|
||||||
|
|
||||||
|
def alert(self, message:str) -> bHTML.Alert:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.Alert)
|
||||||
|
|
||||||
|
def alert_success(self, message:str) -> bHTML.AlertSuccess:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertSuccess)
|
||||||
|
|
||||||
|
def alert_info(self, message:str) -> bHTML.AlertInfo:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertInfo)
|
||||||
|
|
||||||
|
def alert_warning(self, message:str) -> bHTML.AlertWarning:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertWarning)
|
||||||
|
|
||||||
|
def alert_danger(self, message:str) -> bHTML.AlertDanger:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertDanger)
|
||||||
|
|
||||||
|
def alert_primary(self, message:str) -> bHTML.AlertPrimary:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertPrimary)
|
||||||
|
|
||||||
|
def alert_secondary(self, message:str) -> bHTML.AlertSecondary:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertSecondary)
|
||||||
|
|
||||||
|
def alert_light(self, message:str) -> bHTML.AlertLight:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertLight)
|
||||||
|
|
||||||
|
def alert_dark(self, message:str) -> bHTML.AlertDark:
|
||||||
|
"""
|
||||||
|
show an alert on the default alert location (bottom right)
|
||||||
|
"""
|
||||||
|
return self._alert(message, bHTML.AlertDark)
|
||||||
|
|
||||||
class PyScriptBootstrapDashboard(PyScriptBootstrapApp):
|
class PyScriptBootstrapDashboard(PyScriptBootstrapApp):
|
||||||
def __init__(self, parent_element:str = "pyscript_app", brand_name = "Dashboard"):
|
def __init__(self, parent_element:str = "pyscript_app", brand_name = "Dashboard"):
|
||||||
|
|
||||||
super().__init__(parent_element)
|
super().__init__(parent_element)
|
||||||
|
|
||||||
self._sidebar = bHTML.Col(id="sidebar", col_sm=5, col_md=4, col_lg=3, col_xl=3)
|
self._sidebar = bHTML.Col(id="sidebar", col=12, col_sm=12, col_md=4, col_lg=3, col_xl=3)
|
||||||
|
self._sidebar.style = {"height": "100vh", "overflow": "auto"}
|
||||||
|
|
||||||
self._navbar = bHTML.NavbarDark(
|
self._navbar = bHTML.NavbarDark(
|
||||||
parent=self._main_div,
|
parent=self._main_div,
|
||||||
@ -32,13 +124,30 @@ class PyScriptBootstrapDashboard(PyScriptBootstrapApp):
|
|||||||
toggle_button_for_target=self.sidebar
|
toggle_button_for_target=self.sidebar
|
||||||
)
|
)
|
||||||
|
|
||||||
self._navbar.position = bHTML.Position.STICKY_TOP
|
self._navbar.position = bHTML.Position.FIXED_TOP
|
||||||
self._navbar.w = 100
|
self._navbar.height = "4em"
|
||||||
|
self._navbar.ps = 5
|
||||||
|
self._navbar.pe = 5
|
||||||
|
self._navbar.col = 12
|
||||||
|
|
||||||
|
|
||||||
|
top_margin_dummy = bHTML.BootstrapContainer(id="top_margin_dummy", parent=self._main_div)
|
||||||
|
top_margin_dummy.height = "3.5em" # have it slightly less high than navbar
|
||||||
|
top_margin_dummy.width = "100vw"
|
||||||
|
top_margin_dummy.m = 0
|
||||||
|
top_margin_dummy.p = 0
|
||||||
|
|
||||||
|
|
||||||
row = bHTML.Row(parent=self._main_div)
|
row = bHTML.Row(parent=self._main_div)
|
||||||
row.h = 100
|
|
||||||
row.w = 100
|
row.w = 100
|
||||||
|
|
||||||
|
row.height = "calc(100vh - 4em)"
|
||||||
|
row.p = 0
|
||||||
|
row.m = 0
|
||||||
|
row.col_xs = 12
|
||||||
|
row.col = 12
|
||||||
|
|
||||||
|
|
||||||
row.display_property = bHTML.DisplayProperty.INLINE_FLEX
|
row.display_property = bHTML.DisplayProperty.INLINE_FLEX
|
||||||
|
|
||||||
row.append_child(self.sidebar)
|
row.append_child(self.sidebar)
|
||||||
@ -49,17 +158,19 @@ class PyScriptBootstrapDashboard(PyScriptBootstrapApp):
|
|||||||
self._sidebar.position = bHTML.Position.STATIC
|
self._sidebar.position = bHTML.Position.STATIC
|
||||||
self._sidebar.collapsable = True
|
self._sidebar.collapsable = True
|
||||||
self._sidebar.mw = 100
|
self._sidebar.mw = 100
|
||||||
|
self._sidebar.height = "calc(100vh - 4em)"
|
||||||
self._sidebar.shadow = bHTML.Shadow.LARGE
|
self._sidebar.shadow = bHTML.Shadow.LARGE
|
||||||
self._sidebar.overflow = bHTML.Overflow.HIDDEN
|
self._sidebar.overflow = bHTML.Overflow.SCROLL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self._modal = bHTML.Modal(parent=self._main_div, title="Modal")
|
self._modal = bHTML.Modal(parent=self._main_div, title="Modal")
|
||||||
|
|
||||||
self._main_area = bHTML.Col(id="main_area", parent=row, col_lg=9, col_xl=9)
|
self._main_area = bHTML.Col(id="main_area", parent=row, col=12, col_sm=12, col_md=8, col_lg=9, col_xl=9)
|
||||||
|
|
||||||
self._main_area.p = 4
|
self._main_area.p = 4
|
||||||
self._main_area.overflow = bHTML.Overflow.HIDDEN
|
self._main_area.overflow = bHTML.Overflow.SCROLL
|
||||||
#self._main_area.vh_100 = True
|
self._main_area.height = "calc(100vh - 4em)"
|
||||||
self._main_area.mw = 100
|
self._main_area.mw = 100
|
||||||
|
|
||||||
def show_modal(self):
|
def show_modal(self):
|
||||||
|
@ -106,6 +106,17 @@ self.addEventListener('fetch', event => {{
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}})());
|
}})());
|
||||||
|
}});
|
||||||
|
self.addEventListener('activate', (event) => {{
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keyList) => {{
|
||||||
|
return Promise.all(keyList.map((key) => {{
|
||||||
|
if(key !== pwa_version) {{
|
||||||
|
return caches.delete(key);
|
||||||
|
}}
|
||||||
|
}}));
|
||||||
|
}})
|
||||||
|
);
|
||||||
}});
|
}});
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -306,7 +317,7 @@ def main():
|
|||||||
argument_parser.add_argument("--bootstrap-js-url", type=str,
|
argument_parser.add_argument("--bootstrap-js-url", type=str,
|
||||||
help="the url of the bootstrap js file", default="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js")
|
help="the url of the bootstrap js file", default="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js")
|
||||||
argument_parser.add_argument("--pyscript-bootstrap-templates-wheel-url", type=str,
|
argument_parser.add_argument("--pyscript-bootstrap-templates-wheel-url", type=str,
|
||||||
help="the url of the pyscript bootstrap templates wheel file", default="https://the-cake-is-a-lie.net/gogs/jonas/pyscript-bootstrap-templates/raw/branch/main/dist/pyscript_bootstrap_templates-0.1.0-py3-none-any.whl")
|
help="the url of the pyscript bootstrap templates wheel file", default="https://the-cake-is-a-lie.net/gogs/jonas/pyscript-bootstrap-templates/raw/branch/main/dist/pyscript_bootstrap_templates-0.2.0-py3-none-any.whl")
|
||||||
argument_parser.add_argument("--pwa-bg-color", type=str, help="background color for pwa configuration", default="#000000")
|
argument_parser.add_argument("--pwa-bg-color", type=str, help="background color for pwa configuration", default="#000000")
|
||||||
argument_parser.add_argument("--pwa-theme-color", type=str, help="theme color for pwa configuration", default="#ffffff")
|
argument_parser.add_argument("--pwa-theme-color", type=str, help="theme color for pwa configuration", default="#ffffff")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user