Feature: Add cards to library via search view
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
# Title of the Program Window
|
||||
import os
|
||||
from gi.repository import Gdk
|
||||
|
||||
# Title of the Program Window
|
||||
application_title= "MTG Collector (working title) v0.1"
|
||||
|
||||
# Path of image cache
|
||||
cache_path= os.path.dirname(__file__) + "/.cache/"
|
||||
image_cache_path=os.path.dirname(__file__) + "/.cache/images/"
|
||||
|
||||
# Colors to use in the Application
|
||||
green_color = Gdk.color_parse('#87ff89')
|
||||
red_color = Gdk.color_parse('#ff6d6d')
|
||||
|
||||
# When True Search view will list a card multiple times for each set they appear in
|
||||
show_from_all_sets=False
|
||||
@@ -12,7 +12,7 @@ class DetailBar(Gtk.ScrolledWindow):
|
||||
self.add(self.grid)
|
||||
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||
|
||||
# Create area for big card an fill it with a dummy image
|
||||
# Create area for big card
|
||||
self.image_area = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
|
||||
self.bigcard = Gtk.Image()
|
||||
pixbuf = util.load_dummy_image(63 * 5, 88 * 5)
|
||||
@@ -67,8 +67,6 @@ class DetailBar(Gtk.ScrolledWindow):
|
||||
self.rulesstore.clear()
|
||||
|
||||
def set_card_detail(self, card):
|
||||
print("Loading infos for \"" + card.name + "\"")
|
||||
|
||||
self.update_big_card(card)
|
||||
self.rulesstore.clear()
|
||||
self.rulingslabel.set_visible(False)
|
||||
|
||||
@@ -13,6 +13,13 @@ class MainWindow(Gtk.Window):
|
||||
self.set_border_width(2)
|
||||
self.set_size_request(1000, 700)
|
||||
|
||||
self.status_bar = Gtk.Statusbar()
|
||||
self.status_bar.set_no_show_all(True)
|
||||
|
||||
# Set reference to status bar in util
|
||||
util.status_bar = self.status_bar
|
||||
util.push_status("Application started")
|
||||
|
||||
# Load local image Data
|
||||
util.reload_image_cache()
|
||||
util.load_mana_icons()
|
||||
@@ -20,31 +27,53 @@ class MainWindow(Gtk.Window):
|
||||
util.window = self
|
||||
|
||||
util.load_sets()
|
||||
|
||||
self.status_bar = Gtk.Statusbar()
|
||||
self.status_bar.set_no_show_all(True)
|
||||
util.load_library()
|
||||
|
||||
self.notebook = Gtk.Notebook()
|
||||
|
||||
# region Menu Bar
|
||||
|
||||
mb_main = Gtk.Menu()
|
||||
mb_lib = Gtk.Menu()
|
||||
|
||||
self.menu_import = Gtk.MenuItem("Import Library")
|
||||
self.menu_export = Gtk.MenuItem("Export Library")
|
||||
self.menu_quit = Gtk.ImageMenuItem('Quit', Gtk.Image.new_from_icon_name(Gtk.STOCK_QUIT, 0))
|
||||
self.menu_quit.connect("activate", Gtk.main_quit)
|
||||
|
||||
self.lib_save = Gtk.ImageMenuItem("Save", Gtk.Image.new_from_icon_name(Gtk.STOCK_SAVE, 0))
|
||||
self.lib_save.connect("activate", self.mb_save_lib)
|
||||
self.lib_debug_print = Gtk.MenuItem("DEBUG: Print Library")
|
||||
self.lib_debug_print.connect("activate", util.print_lib)
|
||||
|
||||
mb_main.append(self.menu_import)
|
||||
mb_main.append(self.menu_export)
|
||||
mb_main.append(Gtk.SeparatorMenuItem())
|
||||
mb_main.append(self.menu_quit)
|
||||
|
||||
mb_lib.append(self.lib_save)
|
||||
mb_lib.append(self.lib_debug_print)
|
||||
|
||||
root_menu_main = Gtk.MenuItem("Main")
|
||||
root_menu_main.set_submenu(mb_main)
|
||||
|
||||
root_menu_lib = Gtk.MenuItem("Library")
|
||||
root_menu_lib.set_submenu(mb_lib)
|
||||
|
||||
mb = Gtk.MenuBar()
|
||||
mb.append(root_menu_main)
|
||||
mb.append(root_menu_lib)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Accelerators
|
||||
|
||||
accelgrp = Gtk.AccelGroup()
|
||||
|
||||
key, mod = Gtk.accelerator_parse("<Control>Q")
|
||||
self.menu_quit.add_accelerator("activate", accelgrp, key, mod, Gtk.AccelFlags.VISIBLE)
|
||||
|
||||
self.add_accel_group(accelgrp)
|
||||
|
||||
# endregion
|
||||
|
||||
@@ -53,10 +82,6 @@ class MainWindow(Gtk.Window):
|
||||
vbox.pack_start(self.notebook, True, True, 0)
|
||||
vbox.pack_start(self.status_bar, False, False, 0)
|
||||
|
||||
# Set reference to status bar in util
|
||||
util.status_bar = self.status_bar
|
||||
util.push_status("Application started")
|
||||
|
||||
self.collectionView = Gtk.Box()
|
||||
self.collectionView.add(collection.CollectionView())
|
||||
|
||||
@@ -72,6 +97,8 @@ class MainWindow(Gtk.Window):
|
||||
|
||||
self.add(vbox)
|
||||
|
||||
def mb_save_lib(self, menu_item):
|
||||
util.save_library()
|
||||
|
||||
win = MainWindow()
|
||||
win.connect('delete-event', Gtk.main_quit)
|
||||
|
||||
@@ -16,6 +16,7 @@ class SearchView(Gtk.Grid):
|
||||
def __init__(self):
|
||||
Gtk.Grid.__init__(self)
|
||||
self.set_column_spacing(5)
|
||||
self.current_card = None
|
||||
|
||||
# region Search Box
|
||||
self.searchbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5,
|
||||
@@ -178,6 +179,12 @@ class SearchView(Gtk.Grid):
|
||||
|
||||
# Detail View for selected Card
|
||||
self.details = details.DetailBar()
|
||||
|
||||
# Button to add to library
|
||||
self.add_delete_button = Gtk.Button()
|
||||
self.add_delete_button.set_no_show_all(True)
|
||||
self.add_delete_button.connect("clicked", self.on_add_delete)
|
||||
|
||||
# Bring it all together
|
||||
left_pane = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
left_pane.pack_start(self.searchbox, False, False, 0)
|
||||
@@ -193,6 +200,8 @@ class SearchView(Gtk.Grid):
|
||||
self.attach(Gtk.VSeparator(), 3, 0, 1, 1)
|
||||
# Details
|
||||
self.attach(self.details, 4, 0, 1, 1)
|
||||
# Add/delete Button
|
||||
self.attach(self.add_delete_button, 4, 1, 1, 1)
|
||||
|
||||
self.selection = self.list.get_selection()
|
||||
self.selection.connect("changed", self.on_card_selected)
|
||||
@@ -201,11 +210,24 @@ class SearchView(Gtk.Grid):
|
||||
|
||||
# region UI Events
|
||||
|
||||
def on_add_delete(self, button):
|
||||
if util.library.__contains__(self.current_card.multiverse_id):
|
||||
util.remove_card_from_lib(self.current_card)
|
||||
print(self.current_card.name + " removed to library")
|
||||
else:
|
||||
util.add_card_to_lib(self.current_card)
|
||||
print(self.current_card.name + " added to library")
|
||||
self._do_update_add_button()
|
||||
|
||||
def online_search_clicked(self, button):
|
||||
# Clear old data from liststore
|
||||
self.store.clear()
|
||||
# Reset details pane
|
||||
self.details.reset()
|
||||
# Reset selected card
|
||||
self.current_card = None
|
||||
# Hide Add delete button
|
||||
self.add_delete_button.set_visible(False)
|
||||
# Define the function to load cards in a seperate thread, so the UI is not blocked
|
||||
self.loadthread = threading.Thread(target=self.load_cards)
|
||||
# Deamonize Thread so it tops if the main thread exits
|
||||
@@ -235,6 +257,10 @@ class SearchView(Gtk.Grid):
|
||||
selected_card = card
|
||||
if selected_card is not None:
|
||||
self.details.set_card_detail(selected_card)
|
||||
self.current_card = selected_card
|
||||
|
||||
self.add_delete_button.set_visible(True)
|
||||
self._do_update_add_button()
|
||||
|
||||
# endregion
|
||||
|
||||
@@ -332,6 +358,14 @@ class SearchView(Gtk.Grid):
|
||||
|
||||
# region Private Functions
|
||||
|
||||
def _do_update_add_button(self):
|
||||
if not util.library.__contains__(self.current_card.multiverse_id):
|
||||
self.add_delete_button.set_label("Add to Library")
|
||||
self.add_delete_button.modify_bg(Gtk.StateType.NORMAL, config.green_color)
|
||||
else:
|
||||
self.add_delete_button.set_label("Remove from Library")
|
||||
self.add_delete_button.modify_bg(Gtk.StateType.NORMAL, config.red_color)
|
||||
|
||||
def _match_selected(self, completion, model, iter):
|
||||
self.set_combo.set_active_iter(iter)
|
||||
|
||||
|
||||
@@ -8,18 +8,69 @@ import network
|
||||
from gi.repository import GdkPixbuf, Gtk
|
||||
from PIL import Image as PImage
|
||||
from urllib import request
|
||||
from mtgsdk import Card
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
# Locally stored images for faster loading times
|
||||
imagecache = []
|
||||
manaicons = {}
|
||||
|
||||
#Card library object
|
||||
library = {}
|
||||
|
||||
set_list = []
|
||||
|
||||
window = None
|
||||
status_bar = None
|
||||
|
||||
|
||||
def add_card_to_lib(card):
|
||||
library[card.multiverse_id] = card
|
||||
|
||||
|
||||
def remove_card_from_lib(card):
|
||||
del library[card.multiverse_id]
|
||||
|
||||
|
||||
def print_lib(menuItem):
|
||||
print("Printing library:\n")
|
||||
counter = 1
|
||||
for card_id, card in library.items():
|
||||
print(str(counter) + ": " + card.name + " (" + str(card_id) + ")")
|
||||
counter += 1
|
||||
print("\nDone.")
|
||||
|
||||
|
||||
def save_library():
|
||||
if not os.path.exists(config.cache_path):
|
||||
os.makedirs(config.cache_path)
|
||||
path = config.cache_path + "library"
|
||||
# Serialize library object using pickle
|
||||
try:
|
||||
pickle.dump(library, open(path, 'wb'))
|
||||
push_status("Library saved.")
|
||||
print("Library saved")
|
||||
except:
|
||||
show_message("Error", "Error while saving library to disk")
|
||||
|
||||
|
||||
def load_library():
|
||||
path = config.cache_path + "library"
|
||||
library.clear()
|
||||
if os.path.isfile(path):
|
||||
# Deserialize using pickle
|
||||
try:
|
||||
library_loaded = pickle.load(open(path, 'rb'))
|
||||
for id, card in library_loaded.items():
|
||||
library[id] = card
|
||||
push_status("Library loaded.")
|
||||
except :
|
||||
show_message("Error", "Error while loading library from disk")
|
||||
else:
|
||||
save_library()
|
||||
print("No library file found on disk, created new one")
|
||||
|
||||
|
||||
def load_sets():
|
||||
path = config.cache_path + "sets"
|
||||
if not os.path.isfile(path):
|
||||
@@ -29,9 +80,9 @@ def load_sets():
|
||||
show_message("API Error", "Could not retrieve Set infos")
|
||||
return
|
||||
# Serialize the loaded data to a file
|
||||
pickle.dump(new_sets, open(config.cache_path + "sets", 'wb'))
|
||||
pickle.dump(new_sets, open(path, 'wb'))
|
||||
# Deserialize set data from local file
|
||||
sets = pickle.load(open(config.cache_path + "sets", 'rb'))
|
||||
sets = pickle.load(open(path, 'rb'))
|
||||
# Sort the loaded sets based on the sets name
|
||||
for set in sorted(sets, key=lambda x: x.name):
|
||||
set_list.append(set)
|
||||
|
||||
Reference in New Issue
Block a user