diff --git a/cv_engine/engine.py b/cv_engine/engine.py index 3c11a68..bb99f97 100644 --- a/cv_engine/engine.py +++ b/cv_engine/engine.py @@ -45,6 +45,13 @@ class CardvaultEngine: card_id_list[card_id] = card_objects[card_id] return categories + def search_by_name(self, search_term): + """ Search database for cards witch contain the search string in their names + :param search_term: Part of a card name + :return: List of matched cards + """ + return self.database.card_search_by_name(search_term) + if __name__ == "__main__": engine = CardvaultEngine() diff --git a/cv_gtk3/gtk_util.py b/cv_gtk3/gtk_util.py index fb9a847..e76ed4d 100644 --- a/cv_gtk3/gtk_util.py +++ b/cv_gtk3/gtk_util.py @@ -16,6 +16,22 @@ class GTKUtilities: # Cache for combined mana cost icons precon_icon_cache = {} + @staticmethod + def load_icon_cache(path): + icons = {} + if not os.path.isdir(path): + os.mkdir(path) + files = os.listdir(path) + for file in files: + try: + pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(path, file)) + # Strip filename extension + icon_name = os.path.splitext(file)[0] + icons[icon_name] = pixbuf + except Exception as ex: + print('Error while loading icon file "{}"'.format(ex)) + return icons + @staticmethod def get_mana_icons(mana_string): """ Return the combined mana symbols for a mana string @@ -31,6 +47,9 @@ class GTKUtilities: except KeyError: icon = GTKUtilities.create_mana_icons(mana_string) GTKUtilities.precon_icon_cache[icon_name] = icon + # Scale icon for display + if icon: + icon = icon.scale_simple(icon.get_width() / 5, icon.get_height() / 5, GdkPixbuf.InterpType.HYPER) return icon @staticmethod @@ -42,11 +61,13 @@ class GTKUtilities: # Compute horizontal size for the final image size = len(glyphs) * 105 image = PImage.new("RGBA", (size, 105)) - for icon in glyphs: - x_pos = glyphs.index(icon) * 105 + for index, icon in enumerate(glyphs): + x_pos = index * 105 try: - loaded = GTKUtilities.mana_icons[icon] + # Try loading mana icon and converting to PIL.Image for combining + loaded = GTKUtilities.pixbuf_to_image(GTKUtilities.mana_icons[icon]) except KeyError: + print('Mana icon "{}" is not loaded.'.format(icon)) return image.paste(loaded, (x_pos, 0)) # Save pre build icon file @@ -54,8 +75,21 @@ class GTKUtilities: image.save(path) try: pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) - pixbuf = pixbuf.scale_simple(image.width / 5, image.height / 5, GdkPixbuf.InterpType.HYPER) except Exception as err: print(err) return - return pixbuf \ No newline at end of file + return pixbuf + + @staticmethod + def pixbuf_to_image(pix): + """Convert gdkpixbuf to PIL image""" + data = pix.get_pixels() + w = pix.props.width + h = pix.props.height + stride = pix.props.rowstride + mode = "RGB" + if pix.props.has_alpha: + mode = "RGBA" + im = PImage.frombytes(mode, (w, h), data, "raw", mode, stride) + + return im \ No newline at end of file diff --git a/cv_gtk3/gtkui.py b/cv_gtk3/gtkui.py index f7cefd6..a429ed7 100644 --- a/cv_gtk3/gtkui.py +++ b/cv_gtk3/gtkui.py @@ -4,11 +4,12 @@ import os gi.require_version('Gtk', '3.0') from gi.repository import Gtk -from cv_engine import engine +from cv_engine import engine, util from cv_gtk3.main_window import MainWindowFunctions from cv_gtk3.setting import GUISettings from cv_gtk3.signal_handlers import handlers +from cv_gtk3.gtk_util import GTKUtilities class CardvaultGTK(MainWindowFunctions): @@ -27,6 +28,16 @@ class CardvaultGTK(MainWindowFunctions): GUISettings.pages = { "search": self.ui.get_object("searchView"), } + # Verify that cache directories exist + if not os.path.isdir(util.EngineConfig.cache_path): + os.mkdir(util.EngineConfig.cache_path) + if not os.path.isdir(util.EngineConfig.icon_cache_path): + os.mkdir(util.EngineConfig.icon_cache_path) + # Load single mana icons + GTKUtilities.mana_icons = GTKUtilities.load_icon_cache(os.path.join(os.path.dirname(__file__), 'resources', + 'mana')) + # Load the the pre constructed icon cache + GTKUtilities.precon_icon_cache = GTKUtilities.load_icon_cache(util.EngineConfig.icon_cache_path) # Call constructor of superclasses MainWindowFunctions.__init__(self, self.ui) # Create Signal handlers and connect them to the UI diff --git a/cv_gtk3/gui/search.glade b/cv_gtk3/gui/search.glade index 8e0dfbf..f53c6a9 100644 --- a/cv_gtk3/gui/search.glade +++ b/cv_gtk3/gui/search.glade @@ -87,7 +87,7 @@ True True True - + False diff --git a/cv_gtk3/signal_handlers/search.py b/cv_gtk3/signal_handlers/search.py index acb3ede..f052abc 100644 --- a/cv_gtk3/signal_handlers/search.py +++ b/cv_gtk3/signal_handlers/search.py @@ -3,10 +3,12 @@ import os from cv_gtk3.card_view import CardView from cv_gtk3.setting import GUISettings +from cv_gtk3.gtkui import CardvaultGTK + class SearchPageHandlers: """ Class for handling Signals from the search page """ - def __init__(self, app): + def __init__(self, app: 'CardvaultGTK'): """ Constructor :param app: Reference to an CardvaultGTK object """ @@ -14,17 +16,26 @@ class SearchPageHandlers: # Build the card view overlay = self.app.ui.get_object("searchResults") - card_list = CardView(ui_file=os.path.join(GUISettings.glade_file_path, 'cardtree.glade'), filtered=False) - card_list.set_name("resultsScroller") + self.card_list = CardView(ui_file=os.path.join(GUISettings.glade_file_path, 'cardtree.glade'), filtered=False) + self.card_list.set_name("resultsScroller") # TODO Context menu for card view # card_list.tree.connect("row-activated", self.on_search_card_selected) # card_list.selection.connect("changed", self.on_search_selection_changed) - overlay.add(card_list) + overlay.add(self.card_list) overlay.add_overlay(self.app.ui.get_object("searchOverlay")) overlay.show_all() - def do_search_cards(self, *args): - pass + def do_search_cards(self, search_entry): + """ Search cards in database based on user input and display them in a card view + :param search_entry: Search entry widget + """ + search_term = search_entry.get_text() + results = self.app.engine.search_by_name(search_term) + self.card_list.update(results) + # Switch Overlay off and set info diaplay + self.app.ui.get_object("searchOverlay").set_visible(False) + self.app.ui.get_object("search_title_label").set_visible(True) + self.app.ui.get_object("search_title").set_text(search_term) @staticmethod def do_clear_mana_filter(button_grid):