Set up the game review page along with #229
|
@ -16,20 +16,22 @@ You should have received a copy of the GNU General Public License along with On
|
|||
|
||||
use crate::CoreApi;
|
||||
use adw::prelude::*;
|
||||
use async_std::task::{block_on, spawn};
|
||||
|
||||
use otg_core::{
|
||||
settings::{SettingsRequest, SettingsResponse},
|
||||
Config, CoreRequest, CoreResponse,
|
||||
CoreRequest, CoreResponse,
|
||||
};
|
||||
use sgf::GameRecord;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use crate::views::{GameReview, HomeView, SettingsView};
|
||||
|
||||
/*
|
||||
#[derive(Clone)]
|
||||
enum AppView {
|
||||
Home,
|
||||
}
|
||||
*/
|
||||
|
||||
// An application window should generally contain
|
||||
// - an overlay widget
|
||||
|
@ -46,7 +48,7 @@ pub struct AppWindow {
|
|||
// we can maintain the state of previous views. Since the two of these work together, they are
|
||||
// a candidate for extraction into a new widget or a new struct.
|
||||
stack: adw::NavigationView,
|
||||
view_states: Vec<AppView>,
|
||||
// view_states: Vec<AppView>,
|
||||
|
||||
// Overlays are for transient content, such as about and settings, which can be accessed from
|
||||
// anywhere but shouldn't be part of the main application flow.
|
||||
|
@ -63,7 +65,7 @@ impl AppWindow {
|
|||
let window = Self::setup_window(app);
|
||||
let overlay = Self::setup_overlay();
|
||||
let stack = adw::NavigationView::new();
|
||||
let view_states = vec![];
|
||||
// let view_states = vec![];
|
||||
|
||||
window.set_content(Some(&overlay));
|
||||
overlay.set_child(Some(&stack));
|
||||
|
@ -71,7 +73,7 @@ impl AppWindow {
|
|||
let s = Self {
|
||||
window,
|
||||
stack,
|
||||
view_states,
|
||||
// view_states,
|
||||
overlay,
|
||||
core,
|
||||
settings_view_model: Default::default(),
|
||||
|
@ -79,7 +81,7 @@ impl AppWindow {
|
|||
|
||||
let home = s.setup_home();
|
||||
|
||||
let _ = s.stack.push(&home);
|
||||
s.stack.push(&home);
|
||||
|
||||
s
|
||||
}
|
||||
|
@ -149,23 +151,18 @@ impl AppWindow {
|
|||
|
||||
pub fn close_overlay(&self) {
|
||||
let mut view = self.settings_view_model.write().unwrap();
|
||||
match *view {
|
||||
Some(ref mut settings) => {
|
||||
self.overlay.remove_overlay(settings);
|
||||
*view = None;
|
||||
}
|
||||
None => {}
|
||||
if let Some(ref mut settings) = *view {
|
||||
self.overlay.remove_overlay(settings);
|
||||
*view = None;
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_window(app: &adw::Application) -> adw::ApplicationWindow {
|
||||
let window = adw::ApplicationWindow::builder()
|
||||
adw::ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.width_request(800)
|
||||
.height_request(500)
|
||||
.build();
|
||||
|
||||
window
|
||||
.build()
|
||||
}
|
||||
|
||||
fn setup_header() -> adw::HeaderBar {
|
||||
|
|
|
@ -36,16 +36,15 @@ You should have received a copy of the GNU General Public License along with On
|
|||
// that.
|
||||
|
||||
use crate::perftrace;
|
||||
use gio::resources_lookup_data;
|
||||
|
||||
use glib::Object;
|
||||
use gtk::{
|
||||
gdk_pixbuf::{InterpType, Pixbuf},
|
||||
prelude::*,
|
||||
subclass::prelude::*,
|
||||
};
|
||||
use image::io::Reader as ImageReader;
|
||||
|
||||
use otg_core::{Color, Coordinate};
|
||||
use std::{cell::RefCell, io::Cursor, rc::Rc};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
const WIDTH: i32 = 800;
|
||||
const HEIGHT: i32 = 800;
|
||||
|
@ -241,6 +240,7 @@ impl Pen {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn ghost_stone(&self, context: &cairo::Context, row: u8, col: u8, color: Color) {
|
||||
match color {
|
||||
Color::White => context.set_source_rgba(0.9, 0.9, 0.9, 0.5),
|
||||
|
|
|
@ -18,14 +18,13 @@ use cairo::Context;
|
|||
use glib::Object;
|
||||
use gtk::{prelude::*, subclass::prelude::*};
|
||||
use sgf::{GameNode, GameRecord};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
const WIDTH: i32 = 200;
|
||||
const HEIGHT: i32 = 800;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ReviewTreePrivate {
|
||||
record: Rc<RefCell<Option<GameRecord>>>,
|
||||
// record: Rc<RefCell<Option<GameRecord>>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -44,7 +43,7 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
impl ReviewTree {
|
||||
pub fn new(record: GameRecord) -> Self {
|
||||
pub fn new(_record: GameRecord) -> Self {
|
||||
let s: Self = Object::new();
|
||||
|
||||
s.set_width_request(WIDTH);
|
||||
|
@ -60,7 +59,7 @@ impl ReviewTree {
|
|||
s
|
||||
}
|
||||
|
||||
pub fn redraw(&self, ctx: &Context, width: i32, height: i32) {
|
||||
pub fn redraw(&self, _ctx: &Context, _width: i32, _height: i32) {
|
||||
// Implement the tree-drawing algorithm here
|
||||
}
|
||||
}
|
||||
|
@ -113,13 +112,14 @@ struct Tree {
|
|||
// out if it has children that would overlap the children of the first node.
|
||||
//
|
||||
// My algorithm right now is likely to generate unnecessarily wide trees in a complex game review.
|
||||
#[allow(dead_code)]
|
||||
fn node_width(node: &GameNode) -> usize {
|
||||
let children: &Vec<GameNode> = match node {
|
||||
GameNode::MoveNode(mn) => &mn.children,
|
||||
GameNode::SetupNode(sn) => &sn.children,
|
||||
};
|
||||
|
||||
if children.len() == 0 {
|
||||
if children.is_empty() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,8 @@ fn node_width(node: &GameNode) -> usize {
|
|||
//
|
||||
// Just having the node is greatly insufficient. I can get better results if I'm calculating the
|
||||
// position of its children.
|
||||
fn node_children_columns(node: &GameNode) -> Vec<usize> {
|
||||
#[allow(dead_code)]
|
||||
fn node_children_columns(_node: &GameNode) -> Vec<usize> {
|
||||
vec![0, 1, 2]
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ pub use app_window::AppWindow;
|
|||
|
||||
mod views;
|
||||
|
||||
use async_std::task::{spawn, yield_now};
|
||||
use async_std::task::{yield_now};
|
||||
use otg_core::{Core, Observable, CoreRequest, CoreResponse};
|
||||
use std::{rc::Rc, sync::Arc};
|
||||
use tokio::runtime::Runtime;
|
||||
use std::{rc::Rc};
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CoreApi {
|
||||
|
@ -51,6 +51,7 @@ where
|
|||
/// LocalObserver creates a task on the current thread which watches the specified observer for notifications and calls the handler function with each one.
|
||||
///
|
||||
/// The LocalObserver starts a task which listens for notifications during the constructor. When the observer goes out of scope, it will make a point of aborting the task. This combination means that anything which uses the observer can create it, hold on to a reference of it, and then drop it when done, and not have to do anything else with the observer object.
|
||||
#[allow(dead_code)]
|
||||
struct LocalObserver<T> {
|
||||
join_handle: glib::JoinHandle<()>,
|
||||
handler: Rc<dyn Fn(T)>,
|
||||
|
@ -61,6 +62,7 @@ impl<T: 'static> LocalObserver<T> {
|
|||
///
|
||||
/// observable -- any object which emits events
|
||||
/// handler -- a function which can process events
|
||||
#[allow(dead_code)]
|
||||
fn new(observable: &dyn Observable<T>, handler: impl Fn(T) + 'static) -> Self {
|
||||
let listener = observable.subscribe();
|
||||
let handler = Rc::new(handler);
|
||||
|
|
|
@ -4,17 +4,15 @@ use async_std::task::spawn;
|
|||
use gio::ActionEntry;
|
||||
use otg_core::{Config, ConfigOption, Core, CoreNotification, LibraryPath, Observable};
|
||||
use otg_gtk::{
|
||||
perftrace,
|
||||
// ui::{ConfigurationPage, Home, PlayingField},
|
||||
AppWindow,
|
||||
CoreApi,
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
|
||||
const APP_ID_DEV: &str = "com.luminescent-dreams.otg.dev";
|
||||
const APP_ID_PROD: &str = "com.luminescent-dreams.otg";
|
||||
|
||||
const RESOURCE_BASE_PATH: &str = "/com/luminescent-dreams/otg/";
|
||||
// const RESOURCE_BASE_PATH: &str = "/com/luminescent-dreams/otg/";
|
||||
|
||||
async fn handler(notifications: Receiver<CoreNotification>, app_id: String) {
|
||||
loop {
|
||||
|
@ -108,7 +106,7 @@ fn main() {
|
|||
APP_ID_PROD
|
||||
};
|
||||
|
||||
let config = load_config(&app_id);
|
||||
let config = load_config(app_id);
|
||||
|
||||
let core = Core::new(config.clone());
|
||||
|
||||
|
|
|
@ -28,13 +28,10 @@ use gtk::{prelude::*, subclass::prelude::*};
|
|||
use otg_core::Color;
|
||||
use sgf::GameRecord;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GameReviewPrivate {}
|
||||
|
||||
impl Default for GameReviewPrivate {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for GameReviewPrivate {
|
||||
|
@ -52,7 +49,7 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
impl GameReview {
|
||||
pub fn new(api: CoreApi, record: GameRecord) -> Self {
|
||||
pub fn new(_api: CoreApi, record: GameRecord) -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
|
||||
// It's actually really bad to be just throwing away errors. Panics make everyone unhappy.
|
||||
|
|
|
@ -22,7 +22,7 @@ use otg_core::{
|
|||
CoreRequest, CoreResponse,
|
||||
};
|
||||
use sgf::GameRecord;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
|
||||
/*
|
||||
struct PlayerDataEntryPrivate {
|
||||
|
@ -101,19 +101,13 @@ impl PlayerDataEntry {
|
|||
}
|
||||
*/
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct HomePrivate {
|
||||
// black_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
||||
// white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
||||
}
|
||||
|
||||
impl Default for HomePrivate {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// black_player: Rc::new(RefCell::new(None)),
|
||||
// white_player: Rc::new(RefCell::new(None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for HomePrivate {
|
||||
|
@ -158,7 +152,7 @@ impl HomeView {
|
|||
s.append(&new_game_button);
|
||||
*/
|
||||
|
||||
let library = Library::new(move |game| on_select_game(game));
|
||||
let library = Library::new(on_select_game);
|
||||
let library_view = gtk::ScrolledWindow::builder()
|
||||
.hscrollbar_policy(gtk::PolicyType::Never)
|
||||
.min_content_width(360)
|
||||
|
|
|
@ -14,11 +14,11 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License along with On the Grid. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{borrow::Cow, cell::RefCell, path::Path, rc::Rc};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use adw::prelude::*;
|
||||
use glib::Object;
|
||||
use gtk::{prelude::*, subclass::prelude::*};
|
||||
use gtk::{subclass::prelude::*};
|
||||
use otg_core::{Config, ConfigOption, LibraryPath};
|
||||
|
||||
fn library_chooser_row(
|
||||
|
@ -33,7 +33,7 @@ fn library_chooser_row(
|
|||
.valign(gtk::Align::Center)
|
||||
.build();
|
||||
|
||||
let parent = parent.clone();
|
||||
let _parent = parent.clone();
|
||||
|
||||
let library_row = adw::ActionRow::builder()
|
||||
.title("Library Path")
|
||||
|
|
Loading…
Reference in New Issue