Add character and remove character via button

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
This commit is contained in:
TheJackiMonster 2022-10-21 01:31:16 +02:00
parent 2aa65fc815
commit 29fbe2acbb
No known key found for this signature in database
GPG key ID: D850A5F772E880F9
6 changed files with 111 additions and 23 deletions

View file

@ -8,6 +8,7 @@ from manuskript.data.color import Color
from manuskript.data.importance import Importance
from manuskript.data.unique_id import UniqueIDHost
from manuskript.io.mmdFile import MmdFile
from manuskript.util import safeFilename
class Character:
@ -34,6 +35,12 @@ class Character:
def allowPOV(self) -> bool:
return True if self.POV is None else self.POV
def remove(self):
if self.UID is None:
return
self.characters.removeByID(self.UID.value)
@classmethod
def loadAttribute(cls, metadata: dict, name: str, defaultValue=None):
if name in metadata:
@ -104,14 +111,37 @@ class Characters:
def __iter__(self):
return self.data.values().__iter__()
def add(self, name: str = None) -> Character | None:
if name is None:
name = "New character"
UID = self.host.newID()
filename = safeFilename("%s-%s" % (str(UID), name), "txt")
path = os.path.join(self.dir_path, filename)
if os.path.exists(filename):
return None
character = Character(path, self)
character.UID = UID
character.name = name
self.data[character.UID.value] = character
return character
def getByID(self, ID: int) -> Character:
return self.data.get(ID, None)
def removeByID(self, ID: int):
self.data.pop(ID)
def load(self):
self.data.clear()
for name in os.listdir(self.dir_path):
path = os.path.join(self.dir_path, name)
for filename in os.listdir(self.dir_path):
path = os.path.join(self.dir_path, filename)
if not os.path.isfile(path):
continue

View file

@ -19,6 +19,9 @@ class Color:
@classmethod
def parse(cls, string: str):
if string is None:
return None
colorPattern = re.compile(r"\#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})")
m = colorPattern.match(string)

View file

@ -12,19 +12,16 @@ from manuskript.data import Color
def rgbaFromColor(color: Color) -> Gdk.RGBA:
rgba = Gdk.RGBA()
rgba.red = color.red / 255.
rgba.green = color.green / 255.
rgba.blue = color.blue / 255.
rgba.red = 0 if color is None else color.red / 255.
rgba.green = 0 if color is None else color.green / 255.
rgba.blue = 0 if color is None else color.blue / 255.
rgba.alpha = 1.
return rgba
def pixbufFromColor(color: Color) -> GdkPixbuf:
if color is None:
return None
pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, 16, 16)
pixbuf.fill(color.getRGB())
pixbuf.fill(0 if color is None else color.getRGB())
return pixbuf

View file

@ -23,17 +23,7 @@ class CharactersView:
self.widget = builder.get_object("characters_view")
self.charactersStore = builder.get_object("characters_store")
for character in self.characters:
tree_iter = self.charactersStore.append()
if tree_iter is None:
continue
self.charactersStore.set_value(tree_iter, 0, character.UID.value)
self.charactersStore.set_value(tree_iter, 1, validString(character.name))
self.charactersStore.set_value(tree_iter, 2, pixbufFromColor(character.color))
self.charactersStore.set_value(tree_iter, 3, Importance.asValue(character.importance))
self.refreshCharacterStore()
self.mainCharactersStore = builder.get_object("main_characters_store")
self.secondaryCharactersStore = builder.get_object("secondary_characters_store")
@ -56,6 +46,16 @@ class CharactersView:
for selection in self.characterSelections:
selection.connect("changed", self.characterSelectionChanged)
self.addCharacterButton = builder.get_object("add_character")
self.removeCharacterButton = builder.get_object("remove_character")
self.filterCharactersBuffer = builder.get_object("filter_characters")
self.addCharacterButton.connect("clicked", self.addCharacterClicked)
self.removeCharacterButton.connect("clicked", self.removeCharacterClicked)
self.filterCharactersBuffer.connect("deleted-text", self.filterCharactersDeletedText)
self.filterCharactersBuffer.connect("inserted-text", self.filterCharactersInsertedText)
self.colorButton = builder.get_object("color")
self.importanceCombo = builder.get_object("importance")
self.allowPOVCheck = builder.get_object("allow_POV")
@ -100,6 +100,20 @@ class CharactersView:
self.unloadCharacterData()
def refreshCharacterStore(self):
self.charactersStore.clear()
for character in self.characters:
tree_iter = self.charactersStore.append()
if tree_iter is None:
continue
self.charactersStore.set_value(tree_iter, 0, character.UID.value)
self.charactersStore.set_value(tree_iter, 1, validString(character.name))
self.charactersStore.set_value(tree_iter, 2, pixbufFromColor(character.color))
self.charactersStore.set_value(tree_iter, 3, Importance.asValue(character.importance))
def loadCharacterData(self, character: Character):
self.character = None
@ -166,6 +180,30 @@ class CharactersView:
else:
self.loadCharacterData(character)
def addCharacterClicked(self, button: Gtk.Button):
character = self.characters.add()
if character is None:
return
self.refreshCharacterStore()
def removeCharacterClicked(self, button: Gtk.Button):
if self.character is None:
return
self.character.remove()
self.refreshCharacterStore()
def filterCharactersChanged(self, buffer: Gtk.EntryBuffer):
pass
def filterCharactersDeletedText(self, buffer: Gtk.EntryBuffer, position: int, n_chars: int):
self.filterCharactersChanged(buffer)
def filterCharactersInsertedText(self, buffer: Gtk.EntryBuffer, position: int, chars: str, n_chars: int):
self.filterCharactersChanged(buffer)
def colorSet(self, button: Gtk.ColorButton):
if self.character is None:
return

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
from manuskript.util.counter import CharCounter, WordCounter, PageCounter
@ -28,3 +29,20 @@ def validInt(invalid: int) -> int:
def invalidInt(valid: int) -> int:
return None if valid == 0 else valid
def safeFilename(filename: str, extension: str = None) -> str:
if extension is not None:
filename = "%s.%s" % (filename, extension)
name = filename.encode('ascii', 'replace').decode('ascii')
filenamesToAvoid = list(["CON", "PRN", "AUX", "NUL"])
for i in range(1, 9):
filenamesToAvoid.append("COM" + str(i))
filenamesToAvoid.append("LPT" + str(i))
if name.upper() in filenamesToAvoid:
name = "_" + name
return re.sub(r"[^a-zA-Z0-9._\-+()]", "_", name)

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2
<!-- Generated with glade 3.40.0
Copyright (C) 2015-2021 Olivier Keshavjee et al.
@ -56,6 +56,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</columns>
</object>
<object class="GtkTextBuffer" id="epiphany"/>
<object class="GtkEntryBuffer" id="filter_characters"/>
<object class="GtkTextBuffer" id="goal"/>
<object class="GtkListStore" id="importance_store">
<columns>
@ -274,7 +275,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<property name="margin-bottom">8</property>
<property name="spacing">4</property>
<child>
<object class="GtkButton">
<object class="GtkButton" id="add_character">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
@ -293,7 +294,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
</packing>
</child>
<child>
<object class="GtkButton">
<object class="GtkButton" id="remove_character">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
@ -315,6 +316,7 @@ along with Manuskript. If not, see <http://www.gnu.org/licenses/>.
<object class="GtkEntry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="buffer">filter_characters</property>
<property name="placeholder-text" translatable="yes">Filter</property>
</object>
<packing>