Compare commits
4 Commits
projekcija
...
projekcija
| Author | SHA1 | Date | |
|---|---|---|---|
| 39ac654e17 | |||
| f31b9e897b | |||
| c03ad593f2 | |||
| 5529f81989 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Projekcija",
|
"name": "Projekcija",
|
||||||
"description": "Aplikacija za projekcijo besedil pesmi na zaslon.",
|
"description": "Aplikacija za projekcijo besedil pesmi na zaslon.",
|
||||||
"version": "0.7.1",
|
"version": "0.8.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Uroš Urbanija (izvorna zasnova)",
|
"Uroš Urbanija (izvorna zasnova)",
|
||||||
"Valentin Korenjak (nadgradnje in vzdrževanje)"
|
"Valentin Korenjak (nadgradnje in vzdrževanje)"
|
||||||
|
|||||||
190
projector.py
190
projector.py
@@ -239,30 +239,81 @@ class SongProjector:
|
|||||||
"""
|
"""
|
||||||
Vrne seznam pod-vrstic, ki skupaj tvorijo `line`,
|
Vrne seznam pod-vrstic, ki skupaj tvorijo `line`,
|
||||||
pri čemer so dolge največ `self.color_width` pikslov.
|
pri čemer so dolge največ `self.color_width` pikslov.
|
||||||
|
Namesto preprostega 'greedy' preloma izračuna število delov
|
||||||
|
in poskuša narediti vrstice podobnih dolžin.
|
||||||
"""
|
"""
|
||||||
words = line.split()
|
words = line.split()
|
||||||
if not words:
|
if not words:
|
||||||
return [""]
|
return [""]
|
||||||
|
|
||||||
sub_lines = []
|
total_width = self.custom_font.measure(line)
|
||||||
current_words = []
|
if total_width <= self.color_width:
|
||||||
|
return [line]
|
||||||
|
|
||||||
|
# Izračunamo, na koliko delov moramo prelomiti vrstico
|
||||||
|
num_parts = (total_width // self.color_width) + 1
|
||||||
|
|
||||||
|
# Če je num_parts še vedno premalo (zaradi presledkov), preverimo z greedy
|
||||||
|
temp_sub_lines = []
|
||||||
|
current_words = []
|
||||||
for word in words:
|
for word in words:
|
||||||
test_line = " ".join(current_words + [word])
|
test_line = " ".join(current_words + [word])
|
||||||
# Izmerimo širino v pikslih
|
|
||||||
if self.custom_font.measure(test_line) <= self.color_width:
|
if self.custom_font.measure(test_line) <= self.color_width:
|
||||||
current_words.append(word)
|
current_words.append(word)
|
||||||
else:
|
else:
|
||||||
if current_words:
|
if current_words:
|
||||||
sub_lines.append(" ".join(current_words))
|
temp_sub_lines.append(" ".join(current_words))
|
||||||
current_words = [word]
|
current_words = [word]
|
||||||
else:
|
else:
|
||||||
# Beseda je sama po sebi predolga (zelo redko)
|
temp_sub_lines.append(word)
|
||||||
sub_lines.append(word)
|
|
||||||
current_words = []
|
current_words = []
|
||||||
|
|
||||||
if current_words:
|
if current_words:
|
||||||
sub_lines.append(" ".join(current_words))
|
temp_sub_lines.append(" ".join(current_words))
|
||||||
|
|
||||||
|
num_parts = max(num_parts, len(temp_sub_lines))
|
||||||
|
if num_parts <= 1:
|
||||||
|
return [line]
|
||||||
|
|
||||||
|
# Ciljna dolžina vsakega dela
|
||||||
|
target_width = total_width / num_parts
|
||||||
|
|
||||||
|
sub_lines = []
|
||||||
|
remaining_words = words
|
||||||
|
|
||||||
|
# Porazdelimo besede tako, da so vrstice čim bolj enakomerne
|
||||||
|
for i in range(num_parts - 1):
|
||||||
|
best_split_idx = 1
|
||||||
|
min_diff = float('inf')
|
||||||
|
|
||||||
|
for j in range(1, len(remaining_words)):
|
||||||
|
test_line = " ".join(remaining_words[:j])
|
||||||
|
width = self.custom_font.measure(test_line)
|
||||||
|
|
||||||
|
if width > self.color_width:
|
||||||
|
break
|
||||||
|
|
||||||
|
diff = abs(width - target_width)
|
||||||
|
if diff < min_diff:
|
||||||
|
min_diff = diff
|
||||||
|
best_split_idx = j
|
||||||
|
else:
|
||||||
|
# Ker širina narašča, ko se enkrat začne diff povečevati,
|
||||||
|
# smo našli lokalni minimum za to vrstico
|
||||||
|
break
|
||||||
|
|
||||||
|
sub_lines.append(" ".join(remaining_words[:best_split_idx]))
|
||||||
|
remaining_words = remaining_words[best_split_idx:]
|
||||||
|
if not remaining_words:
|
||||||
|
break
|
||||||
|
|
||||||
|
if remaining_words:
|
||||||
|
# Zadnji del (lahko je še vedno predolg, če so bile prejšnje vrstice prekratke)
|
||||||
|
last_line = " ".join(remaining_words)
|
||||||
|
if self.custom_font.measure(last_line) <= self.color_width:
|
||||||
|
sub_lines.append(last_line)
|
||||||
|
else:
|
||||||
|
# Če je zadnji del še vedno predolg, ga rekurzivno razbijemo (varnostni mehanizem)
|
||||||
|
sub_lines.extend(self.split_long_line(last_line))
|
||||||
|
|
||||||
return sub_lines
|
return sub_lines
|
||||||
|
|
||||||
@@ -364,16 +415,19 @@ class SongProjector:
|
|||||||
|
|
||||||
processed_stanzas = []
|
processed_stanzas = []
|
||||||
for stanza in stanzas_raw:
|
for stanza in stanzas_raw:
|
||||||
# Znotraj kitice ohranimo enojne prazne vrstice kot razmike
|
# Razdelimo kitico na odstavke (ločene z eno prazno vrstico)
|
||||||
lines = stanza.splitlines()
|
paragraphs_raw = re.split(r'\n\s*\n', stanza)
|
||||||
stanza_lines = []
|
stanza_paragraphs = []
|
||||||
|
for para in paragraphs_raw:
|
||||||
|
lines = para.splitlines()
|
||||||
|
para_lines = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.strip():
|
if line.strip():
|
||||||
stanza_lines.extend(self.split_long_line(line))
|
para_lines.extend(self.split_long_line(line))
|
||||||
else:
|
if para_lines:
|
||||||
stanza_lines.append("") # Enojna prazna vrstica znotraj kitice
|
stanza_paragraphs.append(para_lines)
|
||||||
if stanza_lines:
|
if stanza_paragraphs:
|
||||||
processed_stanzas.append(stanza_lines)
|
processed_stanzas.append(stanza_paragraphs)
|
||||||
|
|
||||||
# 2. Razdeljevanje kitic na strani
|
# 2. Razdeljevanje kitic na strani
|
||||||
pages = []
|
pages = []
|
||||||
@@ -381,66 +435,80 @@ class SongProjector:
|
|||||||
current_height = 0
|
current_height = 0
|
||||||
split_by_stanza = self.settings.get("split_by_stanza", False)
|
split_by_stanza = self.settings.get("split_by_stanza", False)
|
||||||
|
|
||||||
for stanza in processed_stanzas:
|
for stanza_paragraphs in processed_stanzas:
|
||||||
stanza_height = len(stanza) * self.line_height
|
# Če je vklopljen split_by_stanza, vsaka kitica dobi svojo stran (ali več, če je predolga)
|
||||||
|
|
||||||
# Če je vklopljen split_by_stanza, vsaka kitica dobi svojo stran
|
|
||||||
if split_by_stanza:
|
if split_by_stanza:
|
||||||
if current_page_lines:
|
if current_page_lines:
|
||||||
pages.append("\n".join(current_page_lines))
|
pages.append("\n".join(current_page_lines))
|
||||||
current_page_lines = []
|
current_page_lines = []
|
||||||
current_height = 0
|
current_height = 0
|
||||||
|
|
||||||
# Če je kitica predolga za eno stran, jo še vedno moramo razdeliti
|
for para in stanza_paragraphs:
|
||||||
if stanza_height > max_height:
|
para_height = len(para) * self.line_height
|
||||||
temp_stanza_lines = []
|
# Če odstavek ne gre na trenutno stran (ki je v tem načinu prazna ali vsebuje prejšnje odstavke iste kitice)
|
||||||
temp_height = 0
|
if current_height + para_height + (self.line_height if current_page_lines else 0) > max_height:
|
||||||
for line in stanza:
|
|
||||||
if temp_height + self.line_height > max_height:
|
|
||||||
pages.append("\n".join(temp_stanza_lines))
|
|
||||||
temp_stanza_lines = [line]
|
|
||||||
temp_height = self.line_height
|
|
||||||
else:
|
|
||||||
temp_stanza_lines.append(line)
|
|
||||||
temp_height += self.line_height
|
|
||||||
if temp_stanza_lines:
|
|
||||||
pages.append("\n".join(temp_stanza_lines))
|
|
||||||
else:
|
|
||||||
pages.append("\n".join(stanza))
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Standardna logika (več kitic na stran, če grejo)
|
|
||||||
if stanza_height > max_height:
|
|
||||||
if current_page_lines:
|
if current_page_lines:
|
||||||
pages.append("\n".join(current_page_lines))
|
pages.append("\n".join(current_page_lines))
|
||||||
current_page_lines = []
|
current_page_lines = []
|
||||||
current_height = 0
|
current_height = 0
|
||||||
|
|
||||||
temp_stanza_lines = []
|
# Če je sam odstavek predolg za eno stran, ga razdelimo po vrsticah
|
||||||
temp_height = 0
|
if para_height > max_height:
|
||||||
for line in stanza:
|
for line in para:
|
||||||
if temp_height + self.line_height > max_height:
|
if current_height + self.line_height > max_height:
|
||||||
pages.append("\n".join(temp_stanza_lines))
|
|
||||||
temp_stanza_lines = [line]
|
|
||||||
temp_height = self.line_height
|
|
||||||
else:
|
|
||||||
temp_stanza_lines.append(line)
|
|
||||||
temp_height += self.line_height
|
|
||||||
if temp_stanza_lines:
|
|
||||||
current_page_lines = temp_stanza_lines
|
|
||||||
current_height = temp_height
|
|
||||||
|
|
||||||
elif current_height + stanza_height + (self.line_height if current_page_lines else 0) > max_height:
|
|
||||||
pages.append("\n".join(current_page_lines))
|
pages.append("\n".join(current_page_lines))
|
||||||
current_page_lines = stanza
|
current_page_lines = [line]
|
||||||
current_height = stanza_height
|
current_height = self.line_height
|
||||||
|
else:
|
||||||
|
current_page_lines.append(line)
|
||||||
|
current_height += self.line_height
|
||||||
|
else:
|
||||||
|
current_page_lines = para[:]
|
||||||
|
current_height = para_height
|
||||||
else:
|
else:
|
||||||
if current_page_lines:
|
if current_page_lines:
|
||||||
current_page_lines.append("") # Razmik med kiticami
|
current_page_lines.append("") # Razmik med odstavki znotraj kitice
|
||||||
current_height += self.line_height
|
current_height += self.line_height
|
||||||
current_page_lines.extend(stanza)
|
current_page_lines.extend(para)
|
||||||
current_height += stanza_height
|
current_height += para_height
|
||||||
|
|
||||||
|
if current_page_lines:
|
||||||
|
pages.append("\n".join(current_page_lines))
|
||||||
|
current_page_lines = []
|
||||||
|
current_height = 0
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Standardna logika (več kitic na stran, če grejo, upoštevajoč odstavke)
|
||||||
|
for para in stanza_paragraphs:
|
||||||
|
para_height = len(para) * self.line_height
|
||||||
|
|
||||||
|
# Preverimo, če odstavek gre na trenutno stran
|
||||||
|
# (self.line_height if current_page_lines else 0) upošteva prazno vrstico pred odstavkom
|
||||||
|
if current_height + para_height + (self.line_height if current_page_lines else 0) > max_height:
|
||||||
|
if current_page_lines:
|
||||||
|
pages.append("\n".join(current_page_lines))
|
||||||
|
current_page_lines = []
|
||||||
|
current_height = 0
|
||||||
|
|
||||||
|
# Če je sam odstavek predolg za eno stran
|
||||||
|
if para_height > max_height:
|
||||||
|
for line in para:
|
||||||
|
if current_height + self.line_height > max_height:
|
||||||
|
pages.append("\n".join(current_page_lines))
|
||||||
|
current_page_lines = [line]
|
||||||
|
current_height = self.line_height
|
||||||
|
else:
|
||||||
|
current_page_lines.append(line)
|
||||||
|
current_height += self.line_height
|
||||||
|
else:
|
||||||
|
current_page_lines = para[:]
|
||||||
|
current_height = para_height
|
||||||
|
else:
|
||||||
|
if current_page_lines:
|
||||||
|
current_page_lines.append("")
|
||||||
|
current_height += self.line_height
|
||||||
|
current_page_lines.extend(para)
|
||||||
|
current_height += para_height
|
||||||
|
|
||||||
if current_page_lines:
|
if current_page_lines:
|
||||||
pages.append("\n".join(current_page_lines))
|
pages.append("\n".join(current_page_lines))
|
||||||
|
|||||||
@@ -533,6 +533,31 @@ textarea.form-control {
|
|||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.about-codes-section {
|
||||||
|
text-align: left;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.about-codes-section h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #1f8a46;
|
||||||
|
}
|
||||||
|
|
||||||
|
.about-codes-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.about-codes-list li {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
background-color: #1f8a46;
|
background-color: #1f8a46;
|
||||||
color: white;
|
color: white;
|
||||||
|
|||||||
@@ -95,6 +95,17 @@
|
|||||||
<h3>Avtorji:</h3>
|
<h3>Avtorji:</h3>
|
||||||
<ul id="about-authors" class="about-authors-list"></ul>
|
<ul id="about-authors" class="about-authors-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="about-codes-section">
|
||||||
|
<h3>Posebne kode:</h3>
|
||||||
|
<ul class="about-codes-list">
|
||||||
|
<li><strong>9999</strong>: Izklop računalnika</li>
|
||||||
|
<li><strong>9998</strong>: Ponovni zagon računalnika</li>
|
||||||
|
<li><strong>9997</strong>: Ponovni zagon programa</li>
|
||||||
|
<li><strong>9988</strong>: Izhod iz programa</li>
|
||||||
|
<li><strong>9901</strong>: Posodobitev baze pesmi</li>
|
||||||
|
<li><strong>9900</strong>: Informacije o programu</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="about-close-btn" class="btn-primary">Zapri</button>
|
<button id="about-close-btn" class="btn-primary">Zapri</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user