Initial themes implementation
163
__init__.py
Normal file
@ -0,0 +1,163 @@
|
||||
from django.conf import settings
|
||||
from django.contrib.staticfiles.templatetags.staticfiles import static
|
||||
from django.forms.models import model_to_dict
|
||||
from django.utils.translation import gettext as _
|
||||
import time
|
||||
|
||||
|
||||
available_themes = [
|
||||
('default', 'Default'),
|
||||
('clear-red', 'Clear Red'),
|
||||
('clear-green', 'Clear Green'),
|
||||
('clear-blue', 'Clear Blue'),
|
||||
]
|
||||
default_theme = 'default'
|
||||
|
||||
|
||||
class ThemeSettings(object):
|
||||
def __init__(self):
|
||||
from .models import Setting
|
||||
s = Setting.objects.filter(id=1).first()
|
||||
if s is None:
|
||||
s = Setting(id=1)
|
||||
s.save()
|
||||
for attr_name in model_to_dict(s):
|
||||
attr = getattr(s, attr_name)
|
||||
if attr_name == 'page_theme' and attr == 'default':
|
||||
setattr(self, attr_name, settings.DEFAULT_THEME)
|
||||
else:
|
||||
setattr(self, attr_name, attr)
|
||||
|
||||
|
||||
class bar(list):
|
||||
def __init__(self, turn_around=False):
|
||||
self.time_measurement = time_measurement()
|
||||
list.__init__(self)
|
||||
self.turn_around = turn_around
|
||||
self.debug = False
|
||||
|
||||
def index(self, entry_uid):
|
||||
for i in range(0, len(self)):
|
||||
if self[i].uid == entry_uid:
|
||||
return i
|
||||
raise ValueError('not in list')
|
||||
|
||||
def append_entry(self, *args, **kwargs):
|
||||
self.append(entry(*args, **kwargs))
|
||||
|
||||
def replace_entry(self, entry_uid, *args, **kwargs):
|
||||
i = self.index(entry_uid)
|
||||
self[i] = entry(*args, **kwargs)
|
||||
|
||||
def append_entry_to_entry(self, entry_uid, *args, **kwargs):
|
||||
i = self.index(entry_uid)
|
||||
self[i].append(entry(*args, **kwargs))
|
||||
|
||||
@property
|
||||
def entries(self):
|
||||
rv = self[:]
|
||||
if self.turn_around is True:
|
||||
rv.reverse()
|
||||
if self.debug is True:
|
||||
rv.append(entry('time_measurement', self.time_measurement.time_str, None, None, True, False))
|
||||
return rv
|
||||
|
||||
|
||||
class Context(dict):
|
||||
ACTIONBAR = 'actionbar'
|
||||
BOTTOMBAR = 'bottombar'
|
||||
MENUBAR = 'menubar'
|
||||
NAVIGATIONBAR = 'navigationbar'
|
||||
SETTINGS = 'settings'
|
||||
TITLE = 'title'
|
||||
|
||||
def __init__(self, request):
|
||||
from .models import BottomBar
|
||||
#
|
||||
dict.__init__(
|
||||
self,
|
||||
bottombar=bar(),
|
||||
actionbar=bar(),
|
||||
navigationbar=bar(turn_around=True),
|
||||
menubar=bar(),
|
||||
settings=ThemeSettings(),
|
||||
title=ThemeSettings().page_title,
|
||||
)
|
||||
#
|
||||
for i in range(1, 6):
|
||||
for e in BottomBar.objects.filter(sequence_number=i):
|
||||
if e.icon:
|
||||
icon_url = e.icon.url
|
||||
else:
|
||||
icon_url = None
|
||||
self[self.BOTTOMBAR].append(entry(
|
||||
'bootombar-%d' % e.id,
|
||||
e.name,
|
||||
icon_url,
|
||||
e.url,
|
||||
e.left,
|
||||
False
|
||||
))
|
||||
if settings.DEBUG:
|
||||
self[self.BOTTOMBAR].debug = True
|
||||
self[self.BOTTOMBAR].append(entry('bottombar-w3-validator', _('W3-Validator'), None, 'https://validator.w3.org/nu/?doc=' + request.build_absolute_uri(), False, False))
|
||||
|
||||
def set_additional_title(self, at):
|
||||
if self[self.SETTINGS].page_title and at:
|
||||
self[self.TITLE] = self[self.SETTINGS].page_title + ' - ' + at
|
||||
else:
|
||||
self[self.TITLE] = self[self.SETTINGS].page_title + at
|
||||
|
||||
|
||||
class entry(list):
|
||||
def __init__(self, uid, name, icon, url, left, active):
|
||||
list.__init__(self)
|
||||
self.uid = uid
|
||||
self.name = name
|
||||
self.icon = icon
|
||||
self.url = url
|
||||
self.left = left
|
||||
self.active = active
|
||||
|
||||
@property
|
||||
def is_dropdownmenu(self):
|
||||
return len(self) > 0
|
||||
|
||||
def __str__(self):
|
||||
return 'barentry: %s' % self.uid
|
||||
|
||||
|
||||
def empty_entry_parameters(request):
|
||||
return (
|
||||
'empty', # uid
|
||||
'', # name
|
||||
transparency_icon_url(request), # icon
|
||||
None, # url
|
||||
True, # left
|
||||
False # active
|
||||
)
|
||||
|
||||
|
||||
def get_themename(request):
|
||||
return ThemeSettings().page_theme
|
||||
|
||||
|
||||
class time_measurement(object):
|
||||
def __init__(self):
|
||||
self._start_time = time.time()
|
||||
|
||||
@property
|
||||
def time_str(self):
|
||||
return _('Time consumption') + ': %.2fs' % (time.time() - self._start_time)
|
||||
|
||||
|
||||
def transparency_icon_url(request):
|
||||
return static('themes/' + get_themename(request) + '/transparency.png')
|
||||
|
||||
|
||||
def color_icon_url(request, icon_filename):
|
||||
return static('themes/' + get_themename(request) + '/1st-color/%s' % icon_filename)
|
||||
|
||||
|
||||
def gray_icon_url(request, icon_filename):
|
||||
return static('themes/' + get_themename(request) + '/2nd-color/%s' % icon_filename)
|
5
admin.py
Normal file
@ -0,0 +1,5 @@
|
||||
from django.contrib import admin
|
||||
from .models import Setting, BottomBar
|
||||
|
||||
admin.site.register(Setting)
|
||||
admin.site.register(BottomBar)
|
8
apps.py
Normal file
@ -0,0 +1,8 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ThemesConfig(AppConfig):
|
||||
name = 'themes'
|
||||
|
||||
def ready(self):
|
||||
import themes.signals
|
BIN
locale/de/LC_MESSAGES/django.mo
Normal file
33
locale/de/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,33 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-19 09:24+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: __init__.py:41
|
||||
msgid "W3-Validator"
|
||||
msgstr "W3-Validator"
|
||||
|
||||
#: __init__.py:107
|
||||
msgid "Time consumption"
|
||||
msgstr "Zeit"
|
||||
|
||||
#: templates/themes/clear-blue/base.html:23
|
||||
#: templates/themes/clear-green/base.html:23
|
||||
#: templates/themes/clear-red/base.html:23
|
||||
msgid "Search..."
|
||||
msgstr "Suche..."
|
34
migrations/0001_initial.py
Normal file
@ -0,0 +1,34 @@
|
||||
# Generated by Django 2.2.5 on 2019-12-18 20:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BottomBar',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, max_length=64)),
|
||||
('icon', models.ImageField(blank=True, upload_to='theme')),
|
||||
('url', models.URLField()),
|
||||
('left', models.BooleanField()),
|
||||
('sequence_number', models.SmallIntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')])),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Setting',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('page_image', models.ImageField(default='theme/logo.png', upload_to='theme')),
|
||||
('page_theme', models.CharField(choices=[('default', 'Default'), ('clear-red', 'Clear Red'), ('clear-green', 'Clear Green'), ('clear-blue', 'Clear Blue')], default='default', max_length=64)),
|
||||
('page_title', models.CharField(blank=True, default='MyApp', max_length=32)),
|
||||
],
|
||||
),
|
||||
]
|
0
migrations/__init__.py
Normal file
42
models.py
Normal file
@ -0,0 +1,42 @@
|
||||
from django.db import models
|
||||
from . import available_themes, default_theme
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class Setting(models.Model):
|
||||
page_image = models.ImageField(
|
||||
upload_to='theme',
|
||||
default='theme/logo.png'
|
||||
)
|
||||
page_theme = models.CharField(
|
||||
max_length=64,
|
||||
choices=available_themes,
|
||||
default=default_theme
|
||||
)
|
||||
page_title = models.CharField(max_length=32, default='MyApp', blank=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
img = Image.open(self.page_image.path)
|
||||
if img.height > 50:
|
||||
output_size = (int(img.width * 50 / img.height), 50)
|
||||
img.thumbnail(output_size)
|
||||
img.save(self.page_image.path)
|
||||
|
||||
|
||||
class BottomBar(models.Model):
|
||||
name = models.CharField(max_length=64, blank=True)
|
||||
icon = models.ImageField(upload_to='theme', blank=True)
|
||||
url = models.URLField()
|
||||
left = models.BooleanField()
|
||||
sequence_number = models.SmallIntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')])
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
if self.icon:
|
||||
img = Image.open(self.icon.path)
|
||||
if img.height > 40:
|
||||
output_size = (int(img.width * 40 / img.height), 40)
|
||||
img.thumbnail(output_size)
|
||||
img.save(self.icon.path)
|
74
signals.py
Normal file
@ -0,0 +1,74 @@
|
||||
from django.db.models.signals import pre_delete, pre_save
|
||||
from django.dispatch import receiver
|
||||
from .models import BottomBar, Setting
|
||||
import os
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=BottomBar)
|
||||
def bottombar_auto_delete_file_on_delete(instance: BottomBar, **kwargs):
|
||||
"""
|
||||
Deletes file from filesystem
|
||||
when corresponding `BottomBar` object is deleted.
|
||||
"""
|
||||
if instance.icon:
|
||||
if os.path.isfile(instance.icon.path):
|
||||
os.remove(instance.icon.path)
|
||||
|
||||
|
||||
@receiver(pre_save, sender=BottomBar)
|
||||
def bottombar_auto_delete_file_on_change(instance: BottomBar, **kwargs):
|
||||
"""
|
||||
Deletes old file from filesystem
|
||||
when corresponding `icon` object is updated
|
||||
with new file.
|
||||
"""
|
||||
if not instance.pk:
|
||||
return False
|
||||
|
||||
try:
|
||||
old_file = BottomBar.objects.get(pk=instance.pk).icon
|
||||
except BottomBar.DoesNotExist:
|
||||
return False
|
||||
|
||||
new_file = instance.icon
|
||||
if not old_file == new_file:
|
||||
if os.path.isfile(old_file.path):
|
||||
os.remove(old_file.path)
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=Setting)
|
||||
def setting_auto_delete_file_on_delete(instance: Setting, **kwargs):
|
||||
"""
|
||||
Deletes file from filesystem
|
||||
when corresponding `Settings` object is deleted.
|
||||
"""
|
||||
if instance.page_image.path.endswith(instance.page_image.field.default):
|
||||
return False
|
||||
|
||||
if instance.page_image:
|
||||
if os.path.isfile(instance.page_image.path):
|
||||
os.remove(instance.page_image.path)
|
||||
|
||||
|
||||
@receiver(pre_save, sender=Setting)
|
||||
def setting_auto_delete_file_on_change(instance: Setting, **kwargs):
|
||||
"""
|
||||
Deletes old file from filesystem
|
||||
when corresponding `page_image` object is updated
|
||||
with new file.
|
||||
"""
|
||||
if not instance.pk:
|
||||
return False
|
||||
|
||||
try:
|
||||
old_file = Setting.objects.get(pk=instance.pk).page_image
|
||||
except Setting.DoesNotExist:
|
||||
return False
|
||||
|
||||
if old_file.path.endswith(instance.page_image.field.default):
|
||||
return False
|
||||
|
||||
new_file = instance.page_image
|
||||
if not old_file == new_file:
|
||||
if os.path.isfile(old_file.path):
|
||||
os.remove(old_file.path)
|
BIN
static/themes/clear-blue/1st-color/0.png
Normal file
After Width: | Height: | Size: 576 B |
BIN
static/themes/clear-blue/1st-color/1.png
Normal file
After Width: | Height: | Size: 398 B |
BIN
static/themes/clear-blue/1st-color/2.png
Normal file
After Width: | Height: | Size: 569 B |
BIN
static/themes/clear-blue/1st-color/3.png
Normal file
After Width: | Height: | Size: 584 B |
BIN
static/themes/clear-blue/1st-color/4.png
Normal file
After Width: | Height: | Size: 464 B |
BIN
static/themes/clear-blue/1st-color/5.png
Normal file
After Width: | Height: | Size: 499 B |
BIN
static/themes/clear-blue/1st-color/6.png
Normal file
After Width: | Height: | Size: 564 B |
BIN
static/themes/clear-blue/1st-color/7.png
Normal file
After Width: | Height: | Size: 479 B |
BIN
static/themes/clear-blue/1st-color/8.png
Normal file
After Width: | Height: | Size: 609 B |
BIN
static/themes/clear-blue/1st-color/9.png
Normal file
After Width: | Height: | Size: 588 B |
BIN
static/themes/clear-blue/1st-color/admin.png
Normal file
After Width: | Height: | Size: 486 B |
BIN
static/themes/clear-blue/1st-color/back.png
Normal file
After Width: | Height: | Size: 407 B |
BIN
static/themes/clear-blue/1st-color/delete.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
static/themes/clear-blue/1st-color/display.png
Normal file
After Width: | Height: | Size: 235 B |
BIN
static/themes/clear-blue/1st-color/download.png
Normal file
After Width: | Height: | Size: 360 B |
BIN
static/themes/clear-blue/1st-color/edit.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
static/themes/clear-blue/1st-color/edit2.png
Normal file
After Width: | Height: | Size: 540 B |
BIN
static/themes/clear-blue/1st-color/favourite.png
Normal file
After Width: | Height: | Size: 468 B |
BIN
static/themes/clear-blue/1st-color/filter.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
static/themes/clear-blue/1st-color/folder.png
Normal file
After Width: | Height: | Size: 241 B |
BIN
static/themes/clear-blue/1st-color/gps.png
Normal file
After Width: | Height: | Size: 556 B |
BIN
static/themes/clear-blue/1st-color/help.png
Normal file
After Width: | Height: | Size: 508 B |
BIN
static/themes/clear-blue/1st-color/info.png
Normal file
After Width: | Height: | Size: 404 B |
BIN
static/themes/clear-blue/1st-color/is_favourite.png
Normal file
After Width: | Height: | Size: 493 B |
BIN
static/themes/clear-blue/1st-color/login.png
Normal file
After Width: | Height: | Size: 421 B |
BIN
static/themes/clear-blue/1st-color/logout.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
static/themes/clear-blue/1st-color/permission.png
Normal file
After Width: | Height: | Size: 414 B |
BIN
static/themes/clear-blue/1st-color/play.png
Normal file
After Width: | Height: | Size: 446 B |
BIN
static/themes/clear-blue/1st-color/plus.png
Normal file
After Width: | Height: | Size: 439 B |
BIN
static/themes/clear-blue/1st-color/print.png
Normal file
After Width: | Height: | Size: 334 B |
BIN
static/themes/clear-blue/1st-color/register.png
Normal file
After Width: | Height: | Size: 429 B |
BIN
static/themes/clear-blue/1st-color/save.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
static/themes/clear-blue/1st-color/search.png
Normal file
After Width: | Height: | Size: 474 B |
BIN
static/themes/clear-blue/1st-color/settings.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
static/themes/clear-blue/1st-color/shuffle.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
static/themes/clear-blue/1st-color/sort.png
Normal file
After Width: | Height: | Size: 335 B |
BIN
static/themes/clear-blue/1st-color/staging.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
static/themes/clear-blue/1st-color/stop.png
Normal file
After Width: | Height: | Size: 390 B |
BIN
static/themes/clear-blue/1st-color/task.png
Normal file
After Width: | Height: | Size: 419 B |
BIN
static/themes/clear-blue/1st-color/upload.png
Normal file
After Width: | Height: | Size: 373 B |
BIN
static/themes/clear-blue/1st-color/user.png
Normal file
After Width: | Height: | Size: 406 B |
BIN
static/themes/clear-blue/1st-color/view.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
static/themes/clear-blue/2nd-color/0.png
Normal file
After Width: | Height: | Size: 499 B |
BIN
static/themes/clear-blue/2nd-color/1.png
Normal file
After Width: | Height: | Size: 372 B |
BIN
static/themes/clear-blue/2nd-color/2.png
Normal file
After Width: | Height: | Size: 517 B |
BIN
static/themes/clear-blue/2nd-color/3.png
Normal file
After Width: | Height: | Size: 521 B |
BIN
static/themes/clear-blue/2nd-color/4.png
Normal file
After Width: | Height: | Size: 421 B |
BIN
static/themes/clear-blue/2nd-color/5.png
Normal file
After Width: | Height: | Size: 463 B |
BIN
static/themes/clear-blue/2nd-color/6.png
Normal file
After Width: | Height: | Size: 514 B |
BIN
static/themes/clear-blue/2nd-color/7.png
Normal file
After Width: | Height: | Size: 436 B |
BIN
static/themes/clear-blue/2nd-color/8.png
Normal file
After Width: | Height: | Size: 538 B |
BIN
static/themes/clear-blue/2nd-color/9.png
Normal file
After Width: | Height: | Size: 523 B |
BIN
static/themes/clear-blue/2nd-color/admin.png
Normal file
After Width: | Height: | Size: 480 B |
BIN
static/themes/clear-blue/2nd-color/back.png
Normal file
After Width: | Height: | Size: 390 B |
BIN
static/themes/clear-blue/2nd-color/delete.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
static/themes/clear-blue/2nd-color/display.png
Normal file
After Width: | Height: | Size: 231 B |
BIN
static/themes/clear-blue/2nd-color/download.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
static/themes/clear-blue/2nd-color/download_flat.png
Normal file
After Width: | Height: | Size: 310 B |
BIN
static/themes/clear-blue/2nd-color/edit.png
Normal file
After Width: | Height: | Size: 256 B |
BIN
static/themes/clear-blue/2nd-color/edit2.png
Normal file
After Width: | Height: | Size: 451 B |
BIN
static/themes/clear-blue/2nd-color/favourite.png
Normal file
After Width: | Height: | Size: 455 B |
BIN
static/themes/clear-blue/2nd-color/filter.png
Normal file
After Width: | Height: | Size: 318 B |
BIN
static/themes/clear-blue/2nd-color/folder.png
Normal file
After Width: | Height: | Size: 224 B |
BIN
static/themes/clear-blue/2nd-color/gps.png
Normal file
After Width: | Height: | Size: 513 B |
BIN
static/themes/clear-blue/2nd-color/home.png
Normal file
After Width: | Height: | Size: 345 B |
BIN
static/themes/clear-blue/2nd-color/info.png
Normal file
After Width: | Height: | Size: 390 B |
BIN
static/themes/clear-blue/2nd-color/login.png
Normal file
After Width: | Height: | Size: 397 B |
BIN
static/themes/clear-blue/2nd-color/logout.png
Normal file
After Width: | Height: | Size: 399 B |
BIN
static/themes/clear-blue/2nd-color/permission.png
Normal file
After Width: | Height: | Size: 385 B |
BIN
static/themes/clear-blue/2nd-color/play.png
Normal file
After Width: | Height: | Size: 445 B |
BIN
static/themes/clear-blue/2nd-color/plus.png
Normal file
After Width: | Height: | Size: 401 B |
BIN
static/themes/clear-blue/2nd-color/print.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
static/themes/clear-blue/2nd-color/register.png
Normal file
After Width: | Height: | Size: 419 B |
BIN
static/themes/clear-blue/2nd-color/save.png
Normal file
After Width: | Height: | Size: 235 B |
BIN
static/themes/clear-blue/2nd-color/search.png
Normal file
After Width: | Height: | Size: 456 B |
BIN
static/themes/clear-blue/2nd-color/settings.png
Normal file
After Width: | Height: | Size: 246 B |
BIN
static/themes/clear-blue/2nd-color/shuffle.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
static/themes/clear-blue/2nd-color/sort.png
Normal file
After Width: | Height: | Size: 322 B |
BIN
static/themes/clear-blue/2nd-color/staging.png
Normal file
After Width: | Height: | Size: 244 B |
BIN
static/themes/clear-blue/2nd-color/stop.png
Normal file
After Width: | Height: | Size: 370 B |
BIN
static/themes/clear-blue/2nd-color/task.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
static/themes/clear-blue/2nd-color/upload.png
Normal file
After Width: | Height: | Size: 342 B |
BIN
static/themes/clear-blue/2nd-color/user.png
Normal file
After Width: | Height: | Size: 367 B |
BIN
static/themes/clear-blue/2nd-color/view.png
Normal file
After Width: | Height: | Size: 378 B |
BIN
static/themes/clear-blue/search.png
Normal file
After Width: | Height: | Size: 1020 B |
BIN
static/themes/clear-blue/transparency.png
Normal file
After Width: | Height: | Size: 168 B |
BIN
static/themes/clear-green/1st-color/0.png
Normal file
After Width: | Height: | Size: 546 B |
BIN
static/themes/clear-green/1st-color/1.png
Normal file
After Width: | Height: | Size: 397 B |
BIN
static/themes/clear-green/1st-color/2.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
static/themes/clear-green/1st-color/3.png
Normal file
After Width: | Height: | Size: 571 B |
BIN
static/themes/clear-green/1st-color/4.png
Normal file
After Width: | Height: | Size: 457 B |