Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
2020-06-27 22:30:50 +02:00
parent 00cdb4f995
commit 63da81daa8
11 changed files with 972 additions and 691 deletions

View File

@@ -6,38 +6,38 @@ use crate::{data::PolicyList, keys::*};
pub trait BaseState {
/// Navigates to the given entity.
fn navigate(&self, to: Entity, ctx: &mut Context) {
if let Some(old_focused_element) = ctx.window().get::<Global>("global").focused_widget {
let mut old_focused_element = ctx.get_widget(old_focused_element);
old_focused_element.set("focused", false);
old_focused_element.update_theme_by_state(false);
}
ctx.window().get_mut::<Global>("global").focused_widget = None;
ctx.widget().set("visibility", Visibility::Collapsed);
ctx.get_widget(to).set("visibility", Visibility::Visible);
if let Some(old_focused_element) = ctx.window().get::<Global>("global").focused_widget {
let mut old_focused_element = ctx.get_widget(old_focused_element);
old_focused_element.set("focused", false);
old_focused_element.update_theme_by_state(false);
}
ctx.window().get_mut::<Global>("global").focused_widget = None;
ctx.widget().set("visibility", Visibility::Collapsed);
ctx.get_widget(to).set("visibility", Visibility::Visible);
}
/// Fetches the text of a widget.
fn fetch_text(&self, ctx: &mut Context, entity: Entity) -> Option<String> {
let mut widget = ctx.get_widget(entity);
/// Get the text of a widget.
fn get_text(&self, ctx: &mut Context, entity: Entity) -> Option<String> {
let mut widget = ctx.get_widget(entity);
let entry = widget.get_mut::<String>("text");
if entry.is_empty() {
return None;
}
let entry = widget.get_mut::<String>("text");
if entry.is_empty() {
return None;
}
let copy = entry.to_string();
entry.clear();
Some(copy)
let copy = entry.to_string();
entry.clear();
Some(copy)
}
// Save the data.
fn save(&self, registry: &mut Registry, ctx: &mut Context) {
registry
.get::<Settings>("settings")
.save(
PROP_POLICY_LISTS,
ctx.widget().get::<PolicyList>(PROP_POLICY_LISTS),
)
.unwrap();
registry
.get::<Settings>("settings")
.save(
PROP_POLICY_LIST,
ctx.widget().get::<PolicyList>(PROP_POLICY_LIST),
)
.unwrap();
}
}

View File

@@ -3,8 +3,85 @@ use orbtk::prelude::*;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
/// An enumeration of valid policy codes
/// right now, only "AS" is used
#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum PolicyCode {
AS
}
impl Default for PolicyCode {
fn default() -> Self { PolicyCode::AS }
}
/// Status of a given policy data element (eg: active / inactive)
#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum Status {
Active,
Inactive
}
impl Default for Status {
fn default() -> Self { Status::Active }
}
/// A communication type describes possible classifications of customer calls.
/// If not selected, the default will be 'unclassified'.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmElement {
pub struct CommunicationType {
// Unfall, Bußgeldbescheid, Anhörung, Unfallflucht, Kaufvertrag,
// Vodafone, Kündigung, Lohn, Zeugnis, Nachbar, Vermieter, Rente, GdB, Verwaltungsrecht, Unterhalt, Geburt, Hochzeit
pub communication_id: String,
pub communication_name: String,
}
/// CSV Export
/// The structure elements are required for an export to a comma seperated text list.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct CsvExportRecord {
// policy_code => Versicherungsscheinnummer: "AS1234567890"
// policy_holder => Anrufer: "Vorname, Nachname"
// facts => Sachverhalt: "Kurzschilderung"
// harm_type => Schadensart: "harm_name (harm_id)"
// communication_type => Kommunikationszeichen: "(communication_name)"
// ra_hotline => RA_Hotline: Kanzlei Laqua, Kanzlei Buschbell, Kanzlei DAH, Kanzlei Hiedemann
// ivr_comment => Haftungs-/Deckungskommentar; #IVR (ggf. ergänzt um das Beratungsergebnis)
pub policy_code: String,
pub policy_number: u32,
pub policy_holder: String,
pub facts: String,
pub harm_type: String,
pub communication_name: String,
pub ra_hotline: String, // const "Kanzlei Hiedemann",
pub ivr_comment: String,
}
/// CSV Import
/// The structure elements provided as a comma seperated text list.
/// Referenz: ERG.txt -> 'DION VERS POLLFNR'
/// '1 AS 1515735810'
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct CsvImportRecord {
// dion => Allianz Dion: 1
// policy_code => Policy Typ: "AS"
// policy_number => Versicherungsscheinnummer: "1515735810"
pub dion: String,
pub policy_code: String,
pub policy_number: u32,
}
/// Harm data are list/collections of harm types. You may toggle them to an unselected state.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmData {
pub harm_data: Vec<HarmType>,
//pub name: String,
pub selected: bool
}
/// Harm types are destincted by a type code.
/// The type code represents the unique harm identifier, bound with a literal name.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmType {
// Schadenersatz-RS im Verkehrsbereich (RS112)
// Ordnungswidrigkeits-RS im Verkehrsbereich (RS122)
// Straf-RS im Verkehrsbereich (RS121)
@@ -15,158 +92,139 @@ pub struct HarmElement {
// Sozialgerichts-RS im Privatbereich (RS216)
// Rechtsschutz im Familien- und Erbrecht (RS217)
// Wagnis nicht versicherbar / versichert (RS999)
pub harm_id: String,
pub harm_name: String,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct HarmType {
pub harm_type: Vec<HarmElement>,
pub name: String,
pub selected: bool
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct CommunicationType {
// Unfall, Bußgeldbescheid, Anhörung, Unfallflucht, Kaufvertrag,
// Vodafone, Kündigung, Lohn, Zeugnis, Nachbar, Vermieter, Rente, GdB, Verwaltungsrecht, Unterhalt, Geburt, Hochzeit
pub communication_id: String,
pub communication_name: String,
}
/// CSV Export
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct CSVExport {
// policy_code => Versicherungsscheinnummer: "AS1234567890"
// policy_holder => Anrufer: "Vorname, Nachname"
// facts => Sachverhalt: "Kurzschilderung"
// harm_type => Schadensart: "harm_name (harm_id)"
// communication_type => Kommunikationszeichen: "(communication_name)"
// ra_hotline => RA_Hotline: Kanzlei Laqua, Kanzlei Buschbell, Kanzlei DAH, Kanzlei Hiedemann
// ivr_comment => Haftungs-/Deckungskommentar; #IVR (ggf. ergänzt um das Beratungsergebnis)
pub policy_id: String,
pub policy_number: u32,
pub policy_holder: String,
pub facts: String,
pub harm_type: String,
pub communication_name: String,
pub ra_hotline: String, // const "Kanzlei Hiedemann",
pub ivr_comment: String,
pub harm_name: String,
}
/// Structure used to verify a policy data element.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct PolicyCheck {
pub policy_id: String,
pub policy_check_number: String,
pub policy_number: String,
pub isvalid: bool
pub policy_number_valid: bool
}
// #[derive(Default, Clone, Debug, Serialize, Deserialize)]
// pub struct PolicyCheckList {
// pub title: String,
// pub list: Vec<PolicyCheck>
// }
// impl PolicyCheckList {
// pub fn new(title: impl Into<String>) -> Self {
// PolicyCheckList {
// title: title.into(),
// ..Default::default()
// }
// }
/// Structure collecting policy data elements
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct PolicyList {
pub policy_list: Vec<PolicyData>,
pub name: String,
pub policy_list: Vec<PolicyDataList>,
}
/// implements helper methods, that manage lists of policy data collections
impl PolicyList {
pub fn get(&self, index: usize) -> Option<&PolicyData> {
self.policy_list.get(index)
pub fn get(&self, index: usize) -> Option<&PolicyDataList> {
self.policy_list.get(index)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut PolicyData> {
self.policy_list.get_mut(index)
pub fn get_mut(&mut self, index: usize) -> Option<&mut PolicyDataList> {
self.policy_list.get_mut(index)
}
pub fn insert_front(&mut self, policy_list: PolicyData) {
self.policy_list.insert(0, policy_list);
pub fn insert_front(&mut self, policy_list: PolicyDataList) {
self.policy_list.insert(0, policy_list);
}
pub fn is_empty(&self) -> bool {
self.policy_list.is_empty()
self.policy_list.is_empty()
}
pub fn len(&self) -> usize {
self.policy_list.len()
self.policy_list.len()
}
pub fn push(&mut self, policy_list: PolicyData) {
self.policy_list.push(policy_list);
pub fn new(name: impl Into<String>) -> Self {
PolicyList {
name: name.into(),
..Default::default()
}
}
pub fn remove(&mut self, index: usize) -> PolicyData {
self.policy_list.remove(index)
pub fn push(&mut self, policy_list: PolicyDataList) {
self.policy_list.push(policy_list);
}
pub fn remove(&mut self, index: usize) -> PolicyDataList {
self.policy_list.remove(index)
}
}
// Valid policy codes are represented in this Enumeration
// right now, only "AS" is used
//enum PolicyCode {
// CodeName(String),
//}
/// Structure representing a policy data element.
/// Structure representing a policy data element
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct PolicyElement {
pub struct PolicyData {
// DION VERS POLLFNR
// 1 AS 1515735810
// DION: Allianz id => len = 1??
// VERS: policy_code => enum(AS; ??)
// POLLFNR: policy_number => len = 10
pub date_inserted: Option<NaiveDateTime>,
pub dion: u8,
// is String16 a better default-type?
pub policy_code: String,
pub policy_code: PolicyCode,
pub policy_number: u32,
pub date_inserted: Option<NaiveDateTime>,
pub isactive: bool
pub status: Status
}
/// Structure grouping valid policy data elements
/// Structure collects policy data elements.
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct PolicyData {
pub struct PolicyDataList {
pub date_valid_until: Option<NaiveDateTime>,
pub policy_elements: Vec<PolicyElement>,
pub policy_data: Vec<PolicyData>,
pub name: String,
pub selected: bool
}
/// implements the helper methods, to manage policy data collections.
impl PolicyData {
impl PolicyDataList {
pub fn new(name: impl Into<String>) -> Self {
// the new inserted element will be active by default
PolicyData {
date_valid_until: None,
name: name.into(),
selected: true,
..Default::default()
}
// the new inserted element will be active by default
PolicyDataList {
date_valid_until: None,
name: name.into(),
selected: true,
..Default::default()
}
}
pub fn push(&mut self, policy_element: PolicyElement) {
self.policy_elements.push(policy_element);
pub fn push(&mut self, policy_data: PolicyData) {
self.policy_data.push(policy_data);
}
pub fn insert_front(&mut self, policy_element: PolicyElement) {
self.policy_elements.insert(0, policy_element);
pub fn insert_front(&mut self, policy_data: PolicyData) {
self.policy_data.insert(0, policy_data);
}
pub fn remove(&mut self, index: usize) -> PolicyElement {
self.policy_elements.remove(index)
pub fn remove(&mut self, index: usize) -> PolicyData {
self.policy_data.remove(index)
}
pub fn get(&self, index: usize) -> Option<&PolicyElement> {
self.policy_elements.get(index)
pub fn get(&self, index: usize) -> Option<&PolicyData> {
self.policy_data.get(index)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut PolicyElement> {
self.policy_elements.get_mut(index)
pub fn get_mut(&mut self, index: usize) -> Option<&mut PolicyData> {
self.policy_data.get_mut(index)
}
pub fn len(&self) -> usize {
self.policy_elements.len()
self.policy_data.len()
}
pub fn is_empty(&self) -> bool {
self.policy_elements.is_empty()
self.policy_data.is_empty()
}
}

View File

@@ -14,28 +14,38 @@ pub static CLASS_TOP_BAR: &str = "top_bar";
pub static CLASS_TRANSPARENT: &str = "transparent";
pub static CLASS_SEPERATOR: &str = "seperator";
// DCES: Entity[id] => [Component1, .. , Component<n>] -> data or state
// Widget IDs (DCES: Entity[id] => [Component1, .. , Component<n>] -> data or state)
pub static ID_POLICY_CHECK_FORM: &str = "policy_check_form";
pub static ID_POLICY_CHECK_HEADER: &str = "policy_check_header";
//pub static ID_POLICY_CHECK_ITEMS_WIDGET: &str = "policy_check_items_widget";
pub static ID_POLICY_CHECK_LABEL_POLICY_NUMBER: &str = "policy_check_label_policy_number";
pub static ID_POLICY_CHECK_LABEL_RESULT: &str = "policy_check_label_result";
pub static ID_POLICY_CHECK_MENU_BUTTON: &str = "policy_check_menu_button";
pub static ID_POLICY_CHECK_MENU_CONTAINER: &str = "policy_check_menu_container";
pub static ID_POLICY_CHECK_MENU_TEXT_BLOCK: &str = "policy_check_menu_text_block";
pub static ID_POLICY_CHECK_RESULT: &str = "policy_check_result";
pub static ID_POLICY_CHECK_POLICY_NUMBER: &str = "policy_check_policy_number";
pub static ID_POLICY_CHECK_WIDGET: &str = "policy_check_widget";
pub static ID_POLICY_DATA_ADD_BUTTON: &str = "policy_data_add_button";
pub static ID_POLICY_DATA_ITEMS_WIDGET: &str = "policy_data_items_widget";
pub static ID_POLICY_DATA_TEXT_BOX: &str = "policy_data_text_box";
pub static ID_POLICY_LISTS_ADD_BUTTON: &str = "policy_lists_add_button";
pub static ID_POLICY_LISTS_ITEMS_WIDGET: &str = "policy_lists_items_widget";
pub static ID_POLICY_LISTS_TEXT_BOX: &str = "policy_list_text_box";
//pub static ID_POLICY_DATA_TEXT_BOX: &str = "policy_data_text_box";
pub static ID_POLICY_DATA_DATE_INSERTED: &str = "policy_data_date_inserted";
pub static ID_POLICY_DATA_DION: &str = "policy_data_dion";
pub static ID_POLICY_DATA_POLICY_CODE: &str = "policy_data_policy_code";
pub static ID_POLICY_DATA_POLICY_NUMBER: &str = "policy_data_policy_number";
pub static ID_POLICY_DATA_STATUS: &str = "policy_data_status";
pub static ID_POLICY_DATA_LIST_NAME: &str = "policy_data_list_name";
pub static ID_POLICY_LIST_ADD_BUTTON: &str = "policy_list_add_button";
pub static ID_POLICY_LIST_ITEMS_WIDGET: &str = "policy_list_items_widget";
pub static ID_POLICY_LIST_TEXT_BOX: &str = "policy_list_text_box";
// Component Values (Properties)
pub static PROP_POLICY_CHECK: &str = "policy_check";
pub static PROP_POLICY_CODE: &str = "policy_code";
pub static PROP_POLICY_ELEMENT: &str = "policy_element";
pub static PROP_POLICY_LISTS: &str = "policy_lists";
pub static PROP_POLICY_DATA: &str = "policy_data";
pub static PROP_POLICY_LISTS_COUNT: &str = "policy_lists_count";
pub static PROP_POLICY_CHECK_LIST: &str = "policy_check_list";
pub static PROP_POLICY_DATA_LIST: &str = "policy_data_list";
pub static PROP_POLICY_DATA_COUNT: &str = "policy_data_count";
pub static PROP_POLICY_LIST: &str = "policy_list";
pub static PROP_POLICY_LIST_COUNT: &str = "policy_list_count";

View File

@@ -19,38 +19,42 @@ pub mod policycheck_menu;
pub mod policylist_view;
pub mod policylist_state;
// manage policy data elements
pub mod policydata_view;
pub mod policydata_state;
//#[cfg(feature = "light-theme")]
static STYLESHEET: &'static str = include_str!("../resources/stylesheets/advotracker.css");
fn get_theme() -> ThemeValue {
//ThemeValue::create_from_css(LIGHT_THEME_EXTENSION_CSS)
ThemeValue::create_from_css(DEFAULT_THEME_CSS)
.extension_css(STYLESHEET)
.build()
.extension_css(STYLESHEET)
.build()
}
fn main() {
Application::from_name("rzerres.advotracker")
.window(move |ctx| {
Window::new()
//.title("OrbTk - Policyholder checker example")
.title("AdvoTracker - Versicherungsnummern")
.position((500.0, 100.0))
.size(640.0, 480.0)
.min_width(460.0)
.min_height(180.0)
.resizeable(true)
.theme(get_theme())
.child(main_view::MainView::new().build(ctx))
.build(ctx)
})
.run();
.window(move |ctx| {
Window::new()
//.title("OrbTk - Policyholder checker example")
.title("AdvoTracker - Versicherungsnummern")
.position((500.0, 100.0))
.size(640.0, 480.0)
.min_width(460.0)
.min_height(180.0)
.resizeable(true)
.theme(get_theme())
.child(main_view::MainView::new().build(ctx))
.build(ctx)
})
.run();
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
assert_eq!(2 + 2, 4);
}
}

View File

@@ -1,41 +1,59 @@
use orbtk::prelude::*;
use crate::policycheck_view::PolicyCheckView;
//data::PolicyList,
//policylist_view::PolicyListView,
//policy_view::PolicyDataView
use crate::{
data::{PolicyCheck, PolicyList, PolicyDataList},
policycheck_view::PolicyCheckView,
policylist_view::PolicyListView,
policydata_view::PolicyDataView
};
// use crate::{
// data::{PolicyList, PolicyData},
// //policycheck_view::*,
// //PolicyCheckView,
// //policylist_view::*,
// //PolicyListView,
// //policydata_view::*,
// //PolicyDataList
// };
widget!(MainView {
policy_list_count: usize,
policy_list: PolicyList,
policy_data_list: PolicyDataList,
policycheck_view: u32,
policylist_view: u32,
policy_view: u32
policydata_view: u32
});
impl Template for MainView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
let policycheck_view = PolicyCheckView::new()
//.policylist_view(id)
//.policylist_count(id)
.build(ctx);
/* let policylist_view = PolicyList::new()
.back_entity(policycheck_view.0)
.policydata_view(id)
.policy_list_count(id)
.policylist_view(id)
.build(ctx);
*/
/*
let policydata_view = TaskView::new()
.back_entity(policy_view.0)
let policylist_view = PolicyListView::new()
.back_entity(policycheck_view.0)
.policydata_view(id)
.policylist_view(id)
.policy_list_count(id)
.build(ctx);
let policydata_view = PolicyDataView::new()
.back_entity(policylist_view.0)
.policylist_view(id)
.visibility("collapsed")
.build(ctx);
*/
self.name("MainView")
//.policy_list(policy_list.0)
//.policylist_view(PolicyList:default())
//.policy_list_count(0)
.policy_list_count(0)
.policycheck_view(PolicyCheck::default())
//.policycheck_view(0)
.policydata_view(policydata_view.0)
//.policylist_view(PolicyList::default())
.policylist_view(policylist_view.0)
.child(policydata_view)
.child(policylist_view)
.child(policycheck_view)
}
}

View File

@@ -2,7 +2,7 @@ use orbtk::prelude::*;
use crate::{
base_state::BaseState,
//data::{PolicyData, PolicyList},
data::{PolicyData, PolicyDataList},
keys::*,
};
@@ -11,13 +11,14 @@ use crate::{
pub enum Action {
ClearEntry(Entity),
InputTextChanged(Entity),
OpenMenu(Entity),
ParseEntry(Entity),
RemoveFocus(Entity),
SetEntry(Entity),
TextChanged(Entity, usize),
}
/// Handles the requests of the `OverviewView`.
/// Handles the requests of the `PolicyCheckView`.
#[derive(Default, AsAny)]
pub struct PolicyCheckState {
action:Option<Action>,
@@ -42,9 +43,13 @@ impl PolicyCheckState {
println!("reset {}", text);
}
/// Open menu.
pub fn open_menu(&mut self, text_block: Entity, ctx: &mut Context) {
let mut text_block = TextBlock::get(ctx.get_widget(text_block));
let text = text_block.text_mut();
println!("Menu text: {}", text);
}
/// Parse and verify given policy code to match a valid policy data element.
//fn parse_entry(&self, text_box: Entity, ctx: &mut Context) -> Result<(), Box<dyn std::error::Error>> {
fn parse_entry(&self, text_box: Entity, ctx: &mut Context) {
// Old style
//let length = ctx.get_widget(text_box).get::<String>("policy_number").len();
@@ -125,10 +130,10 @@ impl State for PolicyCheckState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.menu_button = ctx
.entity_of_child(ID_POLICY_CHECK_MENU_BUTTON)
.expect("PolicyState.init: Can't find child 'Menu button'.");
.expect("PolicyCheckState.init: Can't find child 'Menu button'.");
self.text_box = ctx
.entity_of_child(ID_POLICY_CHECK_POLICY_NUMBER)
.expect("PolicyState.init: Can't find child 'Text Box'.");
.expect("PolicyCheckState.init: Can't find child 'Text Box'.");
}
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context) {
@@ -149,6 +154,9 @@ impl State for PolicyCheckState {
Action::InputTextChanged(text_box) => {
self.set_check_button(text_box, ctx);
}
Action::OpenMenu(text_block) => {
self.open_menu(text_block, ctx);
}
Action::ParseEntry(text_box) => {
self.parse_entry(text_box, ctx);
}

View File

@@ -1,26 +1,79 @@
use orbtk::prelude::*;
use orbtk::theme::vector_graphics::material_icons_font;
//use orbtk::theme::vector_graphics::material_icons_font_ttf;
use crate::{
//data::PolicyList,
data::PolicyCheck,
keys::*,
policycheck_state::*,
//policycheck_state::{Action, PolicyCheckState},
};
widget!(PolicyCheckView);
// widget!(
// /// Starter page that offers the dialog to enter an identifier of a policy.
// /// This identifier is checked agains a map of valid policy codes.
// PolicyCheckView<PolicyCheckState> {
// //is_valid: bool,
// title: String,
// policy_check_text_box: String
// }
// );
widget!(
/// Dialog to enter a policy identifier/number.
/// This identifier is checked agains a map of valid policy codes.
PolicyCheckView<PolicyCheckState> {
policy_check: PolicyCheck,
//policy_check_list: PolicyCheckList,
policy_check_title: String,
policy_check_number: String,
policy_check_number_valid: bool,
policy_check_text_box: String,
policy_data_count: u32,
policylist_view: u32,
title: String
}
);
impl Template for PolicyCheckView {
fn template(self, id: Entity, ctx: &mut BuildContext)-> Self {
// collect the DCES elements of our 'policy check' view
// let items_widget = ItemsWidget::new()
// .id(ID_POLICY_CHECK_ITEMS_WIDGET)
// .v_align("start")
// .items_builder(move |ctx, index| {
// let mut title = "".to_string();
// if let Some(policy_check) = ctx
// .get_widget(id)
// .get::<PolicyCheckList>(PROP_POLICY_CHECK_LIST)
// .get(index)
// {
// title = policy_check.title.clone();
// }
// })
// .count((PROP_POLICY_DATA_COUNT, id))
// .build(ctx);
let policycheck_menu_text_block = TextBlock::new()
.foreground("#3b434a")
.text("Help Menu")
.v_align("center")
.h_align("center")
.build(ctx);
let policy_check_menu_button = Button::new()
.margin((0.0, 0.0, 12.0, 12.0))
.icon(material_icons_font_ttf::MD_MENU)
//.class(CLASS_ICON_ONLY)
//.attach(Grid::row(0))
.attach(Grid::column(2))
.margin((8.0, 0.0, 2.0, 0.0))
.text("Menu Button")
//.min_size(8.0, 8.0)
//.min_size(16.0, 16.0)
//.h_align("end")
//.v_align("center")
//.enabled(true)
//.on_mouse_down(|_, _| true)
//.child(policycheck_menu_container)
//.on_click(move |ctx, _| {
// ctx.get_mut::<PolicyCheckState>(id)
// .action(Action::OpenMenu(policy_check_menu_text_block));
// true
//})
.build(ctx);
// let policy_check_text_box = TextBox::new()
// .id(ID_POLICY_CHECK_TEXT_BOX)
// .attach(Grid::row(4))
@@ -50,41 +103,26 @@ impl Template for PolicyCheckView {
// .min_size(120.0, 180.0)
// .v_align("center")
// .on_click(move |ctx, _| {
// ctx.get_mut::<PolicyCheckState>(id)
// .action(Action::NewEntry(quit));
// true
// ctx.get_mut::<PolicyCheckState>(id)
// .action(Action::NewEntry(quit));
// true
// })
// .build(ctx);
let policy_check_menu_button = Button::new()
.id(ID_POLICY_CHECK_MENU_BUTTON)
//.class(CLASS_ICON_ONLY)
//.attach(Grid::row(0))
.attach(Grid::column(2))
//.margin((0.0, 0.0, 12.0, 12.0))
//.min_size(8.0, 8.0)
.min_size(16.0, 16.0)
.h_align("end")
.v_align("center")
.enabled(true)
//.icon(material_icons_font::MENU_FONT_ICON)
//.icon(material_icons_font_ttf::EDIT_FONT_ICON)
//.icon("")
//.icon("")
.on_mouse_down(|_, _| true)
//.child(policycheck_menu)
// .on_click(move |ctx, _| {
// //ctx.get_mut::<PolicyCheckState>(id)
// // .action(Action::NewEntry(policy_check_menu_container));
// true
//})
.build(ctx);
// let policycheck_menu_container = Container::new()
// .id(ID_POLICY_CHECK_MENU_CONTAINER)
// .background("#dfebf5")
// .width(200.0)
// .height(200.0)
// .child(
// The menu implemented as an overlay
//ctx.append_child_to_overlay(policy_check_menu_button).unwrap();
// Check policy identifier page
self.name("Policy check").child(
// Starter page: check for valid policy number
self.name("PolicyCheckView")
.policy_check(PolicyCheck::default())
.child(
Grid::new()
.id(ID_POLICY_CHECK_WIDGET)
//.v_align("start")
@@ -133,7 +171,7 @@ impl Template for PolicyCheckView {
)
.build(ctx),
)
.child(policy_check_menu_button)
//.child(policy_check_menu_button)
.build(ctx),
)
.child(
@@ -294,10 +332,15 @@ impl Template for PolicyCheckView {
.build(ctx),
)
.build(ctx),
//ctx.append_child_to_overlay(policycheck_menu_text_block).unwrap()
)
.build(ctx),
)
.build(ctx),
)
}

View File

@@ -2,11 +2,10 @@ use orbtk::prelude::*;
use crate::{
base_state::BaseState,
data::{PolicyData, PolicyList},
data::{PolicyCode, PolicyData, PolicyList, Status},
keys::*,
};
use chrono::{Local, NaiveDateTime};
//use chrono::{DateTime, Local, TimeZone, NaiveDateTime, Utc};
use chrono::{Utc, NaiveDateTime};
/// Actions that can execute on the task view.
#[derive(Debug, Clone, Copy)]
@@ -16,19 +15,25 @@ pub enum Action {
NewEntry(Entity),
RemoveFocus(Entity),
RemoveEntry(usize),
SetEntry(Entity),
SetDateInserted(Entity),
SetDion(Entity),
SetPolicyCode(Entity),
SetPolicyNumber(Entity),
StatusChanged(Entity, usize),
TextChanged(Entity, usize),
}
/// Handles the requests of the `OverviewView`.
#[derive(Default, AsAny)]
/// Handles the requests of the `PolicyDataListView`.
#[derive(Debug, Default, AsAny)]
pub struct PolicyDataState {
action:Option<Action>,
add_button: Entity,
back_entity: Entity,
last_focused: Option<Entity>,
pub text_box: Entity,
policy_data_add_button: Entity,
pub policy_data_date_inserted: Entity,
pub policy_data_dion: Entity,
pub policy_data_policy_code: Entity,
pub policy_data_policy_number: Entity,
open: bool,
}
@@ -39,214 +44,240 @@ impl BaseState for PolicyDataState {}
impl PolicyDataState {
/// Sets a new action.
pub fn action(&mut self, action: Action) {
self.action = action.into();
self.action = action.into();
}
/// update number of available policy data entries.
fn adjust_count(&self, ctx: &mut Context) {
if let Some(index) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_list) = ctx
.widget()
.clone::<PolicyList>("policy_list")
.get(index)
{
ctx.widget().set("policy_data_count", policy_list.len());
}
}
if let Some(index) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_list) = ctx
.widget()
.clone::<PolicyList>("policy_list")
.get(index)
{
ctx.widget().set("policy_data_count", policy_list.len());
}
}
}
/// If policy data element 'name' is empty, disable the add button
/// otherwise otherwise enabled it.
fn adjust_add_button_enabled(&self, text_box: Entity, ctx: &mut Context) {
if ctx.get_widget(text_box).get::<String16>("name").is_empty() {
ctx.get_widget(self.add_button).set("enabled", false);
} else {
ctx.get_widget(self.add_button).set("enabled", true);
}
if ctx.get_widget(text_box).get::<String16>("name").is_empty() {
ctx.get_widget(self.policy_data_add_button).set("enabled", false);
} else {
ctx.get_widget(self.policy_data_add_button).set("enabled", true);
}
ctx.get_widget(self.add_button).update_theme_by_state(true);
ctx.get_widget(self.policy_data_add_button).update_theme_by_state(true);
}
/// Change status of given text box to edit mode.
fn edit_entry(&self, text_box: Entity, ctx: &mut Context) {
if *ctx.get_widget(text_box).get::<bool>("focused") {
ctx.get_widget(text_box).set("enabled", false);
ctx.push_event_by_window(FocusEvent::RemoveFocus(text_box));
return;
}
if *ctx.get_widget(text_box).get::<bool>("focused") {
ctx.get_widget(text_box).set("enabled", false);
ctx.push_event_by_window(FocusEvent::RemoveFocus(text_box));
return;
}
if let Some(old_focused_element) = ctx.window().get::<Global>("global").focused_widget {
ctx.push_event_by_window(FocusEvent::RemoveFocus(old_focused_element));
}
if let Some(old_focused_element) = ctx.window().get::<Global>("global").focused_widget {
ctx.push_event_by_window(FocusEvent::RemoveFocus(old_focused_element));
}
ctx.get_widget(text_box).set("enabled", true);
ctx.get_widget(text_box).set("enabled", true);
// select all
ctx.get_widget(text_box)
.get_mut::<TextSelection>("text_selection")
.start_index = 0;
ctx.get_widget(text_box)
.get_mut::<TextSelection>("text_selection")
.length = ctx.get_widget(text_box).get::<String16>("name").len();
ctx.push_event_by_window(FocusEvent::RequestFocus(text_box));
// select all
ctx.get_widget(text_box)
.get_mut::<TextSelection>("text_selection")
.start_index = 0;
ctx.get_widget(text_box)
.get_mut::<TextSelection>("text_selection")
.length = ctx.get_widget(text_box).get::<String16>("name").len();
ctx.push_event_by_window(FocusEvent::RequestFocus(text_box));
}
/// navigate to previous policy data entry.
fn navigate_back(&mut self, ctx: &mut Context) {
ctx.get_widget(self.text_box)
.set("name", String16::from(""));
self.open = false;
ctx.widget().set::<Option<usize>>("list_index", None);
ctx.widget().set("policy_data_count", 0 as usize);
self.navigate(self.back_entity, ctx);
ctx.get_widget(self.text_box)
.set("name", String16::from(""));
self.open = false;
ctx.widget().set::<Option<usize>>("list_index", None);
ctx.widget().set("policy_data_count", 0 as usize);
self.navigate(self.back_entity, ctx);
}
/// create a new policy data member
fn new_entry(&self, name: String, registry: &mut Registry, ctx: &mut Context) {
let index = ctx.widget().clone::<Option<usize>>("list_index");
fn new_entry(&self, policy_number: u32, registry: &mut Registry, ctx: &mut Context) {
let index = ctx.widget().clone::<Option<usize>>("list_index");
if let Some(index) = index {
if let Some(policy_elements) = ctx
.widget()
.get_mut::<PolicyData>("policy_elements")
.get_mut(index)
{
policy_list.push(PolicyData {
policy_code,
date_valid_until,
selected: true,
});
}
if let Some(index) = index {
if let Some(policy_data) = ctx
.widget()
.get_mut::<PolicyList>("policy_list")
.get_mut(index)
{
policy_data.push(PolicyData {
date_inserted: Some(Utc::now().naive_utc()),
dion: 1,
policy_code: PolicyCode::AS,
policy_number,
status: Status::Active,
});
}
self.adjust_count(ctx);
}
self.adjust_count(ctx);
}
self.save(registry, ctx);
self.save(registry, ctx);
}
pub fn open(&mut self, ctx: &mut Context) {
if let Some(index) = ctx.widget().clone::<Option<usize>>("list_index") {
let mut name: String16 = "".into();
let mut policy_data_count = 0;
if let Some(policy_list) = ctx.widget().get::<PolicyList>("policy_list").get(index) {
name = String16::from(policy_list.name.as_str());
policy_data_count = policy_list.len();
}
ctx.widget().set("name", title);
ctx.widget().set("policy_data_count", policy_count);
self.open = true;
}
if let Some(index) = ctx.widget().clone::<Option<usize>>("list_index") {
let mut name: String16 = "".into();
let mut policy_data_count = 0;
if let Some(policy_list) = ctx.widget().get::<PolicyList>("policy_list").get(index) {
name = String16::from(policy_list.name.as_str());
policy_data_count = policy_list.len();
}
ctx.widget().set("name", name);
ctx.widget().set("policy_data_count", policy_data_count);
self.open = true;
}
}
fn remove_entry(&self, index: usize, registry: &mut Registry, ctx: &mut Context) {
if let Some(idx) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_list) = ctx
.widget()
.get_mut::<PolicyList>("policy_list")
.get_mut(idx)
{
policy_list.remove(index);
}
}
self.adjust_count(ctx);
self.save(registry, ctx);
if let Some(idx) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_list) = ctx
.widget()
.get_mut::<PolicyList>("policy_list")
.get_mut(idx)
{
policy_list.remove(index);
}
}
self.adjust_count(ctx);
self.save(registry, ctx);
}
/// Toggle the invalid element of the given policy data entry
fn toggle_invalid(
&self,
entry: Entity,
index: usize,
registry: &mut Registry,
ctx: &mut Context,
/// Toggle the selection state of the given policy number element
fn toggle_status(
&self,
entry: Entity,
index: usize,
registry: &mut Registry,
ctx: &mut Context,
) {
let invalid: bool = *ctx.get_widget(entry).get("invalid");
let invalid: bool = *ctx.get_widget(entry).get("status");
if let Some(idx) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_list) = ctx
.widget()
.get_mut::<PolicyData>("policy_list")
.get_mut(idx)
{
if let Some(task) = policy_list.get_mut(index) {
policy.selected = selected;
}
}
}
self.save(registry, ctx);
if let Some(idx) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_data) = ctx
.widget()
.get_mut::<PolicyList>("policy_list")
.get_mut(idx)
{
if let Some(policy_data) = policy_data.get_mut(index) {
policy_data.status = Status::Active;
}
}
}
self.save(registry, ctx);
}
fn update_entry(
&self,
text_box: Entity,
index: usize,
registry: &mut Registry,
ctx: &mut Context,
&self,
policy_data_date_inserted: Entity,
policy_data_dion: Entity,
policy_data_policy_code: Entity,
policy_data_policy_number: Entity,
index: usize,
registry: &mut Registry,
ctx: &mut Context,
) {
let text: String16 = ctx.get_widget(text_box).clone("text");
let date_inserted: Option<NaiveDateTime> = ctx.get_widget(policy_data_date_inserted).clone("date_inserted");
let dion: u8 = ctx.get_widget(policy_data_dion).clone("dion");
let policy_code: PolicyCode = ctx.get_widget(policy_data_policy_code).clone("policy_code");
let policy_number: u32 = ctx.get_widget(policy_data_policy_number).clone("policy_number");
if let Some(idx) = ctx.widget().clone::<Option<usize>>("list_index") {
if let Some(policy_list) = ctx
.widget()
.get_mut::<PolicyList>("policy_list")
.get_mut(idx)
{
if let Some(task) = policy_list.get_mut(index) {
task.text = text.to_string();
}
}
}
self.save(registry, ctx);
// get the index from the active widgets 'list_index' member
if let Some(idx) = ctx.widget().clone::<Option<usize>>("list_index") {
// get view record from the active widgets 'policy_list' member
if let Some(policy_list) = ctx
.widget()
.get_mut::<PolicyList>("policy_list")
.get_mut(idx)
{
// update the record data using the view values of the active policy_list member
if let Some(policy_data) = policy_list.get_mut(index) {
policy_data.date_inserted = date_inserted;
policy_data.dion = dion;
policy_data.policy_code = policy_code;
policy_data.policy_number = policy_number;
}
}
}
self.save(registry, ctx);
}
}
impl State for PolicyState {
impl State for PolicyDataState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.back_entity = (*ctx.widget().get::<u32>("back_entity")).into();
self.add_button = ctx
.entity_of_child(ID_POLICY_ADD_BUTTON)
.expect("PolicyState.init: Can't find child 'Add button'.");
self.text_box = ctx
.entity_of_child(ID_POLICY_TEXT_BOX)
.expect("PolicyState.init: Can't find child 'Text Box'.");
self.back_entity = (*ctx.widget().get::<u32>("back_entity")).into();
self.policy_data_add_button = ctx
.entity_of_child(ID_POLICY_DATA_ADD_BUTTON)
.expect("PolicyState.init: Can't find child 'Add button'.");
self.policy_data_policy_number = ctx
.entity_of_child(ID_POLICY_DATA_POLICY_NUMBER)
.expect("PolicyState.init: Can't find child 'Policy Number'.");
}
fn update(&mut self, registry: &mut Registry, ctx: &mut Context) {
if !self.open {
self.open(ctx);
}
if let Some(action) = self.action {
match action {
Action::InputTextChanged(text_box) => {
self.adjust_add_button_enabled(text_box, ctx);
}
Action::CreateEntry(entity) => {
if let Some(text) = self.fetch_text(ctx, entity) {
self.create_entry(name, registry, ctx);
}
}
Action::RemoveEntry(index) => {
self.remove_entry(index, registry, ctx);
}
Action::SelectionChanged(entity, index) => {
self.toggle_selection(entity, index, registry, ctx);
}
Action::TextChanged(entity, index) => {
self.update_entry(entity, index, registry, ctx);
}
Action::EditEntry(text_box) => {
self.last_focused = Some(text_box);
self.edit_entry(text_box, ctx);
}
Action::RemoveFocus(text_box) => {
ctx.get_widget(text_box).set("enabled", false);
ctx.push_event_by_window(FocusEvent::RemoveFocus(text_box));
}
Action::NavigateBack() => {
self.navigate_back(ctx);
}
}
}
self.action = None;
if !self.open {
self.open(ctx);
}
if let Some(action) = self.action {
match action {
Action::InputTextChanged(text_box) => {
self.adjust_add_button_enabled(text_box, ctx);
}
Action::NewEntry(entity) => {
if let Some(text) = self.fetch_text(ctx, entity) {
self.new_entry(text, registry, ctx);
}
}
Action::RemoveEntry(index) => {
self.remove_entry(index, registry, ctx);
}
Action::SelectionChanged(entity, index) => {
self.toggle_selection(entity, index, registry, ctx);
}
Action::TextChanged(entity, index) => {
self.update_entry(entity, index, registry, ctx);
}
Action::SetDateInserted(policy_data_date_inserted) => {
self.last_focused = Some(policy_data_date_inserted);
self.edit_entry(policy_data_date_inserted, ctx);
}
Action::SetDion(policy_data_dion) => {
self.last_focused = Some(policy_data_dion);
self.edit_entry(policy_data_policy_dion);
}
Action::SetPolicyCode(policy_data_policy_code) => {
self.last_focused = Some(policy_data_policy_code);
self.edit_entry(policy_data_policy_code, ctx);
}
Action::SetPolicyNumber(policy_data_policy_number) => {
self.last_focused = Some(policy_data_policy_number);
self.edit_entry(policy_data_policy_number, ctx);
}
Action::RemoveFocus(text_box) => {
ctx.get_widget(text_box).set("enabled", false);
ctx.push_event_by_window(FocusEvent::RemoveFocus(text_box));
}
Action::NavigateBack() => {
self.navigate_back(ctx);
}
}
}
self.action = None;
}
}

View File

@@ -1,280 +1,387 @@
use orbtk::prelude::*;
use crate::{
data::PolicyData,
data::{PolicyList, Status},
keys::*,
policy_state::{Action, PolicyState},
policydata_state::{Action, PolicyDataState},
};
use chrono::NaiveDateTime;
type ListIndex = Option<usize>;
widget!(PolicyData<PolicyDataState> {
back_entity: u32,
list_index: ListIndex,
name: String16
policy_data: PolicyData,
policy_data_count: usize,
// Dialog to manage policy identifiers.
// The elements may be toggled to be deactivated. The optional value 'data_valid_until'
// will render this value unvalid after the given date.
widget!(
PolicyDataView<PolicyDataState> {
back_entity: u32,
policy_list_count: usize,
policylist_view: u32,
list_index: ListIndex,
date_valid_until: NaiveDateTime,
policy_list: PolicyList
});
impl Template for PolicyData {
impl Template for PolicyDataView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
// listing the policy elements
let items_widget = ItemsWidget::new()
.id(ID_POLICY_DATA_ITEMS_WIDGET)
.v_align("start")
.items_builder(move |ctx, index| {
let mut policy_code = "".to_string();
let mut date_inserted = None;
let mut isactive = false;
// listing the policy elements
let items_widget = ItemsWidget::new()
.id(ID_POLICY_DATA_ITEMS_WIDGET)
.v_align("start")
.items_builder(move |ctx, index| {
let mut date_inserted = None;
let mut dion = 1;
let mut policy_code = "".to_string();
let mut policy_number = None;
let mut status = false; // Status::<Active, Inactive>;
if let Some(list_index) = ctx.get_widget(id).clone::<ListIndex>("list_index") {
if let Some(policy_data) = ctx
.get_widget(id)
.get::<PolicyData(PROP_POLICY_DATA)
.get(list_index)
{
if let Some(policy_data) = policy_data.get(index) {
policy_code = policy_data.policy_code.clone();
date_inserted = policy_data.date_inserted.clone();
isactive = policy_data.isactive;
}
}
}
if let Some(list_index) = ctx.get_widget(id).clone::<ListIndex>("list_index") {
if let Some(policy_data) = ctx
.get_widget(id)
.get::<PolicyList>(PROP_POLICY_LIST)
.get(list_index)
{
if let Some(policy_data) = policy_data.get(index) {
date_inserted = policy_data.date_inserted.clone();
dion = policy_data.dion.clone();
policy_code = policy_data.policy_code.clone();
policy_number = policy_data.policy_number.clone();
status = policy_data.status;
}
}
}
let text_box = TextBox::new()
.text(name)
.enabled(false)
.v_align("center")
.water_mark("Insert the new policy collection name ...")
.class("inplace")
.attach(Grid::column(3))
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::TextChanged(entity, index));
})
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyState>(id)
.action(Action::RemoveFocus(entity));
})
.build(ctx);
let policy_data_status = CheckBox::new()
.attach(Grid::column(1))
.v_align("center")
// status: true -> State::Active false -> State::Inactive
.enabled(status)
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::StatusChanged(entity, index));
})
.build(ctx);
Grid::new()
.height(48.0)
.columns(
Columns::new()
.add(10.0)
.add(24.0)
.add(8.0)
.add("*")
.add(8.0)
.add(32.0)
.add(4.0)
.add(32.0)
.add(8.0)
.build(),
)
.child(
CheckBox::new()
.attach(Grid::column(1))
.v_align("center")
.invalid(invalid)
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyState>(id)
.action(Action::StatusChanged(entity, index));
})
.build(ctx),
)
.child(text_box)
.child(
ToggleButton::new()
.selected(("focused", text_box))
.class(CLASS_ICON_ONLY)
.attach(Grid::column(5))
.min_size(32.0, 32.0)
.v_align("center")
.build(ctx),
)
.child(
Button::new()
.class(CLASS_ICON_ONLY)
.attach(Grid::column(5))
.min_size(32.0, 32.0)
.v_align("center")
// todo use remove from icons
// .icon(material_font_icons::DELETE_FONT_ICON)
.icon("")
.on_mouse_down(|_, _| true)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyState>(id)
.action(Action::EditEntry(text_box));
true
})
.build(ctx),
)
.child(
Button::new()
.class("icon_only")
.attach(Grid::column(7))
.min_size(32.0, 32.0)
.v_align("center")
// todo use remove from icons
// .icon(material_font_icons::DELETE_FONT_ICON)
.icon("")
.on_mouse_down(|_, _| true)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyState>(id)
.action(Action::RemoveEntry(index));
true
})
.build(ctx),
)
.build(ctx)
})
.policy_data_count(PROP_POLICY_COUNT, id)
.build(ctx);
let policy_data_dion = TextBox::new()
.id(ID_POLICY_DATA_DION)
.attach(Grid::row(3))
.v_align("center")
.margin((4.0, 0.0, 0.0, 0.0))
.text(dion)
.lost_focus_on_activation(false)
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::CreateEntry(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::InputTextChanged(entity));
})
.build(ctx);
let scroll_viewer = ScrollViewer::new()
.scroll_viewer_mode(("disabled", "auto"))
.child(items_widget)
.build(ctx);
let policy_data_dion = TextBox::new()
.id(ID_POLICY_DATA_DION)
.attach(Grid::row(5))
.v_align("center")
.margin((4.0, 0.0, 0.0, 0.0))
.text(policy_code)
.lost_focus_on_activation(false)
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::TextChanged(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::RemoveFocus(entity));
})
.build(ctx);
let task_text_box = TextBox::new()
.id(ID_POLICY_TEXT_BOX)
.attach(Grid::row(4))
.v_align("center")
.margin((4.0, 0.0, 0.0, 0.0))
.lost_focus_on_activation(false)
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyState>(id)
.action(Action::CreateEntry(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyState>(id)
.action(Action::InputTextChanged(entity));
})
.build(ctx);
let policy_data_policy_code = TextBox::new()
.id(ID_POLICY_DATA_POLICY_CODE)
.attach(Grid::row(7))
.v_align("center")
.margin((4.0, 0.0, 0.0, 0.0))
.text(policy_code)
.lost_focus_on_activation(false)
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::TextChanged(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::RemoveFocus(entity));
})
.build(ctx);
self.name("PolicyList").child(
Grid::new()
.rows(
Rows::new()
.add(52.0)
.add(1.0)
.add("*")
.add(1.0)
.add("auto")
.build(),
)
.columns(
Columns::new()
.add("*")
.add(4.0)
.add(36.0)
.build(),
)
// Content
.child(
Container::new()
.attach(Grid::row(2))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.child(scroll_viewer)
.child(
ScrollIndicator::new()
.padding((0.0, 4.0, 0.0, 0.0))
.content_id(items_widget.0)
.scroll_offset(scroll_viewer)
.build(ctx),
)
.build(ctx),
)
// Top Bar
.child(
Container::new()
.class(CLASS_TOP_BAR)
.attach(Grid::row(0))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.child(
Grid::new()
.columns(
Columns::new()
.add(32.0)
.add(4.0)
.add("*")
.add(4.0)
.add(32.0)
.build(),
)
.child(
Button::new()
.height(32.0)
.icon("")
.class(CLASS_ICON_ONLY)
.v_align("center")
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyState>(id)
.action(Action::NavigateBack());
true
})
.build(ctx),
)
.child(
TextBlock::new()
.class(CLASS_HEADER)
.attach(Grid::column(2))
.v_align("center")
.h_align("center")
.text(("name", id))
.build(ctx),
)
.build(ctx),
)
.build(ctx),
)
.child(
Container::new()
.class("separator")
.attach(Grid::row(1))
.attach(Grid::column_span(3))
.build(ctx),
)
.child(
Container::new()
.class("separator")
.attach(Grid::row(3))
.attach(Grid::column_span(3))
.build(ctx),
)
// Bottom bar
.child(
Container::new()
.class(CLASS_BOTTOM_BAR)
.attach(Grid::row(4))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.build(ctx),
)
.child(task_text_box)
.child(
Button::new()
.id(ID_POLICY_ADD_BUTTON)
.class(CLASS_ICON_ONLY)
.attach(Grid::row(4))
.attach(Grid::column(2))
.margin((0.0, 0.0, 4.0, 0.0))
.enabled(false)
.min_size(32.0, 32.0)
.v_align("center")
.icon(material_font_icons::ADD_FONT_ICON)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyState>(id)
.action(Action::CreateEntry(task_text_box));
true
})
.build(ctx),
)
.build(ctx),
)
let policy_data_policy_number = TextBox::new()
.id(ID_POLICY_DATA_POLICY_NUMBER)
.attach(Grid::column(9))
.text(policy_number)
.enabled(false)
.v_align("center")
.water_mark("Insert the new policy number ...")
.class("inplace")
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::TextChanged(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::RemoveFocus(entity));
})
.build(ctx);
let policy_data_date_inserted = TextBlock::new()
.id(ID_POLICY_DATA_DATE_INSERTED)
.attach(Grid::column(9))
.text(date_inserted)
.v_align("start")
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::TextChanged(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::RemoveFocus(entity));
})
.build(ctx);
Grid::new()
.height(48.0)
.columns(
Columns::new()
.add(10.0)
.add(24.0)
.add(8.0)
.add(24.0)
.add(8.0)
.add(24.0)
.add(8.0)
.add("auto")
.add(8.0)
.add("auto")
.add(8.0)
.add(32.0)
.add(4.0)
.add(32.0)
.add(8.0)
.build(),
)
.child(policy_data_status)
.child(policy_data_dion)
.child(policy_data_policy_code)
.child(policy_data_policy_number)
.child(policy_data_date_inserted)
.child(
// edit active policy data element
Button::new()
.class(CLASS_ICON_ONLY)
.attach(Grid::column(11))
.min_size(32.0, 32.0)
.v_align("center")
.icon(material_icons_font_ttf::MD_EDIT)
//.icon("")
.on_mouse_down(|_, _| true)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::EditEntry(text_box));
true
})
.build(ctx),
)
.child(
// delete active policy data element
Button::new()
.class("icon_only")
.attach(Grid::column(13))
.min_size(32.0, 32.0)
.v_align("center")
.icon(material_icons_font_ttf::MD_DELETE)
//.icon("")
.on_mouse_down(|_, _| true)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::RemoveEntry(index));
true
})
.build(ctx),
)
.build(ctx)
})
.policy_data_count(PROP_POLICY_DATA_COUNT, id)
.build(ctx);
let scroll_viewer = ScrollViewer::new()
.scroll_viewer_mode(("disabled", "auto"))
.child(items_widget)
.build(ctx);
let policy_data_list_name = TextBox::new()
.id(ID_POLICY_DATA_LIST_NAME)
.attach(Grid::row(4))
.v_align("center")
.margin((4.0, 0.0, 0.0, 0.0))
.lost_focus_on_activation(false)
.on_activate(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::CreateEntry(entity));
})
.on_changed(move |ctx, entity| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::InputTextChanged(entity));
})
.build(ctx);
// Child page: list available policy data elements
self.name("PolicyDataListView").child(
Grid::new()
.rows(
Rows::new()
.add(52.0)
.add(1.0)
.add("*")
.add(1.0)
.add("auto")
.build(),
)
.columns(
Columns::new()
.add("*")
.add(4.0)
.add(36.0)
.build(),
)
// Top Bar
.child(
Container::new()
.class(CLASS_TOP_BAR)
.attach(Grid::row(0))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.child(
Grid::new()
.columns(
Columns::new()
.add(32.0)
.add(4.0)
.add("*")
.add(4.0)
.add(32.0)
.build(),
)
.child(
Button::new()
.height(32.0)
.icon(material_icons_font_ttf::MD_ARROW_LEFT)
//.icon("")
.class(CLASS_ICON_ONLY)
.v_align("center")
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::NavigateBack());
true
})
.build(ctx),
)
.child(
TextBlock::new()
.class(CLASS_HEADER)
.attach(Grid::column(2))
.v_align("center")
.h_align("center")
.text(("name", id))
.build(ctx),
)
.child(
Stack::new()
.class(CLASS_HEADER)
.attach(Grid::column(3))
.h_align("start")
.orientation("horizontal")
.child(
TextBox::new()
.class(CLASS_HEADER)
//.v_align("center")
.h_align("start")
.text(("Anzahl:", id))
.build(ctx),
)
.child(
TextBlock::new()
.class(CLASS_HEADER)
.id(PROP_POLICY_DATA_COUNT)
.attach(Grid::column(3))
//.v_align("center")
.h_align("end")
.text("policy_data_count")
.build(ctx),
)
.build,
)
.build(ctx),
)
.build(ctx),
)
.child(
Container::new()
.class("separator")
.attach(Grid::row(1))
.attach(Grid::column_span(3))
.build(ctx),
)
// Content
.child(
Container::new()
.attach(Grid::row(2))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.child(scroll_viewer)
.child(
ScrollIndicator::new()
.padding((0.0, 4.0, 0.0, 0.0))
.content_id(items_widget.0)
.scroll_offset(scroll_viewer)
.build(ctx),
)
.build(ctx),
)
.child(
Container::new()
.class("separator")
.attach(Grid::row(3))
.attach(Grid::column_span(3))
.build(ctx),
)
// Bottom bar
.child(
Container::new()
.class(CLASS_BOTTOM_BAR)
.attach(Grid::row(4))
.attach(Grid::column(0))
.attach(Grid::column_span(3))
.build(ctx),
)
.child(policy_data_list_name)
.child(
Button::new()
.id(ID_POLICY_DATA_ADD_BUTTON)
.class(CLASS_ICON_ONLY)
.attach(Grid::row(4))
.attach(Grid::column(2))
.margin((0.0, 0.0, 4.0, 0.0))
.enabled(false)
.min_size(32.0, 32.0)
.v_align("center")
.icon(material_icons_font_ttf::MD_ADD_CIRCLE)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyDataState>(id)
.action(Action::CreateEntry(policy_data_list_name));
true
})
.build(ctx),
)
.build(ctx),
)
}
}

