learn-hieroglyphs/src/ui/cards/game/imp.rs

136 lines
4.4 KiB
Rust

use std::cell::RefCell;
use crate::card::Card;
use crate::db::{get_db_path, get_images_store_path};
use crate::widgets::card_display::*;
use glib::subclass::InitializingObject;
use gtk::glib::clone;
use gtk::subclass::prelude::*;
use gtk::{glib, Box, Button, CompositeTemplate, Label};
use gtk::{prelude::*, Entry};
use rusqlite::Connection;
#[derive(CompositeTemplate, Default)]
#[template(resource = "/org/foxarmy/learn-hieroglyph/cards/game/ui.xml")]
pub struct MemoryCardsGameScene {
#[template_child]
pub card_display: TemplateChild<CardDisplay>,
#[template_child]
pub stats_label: TemplateChild<Label>,
#[template_child]
pub content: TemplateChild<Box>,
#[template_child]
pub no_cards_label: TemplateChild<Label>,
#[template_child]
pub back_button: TemplateChild<Button>,
pub correct: RefCell<usize>,
pub incorrect: RefCell<usize>,
}
#[glib::object_subclass]
impl ObjectSubclass for MemoryCardsGameScene {
const NAME: &'static str = "MemoryCardsGameScene";
type Type = super::MemoryCardsGameScene;
type ParentType = gtk::ApplicationWindow;
fn class_init(klass: &mut Self::Class) {
klass.bind_template();
}
fn instance_init(obj: &InitializingObject<Self>) {
obj.init_template();
}
}
impl ObjectImpl for MemoryCardsGameScene {
fn constructed(&self) {
self.parent_constructed();
let card_display_binding = self.card_display.imp().obj();
let self_binding = self.obj();
self.update_card();
card_display_binding.get_answer_entry().connect_activate(clone!(@strong card_display_binding, @strong self_binding => move |e: &Entry| {
card_display_binding.imp().incorrect_message.set_visible(false);
let incorrect_message_label = &card_display_binding.imp().incorrect_message;
if e.text() == *card_display_binding.hieroglyph() {
*self_binding.imp().correct.borrow_mut() += 1;
incorrect_message_label.set_visible(false);
} else {
*self_binding.imp().incorrect.borrow_mut() +=1;
incorrect_message_label.set_visible(true);
let message = format!("Incorrect! It was {} reading as {} with meaning {}", card_display_binding.hieroglyph(), card_display_binding.reading(), card_display_binding.translation());
incorrect_message_label.set_label(&message);
}
self_binding.update_stats();
self_binding.imp().update_card();
e.set_text("");
}));
}
}
impl MemoryCardsGameScene {
pub fn update_card(&self) {
match generate_card() {
Some(card) => {
self.card_display.set_imagepath(card.imagepath());
self.card_display.set_hieroglyph(card.hieroglyph());
self.card_display.set_reading(card.reading());
self.card_display.set_translation(card.translation());
self.card_display.update_file_for_image();
self.obj().hide_no_cards_msg();
}
None => self.obj().show_no_cards_msg(),
}
}
}
fn generate_card() -> Option<CardDisplay> {
let connection = Connection::open(get_db_path()).unwrap();
let mut stmt = connection.prepare("SELECT imagename, hieroglyph, reading, translation FROM cards WHERE is_learning = TRUE ORDER BY RANDOM() LIMIT 1").unwrap();
let random_card_iter = stmt
.query_map((), |row| {
Ok(Card::new(
row.get(0).unwrap(),
row.get(1).unwrap(),
row.get(2).unwrap(),
row.get(3).unwrap(),
Some(true),
))
})
.unwrap();
let mut random_card = None;
for i in random_card_iter {
random_card = Some(i.unwrap());
}
let random_card: Card = match random_card {
Some(card) => card,
None => return None,
};
let generated_card = CardDisplay::new(
&(get_images_store_path()
+ "/"
+ match &random_card.image_path() {
Some(path) => path,
None => return None,
}),
&random_card.hieroglyph().unwrap(),
Some(&random_card.reading().unwrap()),
&random_card.translation().unwrap(),
);
Some(generated_card)
}
impl WidgetImpl for MemoryCardsGameScene {}
impl WindowImpl for MemoryCardsGameScene {}
impl ApplicationWindowImpl for MemoryCardsGameScene {}