View File

@@ -2,7 +2,7 @@ use orbtk::prelude::*;
use crate::{
base_state::BaseState,
data::{PolicyData, PolicyList},
data::{PolicyDataList, PolicyList},
keys::*,
};
@@ -18,7 +18,7 @@ pub enum Action {
TextChanged(Entity, usize),
}
/// Handles the requests of the `OverviewView`.
/// Handles the requests of the `PolicyListView`.
#[derive(Default, AsAny)]
pub struct PolicyListState {
action:Option<Action>,
@@ -60,21 +60,21 @@ impl PolicyListState {
/// update number of available policy list entries.
fn adjust_count(&self, ctx: &mut Context) {
let policy_lists_count = ctx.widget().get::<PolicyList>(PROP_POLICY_LISTS).len();
ctx.widget().set(PROP_POLICY_LISTS_COUNT, policy_lists_count);
let policy_list_count = ctx.widget().get::<PolicyList>(PROP_POLICY_LIST).len();
ctx.widget().set(PROP_POLICY_LIST_COUNT, policy_list_count);
}
// Creates a new policy list.
// Creates a new policy data list.
fn new_entry(&self, name: String, registry: &mut Registry, ctx: &mut Context) {
ctx.widget()
.get_mut::<PolicyList>(PROP_POLICY_LISTS)
.push(PolicyData::new(name));
.get_mut::<PolicyList>(PROP_POLICY_LIST)
.push(PolicyList::new(name));
self.adjust_count(ctx);
self.save(registry, ctx);
}
// opens a given policy list name.
fn open_policy_lists(&self, index: usize, ctx: &mut Context) {
fn open_policy_list(&self, index: usize, ctx: &mut Context) {
ctx.get_widget(self.text_box)
.set("text", String16::from(""));
ctx.get_widget(self.policydata_view)
@@ -85,7 +85,7 @@ impl PolicyListState {
// removes a policy list.
fn remove_entry(&self, index: usize, registry: &mut Registry, ctx: &mut Context) {
ctx.widget()
.get_mut::<PolicyList>(PROP_POLICY_LISTS)
.get_mut::<PolicyList>(PROP_POLICY_LIST)
.remove(index);
self.adjust_count(ctx);
self.save(registry, ctx);
@@ -120,22 +120,22 @@ impl PolicyListState {
impl State for PolicyListState {
fn init(&mut self, registry: &mut Registry, ctx: &mut Context) {
self.text_box = ctx
.entity_of_child(ID_POLICY_LISTS_TEXT_BOX)
.entity_of_child(ID_POLICY_LIST_TEXT_BOX)
.expect("PolicyListState.init: Child 'Text box' not found.");
self.add_button = ctx
.entity_of_child(ID_POLICY_LISTS_ADD_BUTTON)
.entity_of_child(ID_POLICY_LIST_ADD_BUTTON)
.expect("PolicyListState.init: Child 'Add button' not found.");
self.items_widget = ctx
.entity_of_child(ID_POLICY_LISTS_ITEMS_WIDGET)
.entity_of_child(ID_POLICY_LIST_ITEMS_WIDGET)
.expect("PolicyListState.init: Child 'Items widget' not found.");
self.policydata_view = (*ctx.widget()
.get::<u32>("policy_lists_view")).into();
.get::<u32>("policy_list_view")).into();
if let Ok(tasks) = registry
if let Ok(policy_list_name) = registry
.get::<Settings>("settings")
.load::<PolicyList>(PROP_POLICY_LISTS)
.load::<PolicyList>(PROP_POLICY_LIST)
{
ctx.widget().set(PROP_POLICY_LISTS, tasks);
ctx.widget().set(PROP_POLICY_LIST, policy_list_name);
}
self.adjust_count(ctx);
@@ -157,8 +157,8 @@ impl State for PolicyListState {
self.adjust_add_button_enabled(text_box, ctx);
}
Action::NewEntry(entity) => {
if let Some(text) = self.fetch_text(ctx, entity) {
self.new_entry(text, registry, ctx);
if let Some(name) = self.fetch_text(ctx, entity) {
self.new_entry(name, registry, ctx);
}
}
Action::RemoveEntry(index) => {
@@ -169,7 +169,7 @@ impl State for PolicyListState {
if let Some(header) = ctx
.widget()
.get_mut::<PolicyList>("policy_lists")
.get_mut::<PolicyList>("policy_list")
.get_mut(index)
{
header.name = text.to_string();
@@ -186,7 +186,7 @@ impl State for PolicyListState {
ctx.push_event_by_window(FocusEvent::RemoveFocus(text_box));
}
Action::OpenPolicyList(index) => {
self.open_policy_lists(index, ctx);
self.open_policy_list(index, ctx);
}
}
}

View File

@@ -10,34 +10,35 @@ use crate::{
//type ListIndex = Option<usize>;
widget!(
/// Starter page that offers the dialog to enter an identifier of a policy.
/// This identifier is checked agains a map of valid policy codes.
/// Dialog selecting a list of policy identifiers.
/// The lists groups a collection of policy codes.
PolicyListView<PolicyListState> {
policy_lists: PolicyList,
policy_lists_count: usize,
policy_data: u32
back_entity: u32,
policy_list: PolicyList,
policy_list_count: usize,
policydata_view: u32
}
);
impl Template for PolicyListView {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
// all items of our policy lists
// collect the DCES elements of our 'policy lists' view
let items_widget = ItemsWidget::new()
.id(ID_POLICY_LISTS_ITEMS_WIDGET)
.id(ID_POLICY_LIST_ITEMS_WIDGET)
.v_align("start")
.items_builder(move |ctx, index| {
let mut name = "".to_string();
//let mut selected = false;
if let Some(policy_lists) = ctx
if let Some(policy_list) = ctx
.get_widget(id)
.get::<PolicyList>(PROP_POLICY_LISTS)
.get(index) {
name = policy_lists.name.clone();
}
.get::<PolicyList>(PROP_POLICY_LIST)
.get(index)
{
name = policy_list.name.clone();
}
// plus button: open new policy
let helper_button = Button::new()
let new_list_button = Button::new()
.min_height(48.0)
.class(CLASS_ITEM_BUTTON)
.attach(Grid::column(0))
@@ -51,7 +52,7 @@ impl Template for PolicyListView {
.build(ctx);
let text_block = TextBlock::new()
.foreground(helper_button)
.foreground(new_list_button)
.margin((14.0, 0.0, 0.0, 0.0))
.v_align("center")
.attach(Grid::column(0))
@@ -63,7 +64,7 @@ impl Template for PolicyListView {
.margin((8.0, 0.0, 0.0, 0.0))
.visibility("collapsed")
.v_align("center")
.water_mark("Insert name of a new policy list...")
.water_mark("Insert name of a new policy collection ...")
.attach(Grid::column(0))
.text(text_block)
.on_changed(move |ctx, entity| {
@@ -88,10 +89,11 @@ impl Template for PolicyListView {
.add(8.0)
.build(),
)
.child(helper_button)
.child(new_list_button)
.child(text_box)
.child(text_block)
.child(
// toggle if text_box is focused
ToggleButton::new()
.selected(("focused", text_box))
.class(CLASS_ICON_ONLY)
@@ -107,9 +109,9 @@ impl Template for PolicyListView {
.attach(Grid::column(2))
.min_size(32.0, 32.0)
.v_align("center")
// todo use remove from icons
// .icon(material_font_icons::DELETE_FONT_ICON)
.icon("")
.icon(material_icons_font_ttf::MD_ADD)
//.icon(material_icons_font_ttf::MD_EDIT)
//.icon("")
.on_mouse_down(|_, _| true)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyListState>(id)
@@ -124,9 +126,8 @@ impl Template for PolicyListView {
.attach(Grid::column(4))
.min_size(32.0, 32.0)
.v_align("center")
// todo use Tray icon for action remove
// .icon(material_font_icons::DELETE_FONT_ICON)
.icon("")
.icon(material_icons_font_ttf::MD_DELETE)
//.icon("")
.on_mouse_down(|_, _| true)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyListState>(id)
@@ -137,12 +138,12 @@ impl Template for PolicyListView {
)
.build(ctx)
})
.count((PROP_POLICY_LISTS_COUNT, id))
.count((PROP_POLICY_LIST_COUNT, id))
.build(ctx);
// create new policy list element
let policy_lists_text_box = TextBox::new()
.id(ID_POLICY_LISTS_TEXT_BOX)
let policy_list_text_box = TextBox::new()
.id(ID_POLICY_LIST_TEXT_BOX)
.attach(Grid::row(4))
.v_align("center")
.margin((4.0, 0.0, 0.0, 2.0))
@@ -162,9 +163,10 @@ impl Template for PolicyListView {
.child(items_widget)
.build(ctx);
self.name("Policy Lists")
.policy_lists(PolicyList::default())
.policy_lists_count(0)
// Child page: list available policy lists
self.name("PolicyListView")
.policy_list(PolicyList::default())
.policy_list_count(0)
.child(
Grid::new()
.rows(
@@ -213,7 +215,7 @@ impl Template for PolicyListView {
.class(CLASS_HEADER)
.v_align("center")
.h_align("center")
.text("Lists with policy data collections")
.text("Lists of policy data collections")
.build(ctx),
)
.build(ctx),
@@ -255,10 +257,10 @@ impl Template for PolicyListView {
.class(CLASS_TRANSPARENT)
.build(ctx),
)
.child(policy_lists_text_box)
.child(policy_list_text_box)
.child(
Button::new()
.id(ID_POLICY_LISTS_ADD_BUTTON)
.id(ID_POLICY_LIST_ADD_BUTTON)
.class(CLASS_ICON_ONLY)
.attach(Grid::row(4))
.attach(Grid::column(2))
@@ -266,10 +268,10 @@ impl Template for PolicyListView {
.enabled(false)
.min_size(32.0, 32.0)
.v_align("center")
.icon(material_icons_font::ADD_FONT_ICON)
.icon(material_icons_font_ttf::MD_ADD)
.on_click(move |ctx, _| {
ctx.get_mut::<PolicyListState>(id)
.action(Action::NewEntry(policy_lists_text_box));
.action(Action::NewEntry(policy_list_text_box));
true
})
.build(ctx),