ui: refactor colors, add disabled server message, optimize Android sensor delay.
This commit is contained in:
parent
de7be791a9
commit
c4a87ad755
15 changed files with 158 additions and 174 deletions
|
@ -5,7 +5,6 @@ import android.os.Bundle;
|
|||
import android.os.Process;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.OrientationEventListener;
|
||||
import com.google.androidgamesdk.GameActivity;
|
||||
|
@ -30,7 +29,7 @@ public class MainActivity extends GameActivity {
|
|||
|
||||
// Callback to update display cutouts at native code.
|
||||
OrientationEventListener orientationEventListener = new OrientationEventListener(this,
|
||||
SensorManager.SENSOR_DELAY_FASTEST) {
|
||||
SensorManager.SENSOR_DELAY_NORMAL) {
|
||||
@Override
|
||||
public void onOrientationChanged(int orientation) {
|
||||
onDisplayCutoutsChanged(Utils.getDisplayCutouts(MainActivity.this));
|
||||
|
@ -83,7 +82,6 @@ public class MainActivity extends GameActivity {
|
|||
|
||||
// Called from native code
|
||||
public void onExit() {
|
||||
Log.d("12345", "onExit");
|
||||
mManualExit = true;
|
||||
BackgroundService.stop(this);
|
||||
finish();
|
||||
|
|
|
@ -8,6 +8,7 @@ network:
|
|||
enable: Enable
|
||||
disable: Disable
|
||||
restart: Restart
|
||||
inactive_message: 'Enable server or choose/add another connection method by pressing %{dots} on top left corner of the screen.'
|
||||
sync_status:
|
||||
server_restarting: Server is restarting
|
||||
server_down: Server is down
|
||||
|
@ -22,7 +23,7 @@ sync_status:
|
|||
tx_hashset_range_proofs_validation: 'Validating state - range proofs: %{percent}%'
|
||||
tx_hashset_kernels_validation: 'Validating state - kernels: %{percent}%'
|
||||
tx_hashset_save: Finalizing chain state
|
||||
body_sync: Downloading blocks
|
||||
body_sync: Downloading blockchain
|
||||
body_sync_percent: 'Downloading blocks: %{percent}%'
|
||||
shutdown: Server is shutting down
|
||||
network_node:
|
||||
|
|
|
@ -8,6 +8,7 @@ network:
|
|||
enable: Включить
|
||||
disable: Выключить
|
||||
restart: Перезапустить
|
||||
inactive_message: 'Включите сервер или выберите/добавьте другой способ подключения, нажав %{dots} в левом верхнем углу экрана.'
|
||||
sync_status:
|
||||
server_restarting: Сервер перезапускается
|
||||
server_down: Сервер выключен
|
||||
|
@ -22,7 +23,7 @@ sync_status:
|
|||
tx_hashset_range_proofs_validation: 'Проверка доказательств: %{percent}%'
|
||||
tx_hashset_kernels_validation: 'Проверка ядер: %{percent}%'
|
||||
tx_hashset_save: Сохранение состояния цепи
|
||||
body_sync: Загрузка блоков
|
||||
body_sync: Загрузка блокчейна
|
||||
body_sync_percent: 'Загрузка блоков: %{percent}%'
|
||||
shutdown: Выключение сервера
|
||||
network_node:
|
||||
|
|
|
@ -16,8 +16,7 @@ use egui::{Color32, Context, RichText, Spinner, Stroke, Widget};
|
|||
use egui::os::OperatingSystem;
|
||||
use egui::style::Margin;
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_LIGHT, COLOR_YELLOW};
|
||||
use crate::gui::Navigator;
|
||||
use crate::gui::{Colors, Navigator};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::screens::Root;
|
||||
use crate::gui::views::{Modal, ModalId, ModalLocation, View};
|
||||
|
@ -38,7 +37,7 @@ impl App {
|
|||
pub fn ui(&mut self, ctx: &Context, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
fill: COLOR_LIGHT,
|
||||
fill: Colors::FILL,
|
||||
.. Default::default()
|
||||
})
|
||||
.show(ctx, |ui| {
|
||||
|
@ -64,11 +63,11 @@ impl App {
|
|||
}
|
||||
ui.add_space(16.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
Spinner::new().size(42.0).color(COLOR_YELLOW).ui(ui);
|
||||
Spinner::new().size(42.0).color(Colors::GRAY).ui(ui);
|
||||
ui.add_space(10.0);
|
||||
ui.label(RichText::new(Node::get_sync_status_text())
|
||||
.size(18.0)
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::INACTIVE_TEXT)
|
||||
);
|
||||
});
|
||||
ui.add_space(12.0);
|
||||
|
@ -82,7 +81,7 @@ impl App {
|
|||
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 0.0);
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal_exit.exit"), Color32::WHITE, || {
|
||||
View::button(ui, t!("modal_exit.exit"), Colors::WHITE, || {
|
||||
if !Node::is_running() {
|
||||
Self::exit(frame, cb);
|
||||
modal.close();
|
||||
|
@ -94,7 +93,7 @@ impl App {
|
|||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("modal.cancel"), Color32::WHITE, || {
|
||||
View::button(ui, t!("modal.cancel"), Colors::WHITE, || {
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,9 +12,23 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub const COLOR_YELLOW: egui::Color32 = egui::Color32::from_rgb(254, 241, 2);
|
||||
pub const COLOR_LIGHT: egui::Color32 = egui::Color32::from_gray(240);
|
||||
pub const COLOR_DARK: egui::Color32 = egui::Color32::from_gray(60);
|
||||
pub const COLOR_GRAY: egui::Color32 = egui::Color32::from_gray(120);
|
||||
pub const COLOR_GRAY_LIGHT: egui::Color32 = egui::Color32::from_gray(220);
|
||||
pub const COLOR_GRAY_DARK: egui::Color32 = egui::Color32::from_gray(80);
|
||||
use egui::Color32;
|
||||
|
||||
pub struct Colors;
|
||||
|
||||
impl Colors {
|
||||
pub const WHITE: Color32 = Color32::from_gray(253);
|
||||
pub const BLACK: Color32 = Color32::from_gray(2);
|
||||
pub const TRANSPARENT: Color32 = Color32::from_rgba_premultiplied(0, 0, 0, 0);
|
||||
pub const SEMI_TRANSPARENT: Color32 = Color32::from_black_alpha(100);
|
||||
pub const YELLOW: Color32 = Color32::from_rgb(254, 241, 2);
|
||||
pub const GOLD: Color32 = Color32::from_rgb(255, 215, 0);
|
||||
pub const FILL: Color32 = Color32::from_gray(240);
|
||||
pub const TITLE: Color32 = Color32::from_gray(60);
|
||||
pub const SUB_TITLE: Color32 = Color32::from_gray(80);
|
||||
pub const BUTTON: Color32 = Color32::from_gray(70);
|
||||
pub const GRAY: Color32 = Color32::from_gray(120);
|
||||
pub const STROKE: Color32 = Color32::from_gray(190);
|
||||
pub const INACTIVE_TEXT: Color32 = Color32::from_gray(150);
|
||||
pub const ITEM_STROKE: Color32 = Color32::from_gray(220);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@ pub use app::{App, PlatformApp};
|
|||
mod navigator;
|
||||
pub use navigator::Navigator;
|
||||
|
||||
mod colors;
|
||||
pub use colors::Colors;
|
||||
|
||||
pub mod platform;
|
||||
pub mod screens;
|
||||
pub mod views;
|
||||
pub mod icons;
|
||||
pub mod colors;
|
|
@ -20,17 +20,8 @@ use crate::gui::platform::PlatformCallbacks;
|
|||
use crate::gui::screens::{Screen, ScreenId};
|
||||
use crate::gui::views::{TitlePanel, TitlePanelAction, View};
|
||||
|
||||
pub struct Accounts {
|
||||
title: String
|
||||
}
|
||||
|
||||
impl Default for Accounts {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: t!("screen_accounts.title").to_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct Accounts;
|
||||
|
||||
impl Screen for Accounts {
|
||||
fn id(&self) -> ScreenId {
|
||||
|
@ -38,9 +29,7 @@ impl Screen for Accounts {
|
|||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||
let Self { title } = self;
|
||||
|
||||
TitlePanel::new(title)
|
||||
TitlePanel::new(t!("screen_accounts.title"))
|
||||
.ui(if !View::is_dual_panel_mode(frame) {
|
||||
TitlePanelAction::new(GLOBE, || {
|
||||
Navigator::toggle_side_panel();
|
||||
|
|
|
@ -30,6 +30,6 @@ mod network_metrics;
|
|||
mod network_mining;
|
||||
|
||||
pub trait NetworkTab {
|
||||
fn name(&self) -> &String;
|
||||
fn name(&self) -> String;
|
||||
fn ui(&mut self, ui: &mut egui::Ui);
|
||||
}
|
|
@ -15,12 +15,12 @@
|
|||
use std::cmp::min;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use egui::{Align2, Color32, RichText, Rounding, Sense, Separator, Stroke, Vec2, Widget};
|
||||
use egui::{Align2, RichText, Rounding, Sense, Separator, Stroke, Vec2, Widget};
|
||||
use egui::epaint::RectShape;
|
||||
use egui::style::Margin;
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
use crate::gui::Colors;
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_LIGHT, COLOR_YELLOW};
|
||||
use crate::gui::views::View;
|
||||
|
||||
/// Identifier for [`Modal`] content to draw at [`Modal::ui`].
|
||||
|
@ -128,7 +128,7 @@ impl Modal {
|
|||
.fixed_pos(ui.next_widget_position())
|
||||
.fixed_size(ui.available_size())
|
||||
.frame(egui::Frame {
|
||||
fill: Color32::from_black_alpha(100),
|
||||
fill: Colors::SEMI_TRANSPARENT,
|
||||
..Default::default()
|
||||
})
|
||||
.show(ui.ctx(), |ui| {
|
||||
|
@ -144,7 +144,7 @@ impl Modal {
|
|||
.anchor(self.modal_position(), Vec2::default())
|
||||
.frame(egui::Frame {
|
||||
rounding: Rounding::same(8.0),
|
||||
fill: COLOR_YELLOW,
|
||||
fill: Colors::YELLOW,
|
||||
..Default::default()
|
||||
})
|
||||
.show(ui.ctx(), |ui| {
|
||||
|
@ -202,7 +202,7 @@ impl Modal {
|
|||
let mut bg_shape = RectShape {
|
||||
rect,
|
||||
rounding,
|
||||
fill: COLOR_LIGHT,
|
||||
fill: Colors::FILL,
|
||||
stroke: Stroke::NONE,
|
||||
};
|
||||
let bg_idx = ui.painter().add(bg_shape);
|
||||
|
@ -232,7 +232,7 @@ impl Modal {
|
|||
sw: 0.0,
|
||||
se: 0.0,
|
||||
},
|
||||
fill: COLOR_YELLOW,
|
||||
fill: Colors::YELLOW,
|
||||
stroke: Stroke::NONE,
|
||||
};
|
||||
let bg_idx = ui.painter().add(bg_shape);
|
||||
|
@ -241,7 +241,10 @@ impl Modal {
|
|||
let title_resp = ui.allocate_ui_at_rect(rect, |ui| {
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
ui.add_space(8.0);
|
||||
ui.label(RichText::new(self.title.as_ref().unwrap()).size(20.0).color(COLOR_DARK));
|
||||
ui.label(RichText::new(self.title.as_ref().unwrap())
|
||||
.size(20.0)
|
||||
.color(Colors::TITLE)
|
||||
);
|
||||
ui.add_space(8.0);
|
||||
});
|
||||
}).response;
|
||||
|
@ -250,10 +253,12 @@ impl Modal {
|
|||
bg_shape.rect = title_resp.rect;
|
||||
ui.painter().set(bg_idx, bg_shape);
|
||||
|
||||
let (rect, _) = ui.allocate_exact_size(Vec2::new(ui.available_width(), 1.0),Sense::hover());
|
||||
// Draw line below title.
|
||||
let line_size = Vec2::new(ui.available_width(), 1.0);
|
||||
let (line_rect, _) = ui.allocate_exact_size(line_size, Sense::hover());
|
||||
let painter = ui.painter();
|
||||
painter.hline(rect.x_range(),
|
||||
painter.round_to_pixel(rect.center().y),
|
||||
painter.hline(line_rect.x_range(),
|
||||
painter.round_to_pixel(line_rect.center().y),
|
||||
View::DEFAULT_STROKE);
|
||||
}
|
||||
}
|
|
@ -20,12 +20,12 @@ use egui_extras::{Size, StripBuilder};
|
|||
use grin_chain::SyncStatus;
|
||||
use grin_core::global::ChainTypes;
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_GRAY, COLOR_GRAY_DARK, COLOR_YELLOW};
|
||||
use crate::gui::icons::{CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, PLUGS, POWER};
|
||||
use crate::gui::Navigator;
|
||||
use crate::gui::{Colors, Navigator};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{NetworkTab, View};
|
||||
use crate::gui::views::network_metrics::NetworkMetrics;
|
||||
use crate::gui::views::network_mining::NetworkMining;
|
||||
use crate::gui::views::network_node::NetworkNode;
|
||||
use crate::node::Node;
|
||||
|
||||
|
@ -33,7 +33,7 @@ use crate::node::Node;
|
|||
enum Mode {
|
||||
Node,
|
||||
Metrics,
|
||||
Miner,
|
||||
Mining,
|
||||
Tuning
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ pub struct Network {
|
|||
|
||||
node_view: NetworkNode,
|
||||
metrics_view: NetworkMetrics,
|
||||
mining_view: NetworkMining,
|
||||
}
|
||||
|
||||
impl Default for Network {
|
||||
|
@ -49,7 +50,8 @@ impl Default for Network {
|
|||
Self {
|
||||
current_mode: Mode::Node,
|
||||
node_view: NetworkNode::default(),
|
||||
metrics_view: NetworkMetrics::default()
|
||||
metrics_view: NetworkMetrics::default(),
|
||||
mining_view: NetworkMining::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +61,7 @@ impl Network {
|
|||
egui::TopBottomPanel::top("network_title")
|
||||
.resizable(false)
|
||||
.frame(egui::Frame {
|
||||
fill: COLOR_YELLOW,
|
||||
fill: Colors::YELLOW,
|
||||
inner_margin: Margin::same(0.0),
|
||||
outer_margin: Margin::same(0.0),
|
||||
stroke: Stroke::NONE,
|
||||
|
@ -83,7 +85,7 @@ impl Network {
|
|||
.frame(egui::Frame {
|
||||
stroke: View::DEFAULT_STROKE,
|
||||
inner_margin: Margin::same(4.0),
|
||||
fill: Color32::WHITE,
|
||||
fill: Colors::WHITE,
|
||||
.. Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
|
@ -110,8 +112,8 @@ impl Network {
|
|||
});
|
||||
});
|
||||
columns[2].vertical_centered_justified(|ui| {
|
||||
View::tab_button(ui, FACTORY, self.current_mode == Mode::Miner, || {
|
||||
self.current_mode = Mode::Miner;
|
||||
View::tab_button(ui, FACTORY, self.current_mode == Mode::Mining, || {
|
||||
self.current_mode = Mode::Mining;
|
||||
});
|
||||
});
|
||||
columns[3].vertical_centered_justified(|ui| {
|
||||
|
@ -134,7 +136,7 @@ impl Network {
|
|||
Mode::Tuning => {
|
||||
self.node_view.ui(ui);
|
||||
}
|
||||
Mode::Miner => {}
|
||||
Mode::Mining => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,8 +182,8 @@ impl Network {
|
|||
Mode::Metrics => {
|
||||
self.metrics_view.name()
|
||||
}
|
||||
Mode::Miner => {
|
||||
self.node_view.name()
|
||||
Mode::Mining => {
|
||||
self.mining_view.name()
|
||||
}
|
||||
Mode::Tuning => {
|
||||
self.node_view.name()
|
||||
|
@ -195,9 +197,9 @@ impl Network {
|
|||
strip.cell(|ui| {
|
||||
ui.add_space(2.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(title_text)
|
||||
ui.label(RichText::new(title_text.to_uppercase())
|
||||
.size(18.0)
|
||||
.color(COLOR_DARK));
|
||||
.color(Colors::TITLE));
|
||||
});
|
||||
});
|
||||
strip.cell(|ui| {
|
||||
|
@ -211,13 +213,13 @@ impl Network {
|
|||
};
|
||||
let (dark, bright) = (0.3, 1.0);
|
||||
let color_factor = if !idle {
|
||||
lerp(dark..=bright, ui.input().time.cos().abs())
|
||||
lerp(dark..=bright, ui.input().time.cos().abs()) as f32
|
||||
} else {
|
||||
bright
|
||||
bright as f32
|
||||
};
|
||||
|
||||
// Draw sync text
|
||||
let status_color_rgba = Rgba::from(COLOR_GRAY_DARK) * color_factor as f32;
|
||||
let status_color_rgba = Rgba::from(Colors::SUB_TITLE) * color_factor;
|
||||
let status_color = Color32::from(status_color_rgba);
|
||||
View::ellipsize_text(ui, Node::get_sync_status_text(), 15.0, status_color);
|
||||
|
||||
|
@ -233,18 +235,16 @@ impl Network {
|
|||
}
|
||||
|
||||
pub fn server_off_content(ui: &mut egui::Ui) {
|
||||
View::center_content(ui, [240.0, 214.0], |ui| {
|
||||
ui.label(RichText::new(PLUGS)
|
||||
.size(84.0)
|
||||
.color(Color32::from_gray(200))
|
||||
View::center_content(ui, [ui.available_width() - 48.0, 160.0], |ui| {
|
||||
let text = t!("network.inactive_message","dots" => DOTS_THREE_OUTLINE_VERTICAL);
|
||||
ui.label(RichText::new(text)
|
||||
.size(16.0)
|
||||
.color(Colors::INACTIVE_TEXT)
|
||||
);
|
||||
ui.add_space(-16.0);
|
||||
ui.label(RichText::new(Node::get_sync_status_text())
|
||||
.size(19.0)
|
||||
.color(Color32::from_gray(150))
|
||||
);
|
||||
ui.add_space(12.0);
|
||||
View::button(ui, format!("{} {}", POWER, t!("network.enable")), COLOR_YELLOW, || {
|
||||
|
||||
ui.add_space(10.0);
|
||||
|
||||
View::button(ui, format!("{} {}", POWER, t!("network.enable")), Colors::GOLD, || {
|
||||
Node::start(ChainTypes::Mainnet);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,30 +18,21 @@ use egui::{RichText, ScrollArea, Spinner, Widget};
|
|||
use grin_core::global::ChainTypes;
|
||||
use grin_servers::DiffBlock;
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_GRAY, COLOR_GRAY_LIGHT, COLOR_YELLOW};
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{AT, COINS, CUBE_TRANSPARENT, HASH, HOURGLASS_LOW, HOURGLASS_MEDIUM, PLUGS, POWER, TIMER};
|
||||
use crate::gui::views::{Network, NetworkTab, View};
|
||||
use crate::node::Node;
|
||||
|
||||
pub struct NetworkMetrics {
|
||||
title: String
|
||||
}
|
||||
|
||||
impl Default for NetworkMetrics {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: t!("network.metrics").to_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct NetworkMetrics;
|
||||
|
||||
const BLOCK_REWARD: f64 = 60.0;
|
||||
// 1 year is calculated as 365 days and 6 hours (31557600).
|
||||
const YEARLY_SUPPLY: f64 = ((60 * 60 * 24 * 365) + 6 * 60 * 60) as f64;
|
||||
|
||||
impl NetworkTab for NetworkMetrics {
|
||||
fn name(&self) -> &String {
|
||||
&self.title
|
||||
fn name(&self) -> String {
|
||||
t!("network.metrics")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
|
@ -51,11 +42,11 @@ impl NetworkTab for NetworkMetrics {
|
|||
Network::server_off_content(ui);
|
||||
} else {
|
||||
View::center_content(ui, [280.0, 160.0], |ui| {
|
||||
Spinner::new().size(104.0).color(COLOR_YELLOW).ui(ui);
|
||||
Spinner::new().size(104.0).color(Colors::GOLD).ui(ui);
|
||||
ui.add_space(18.0);
|
||||
ui.label(RichText::new(t!("network_metrics.loading"))
|
||||
.size(16.0)
|
||||
.color(Color32::from_gray(150))
|
||||
.color(Colors::INACTIVE_TEXT)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -177,60 +168,60 @@ fn draw_diff_block(ui: &mut egui::Ui, db: &DiffBlock, rounding: [bool; 2]) {
|
|||
se: if rounding[1] { 8.0 } else { 0.0 },
|
||||
},
|
||||
Color32::WHITE,
|
||||
Stroke { width: 1.0, color: COLOR_GRAY_LIGHT }
|
||||
Stroke { width: 1.0, color: Colors::ITEM_STROKE }
|
||||
);
|
||||
|
||||
ui.add_space(2.0);
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.add_space(5.0);
|
||||
ui.heading(RichText::new(HASH)
|
||||
.color(Color32::BLACK)
|
||||
.color(Colors::BLACK)
|
||||
.size(18.0));
|
||||
ui.add_space(2.0);
|
||||
|
||||
// Draw block hash
|
||||
ui.heading(RichText::new(db.block_hash.to_string())
|
||||
.color(Color32::BLACK)
|
||||
.color(Colors::BLACK)
|
||||
.size(18.0));
|
||||
});
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.add_space(6.0);
|
||||
ui.heading(RichText::new(CUBE_TRANSPARENT)
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::TITLE)
|
||||
.size(16.0));
|
||||
ui.add_space(4.0);
|
||||
|
||||
// Draw block difficulty and height
|
||||
ui.heading(RichText::new(db.difficulty.to_string())
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::TITLE)
|
||||
.size(16.0));
|
||||
ui.add_space(2.0);
|
||||
ui.heading(RichText::new(AT).color(COLOR_DARK).size(16.0));
|
||||
ui.heading(RichText::new(AT).color(Colors::TITLE).size(16.0));
|
||||
ui.add_space(2.0);
|
||||
ui.heading(RichText::new(db.block_height.to_string())
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::TITLE)
|
||||
.size(16.0));
|
||||
});
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.add_space(6.0);
|
||||
ui.heading(RichText::new(TIMER)
|
||||
.color(COLOR_GRAY)
|
||||
.color(Colors::GRAY)
|
||||
.size(16.0));
|
||||
ui.add_space(4.0);
|
||||
|
||||
// Draw block time
|
||||
ui.heading(RichText::new(format!("{}s", db.duration))
|
||||
.color(COLOR_GRAY)
|
||||
.color(Colors::GRAY)
|
||||
.size(16.0));
|
||||
ui.add_space(2.0);
|
||||
ui.heading(RichText::new(HOURGLASS_LOW).color(COLOR_GRAY).size(16.0));
|
||||
ui.heading(RichText::new(HOURGLASS_LOW).color(Colors::GRAY).size(16.0));
|
||||
ui.add_space(2.0);
|
||||
|
||||
let naive_datetime = NaiveDateTime::from_timestamp_opt(db.time as i64, 0);
|
||||
if naive_datetime.is_some() {
|
||||
let datetime: DateTime<Utc> = DateTime::from_utc(naive_datetime.unwrap(), Utc);
|
||||
ui.heading(RichText::new(datetime.to_string())
|
||||
.color(COLOR_GRAY)
|
||||
.color(Colors::GRAY)
|
||||
.size(16.0));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -15,21 +15,12 @@
|
|||
use egui::Ui;
|
||||
use crate::gui::views::NetworkTab;
|
||||
|
||||
pub struct NetworkMining {
|
||||
title: String
|
||||
}
|
||||
|
||||
impl Default for NetworkMining {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: t!("network.mining").to_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct NetworkMining;
|
||||
|
||||
impl NetworkTab for NetworkMining {
|
||||
fn name(&self) -> &String {
|
||||
&self.title
|
||||
fn name(&self) -> String {
|
||||
t!("network.mining")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut Ui) {
|
||||
|
|
|
@ -17,27 +17,18 @@ use egui::{Color32, RichText, Rounding, ScrollArea, Spinner, Widget};
|
|||
use egui_extras::{Size, StripBuilder};
|
||||
use grin_core::global::ChainTypes;
|
||||
use grin_servers::PeerStats;
|
||||
use crate::gui::Colors;
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_GRAY, COLOR_GRAY_LIGHT, COLOR_YELLOW};
|
||||
use crate::gui::icons::{AT, CUBE, DEVICES, FLOW_ARROW, HANDSHAKE, PACKAGE, PLUGS, PLUGS_CONNECTED, POWER, SHARE_NETWORK};
|
||||
use crate::gui::views::{Network, NetworkTab, View};
|
||||
use crate::node::Node;
|
||||
|
||||
pub struct NetworkNode {
|
||||
title: String
|
||||
}
|
||||
|
||||
impl Default for NetworkNode {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: t!("network.node").to_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct NetworkNode;
|
||||
|
||||
impl NetworkTab for NetworkNode {
|
||||
fn name(&self) -> &String {
|
||||
&self.title
|
||||
fn name(&self) -> String {
|
||||
t!("network.node")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
|
@ -47,7 +38,7 @@ impl NetworkTab for NetworkNode {
|
|||
Network::server_off_content(ui);
|
||||
} else {
|
||||
ui.centered_and_justified(|ui| {
|
||||
Spinner::new().size(104.0).color(COLOR_YELLOW).ui(ui);
|
||||
Spinner::new().size(104.0).color(Colors::GOLD).ui(ui);
|
||||
});
|
||||
}
|
||||
return;
|
||||
|
@ -218,51 +209,51 @@ fn draw_peer_stats(ui: &mut egui::Ui, peer: &PeerStats, rounding: [bool; 2]) {
|
|||
se: if rounding[1] { 8.0 } else { 0.0 },
|
||||
},
|
||||
Color32::WHITE,
|
||||
Stroke { width: 1.0, color: COLOR_GRAY_LIGHT }
|
||||
Stroke { width: 1.0, color: Colors::ITEM_STROKE }
|
||||
);
|
||||
|
||||
ui.add_space(2.0);
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.add_space(5.0);
|
||||
ui.heading(RichText::new(PLUGS_CONNECTED)
|
||||
.color(Color32::BLACK)
|
||||
.color(Colors::BLACK)
|
||||
.size(18.0));
|
||||
ui.add_space(3.0);
|
||||
|
||||
// Draw peer address
|
||||
ui.heading(RichText::new(&peer.addr)
|
||||
.color(Color32::BLACK)
|
||||
.color(Colors::BLACK)
|
||||
.size(18.0));
|
||||
});
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.add_space(6.0);
|
||||
ui.heading(RichText::new(PACKAGE)
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::TITLE)
|
||||
.size(16.0));
|
||||
ui.add_space(4.0);
|
||||
|
||||
// Draw peer difficulty and height
|
||||
ui.heading(RichText::new(peer.total_difficulty.to_string())
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::TITLE)
|
||||
.size(16.0));
|
||||
ui.add_space(2.0);
|
||||
ui.heading(RichText::new(AT).color(COLOR_DARK).size(16.0));
|
||||
ui.heading(RichText::new(AT).color(Colors::TITLE).size(16.0));
|
||||
ui.add_space(2.0);
|
||||
ui.heading(RichText::new(peer.height.to_string())
|
||||
.color(COLOR_DARK)
|
||||
.color(Colors::TITLE)
|
||||
.size(16.0));
|
||||
});
|
||||
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.add_space(6.0);
|
||||
ui.heading(RichText::new(DEVICES)
|
||||
.color(COLOR_GRAY)
|
||||
.color(Colors::GRAY)
|
||||
.size(16.0));
|
||||
ui.add_space(4.0);
|
||||
|
||||
// Draw peer user-agent
|
||||
ui.heading(RichText::new(&peer.user_agent)
|
||||
.color(COLOR_GRAY)
|
||||
.color(Colors::GRAY)
|
||||
.size(16.0));
|
||||
});
|
||||
ui.add_space(2.0);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
use egui::style::Margin;
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_YELLOW};
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::views::View;
|
||||
|
||||
pub struct TitlePanelAction<'action> {
|
||||
|
@ -34,19 +34,17 @@ pub struct TitlePanel {
|
|||
}
|
||||
|
||||
impl TitlePanel {
|
||||
const PANEL_SIZE: f32 = 52.0;
|
||||
const PANEL_HEIGHT: f32 = 52.0;
|
||||
|
||||
pub fn new(title: &String) -> Self {
|
||||
pub fn new(title: String) -> Self {
|
||||
Self { title: title.to_uppercase() }
|
||||
}
|
||||
|
||||
pub fn ui(&self, l: Option<TitlePanelAction>, r: Option<TitlePanelAction>, ui: &mut egui::Ui) {
|
||||
let Self { title } = self;
|
||||
|
||||
egui::TopBottomPanel::top("title_panel")
|
||||
.resizable(false)
|
||||
.frame(egui::Frame {
|
||||
fill: COLOR_YELLOW,
|
||||
fill: Colors::YELLOW,
|
||||
inner_margin: Margin::same(0.0),
|
||||
outer_margin: Margin::same(0.0),
|
||||
stroke: egui::Stroke::NONE,
|
||||
|
@ -54,33 +52,30 @@ impl TitlePanel {
|
|||
})
|
||||
.show_inside(ui, |ui| {
|
||||
StripBuilder::new(ui)
|
||||
.size(Size::exact(Self::PANEL_SIZE))
|
||||
.size(Size::exact(Self::PANEL_HEIGHT))
|
||||
.vertical(|mut strip| {
|
||||
strip.strip(|builder| {
|
||||
builder
|
||||
.size(Size::exact(Self::PANEL_SIZE))
|
||||
.size(Size::exact(Self::PANEL_HEIGHT))
|
||||
.size(Size::remainder())
|
||||
.size(Size::exact(Self::PANEL_SIZE))
|
||||
.size(Size::exact(Self::PANEL_HEIGHT))
|
||||
.horizontal(|mut strip| {
|
||||
strip.cell(|ui| {
|
||||
show_action(ui, l.as_ref());
|
||||
self.draw_action(ui, l);
|
||||
});
|
||||
strip.cell(|ui| {
|
||||
ui.centered_and_justified(|ui| {
|
||||
View::ellipsize_text(ui, title.into(), 20.0, COLOR_DARK);
|
||||
});
|
||||
self.draw_title(ui);
|
||||
});
|
||||
strip.cell(|ui| {
|
||||
show_action(ui, r.as_ref());
|
||||
self.draw_action(ui, r);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn show_action(ui: &mut egui::Ui, action: Option<&TitlePanelAction>) {
|
||||
fn draw_action(&self, ui: &mut egui::Ui, action: Option<TitlePanelAction>) {
|
||||
if action.is_some() {
|
||||
let action = action.unwrap();
|
||||
ui.centered_and_justified(|ui| {
|
||||
|
@ -91,3 +86,10 @@ fn show_action(ui: &mut egui::Ui, action: Option<&TitlePanelAction>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn draw_title(&self, ui: &mut egui::Ui) {
|
||||
let Self { title } = self;
|
||||
ui.centered_and_justified(|ui| {
|
||||
View::ellipsize_text(ui, title.into(), 20.0, Colors::TITLE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,19 +12,19 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::epaint::{Color32, FontId, Rounding, Stroke};
|
||||
use egui::text::{LayoutJob, TextFormat};
|
||||
use egui::{Button, PointerState, Response, RichText, Sense, Vec2, Widget};
|
||||
use egui::epaint::{Color32, FontId, Rounding, Stroke};
|
||||
use egui::epaint::text::TextWrapping;
|
||||
use egui::text::{LayoutJob, TextFormat};
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
|
||||
use crate::gui::colors::{COLOR_DARK, COLOR_GRAY, COLOR_LIGHT, COLOR_GRAY_LIGHT, COLOR_GRAY_DARK, COLOR_YELLOW};
|
||||
use crate::gui::Colors;
|
||||
|
||||
pub struct View;
|
||||
|
||||
impl View {
|
||||
/// Default stroke around views.
|
||||
pub const DEFAULT_STROKE: Stroke = Stroke { width: 1.0, color: Color32::from_gray(190) };
|
||||
pub const DEFAULT_STROKE: Stroke = Stroke { width: 1.0, color: Colors::STROKE };
|
||||
|
||||
/// Default width of side panel at application UI.
|
||||
pub const SIDE_PANEL_MIN_WIDTH: i64 = 400;
|
||||
|
@ -56,7 +56,7 @@ impl View {
|
|||
|
||||
/// Sub-header with uppercase characters and more lighter color.
|
||||
pub fn sub_header(ui: &mut egui::Ui, text: String) {
|
||||
ui.label(RichText::new(text.to_uppercase()).size(16.0).color(COLOR_GRAY_DARK));
|
||||
ui.label(RichText::new(text.to_uppercase()).size(16.0).color(Colors::SUB_TITLE));
|
||||
}
|
||||
|
||||
/// Temporary button click optimization for touch screens.
|
||||
|
@ -77,9 +77,9 @@ impl View {
|
|||
// Disable stroke around title buttons on hover
|
||||
ui.style_mut().visuals.widgets.active.bg_stroke = Stroke::NONE;
|
||||
|
||||
let wt = RichText::new(icon.to_string()).size(24.0).color(COLOR_DARK);
|
||||
let wt = RichText::new(icon.to_string()).size(24.0).color(Colors::TITLE);
|
||||
let br = Button::new(wt)
|
||||
.fill(Color32::TRANSPARENT)
|
||||
.fill(Colors::TRANSPARENT)
|
||||
.ui(ui).interact(Sense::click_and_drag());
|
||||
|
||||
Self::on_button_click(ui, br, action);
|
||||
|
@ -89,8 +89,8 @@ impl View {
|
|||
/// Tab button with white background fill color, contains only icon.
|
||||
pub fn tab_button(ui: &mut egui::Ui, icon: &str, active: bool, action: impl FnOnce()) {
|
||||
let text_color = match active {
|
||||
true => { COLOR_GRAY_DARK }
|
||||
false => { COLOR_DARK }
|
||||
true => { Colors::TITLE }
|
||||
false => { Colors::SUB_TITLE }
|
||||
};
|
||||
let wt = RichText::new(icon.to_string()).size(24.0).color(text_color);
|
||||
|
||||
|
@ -100,8 +100,8 @@ impl View {
|
|||
};
|
||||
|
||||
let color = match active {
|
||||
true => { COLOR_LIGHT }
|
||||
false => { Color32::WHITE }
|
||||
true => { Colors::FILL }
|
||||
false => { Colors::WHITE }
|
||||
};
|
||||
let br = Button::new(wt)
|
||||
.stroke(stroke)
|
||||
|
@ -113,7 +113,7 @@ impl View {
|
|||
|
||||
/// Draw [`Button`] with specified background fill color.
|
||||
pub fn button(ui: &mut egui::Ui, text: String, fill_color: Color32, action: impl FnOnce()) {
|
||||
let wt = RichText::new(text.to_uppercase()).size(18.0).color(COLOR_GRAY_DARK);
|
||||
let wt = RichText::new(text.to_uppercase()).size(18.0).color(Colors::BUTTON);
|
||||
let br = Button::new(wt)
|
||||
.stroke(Self::DEFAULT_STROKE)
|
||||
.fill(fill_color)
|
||||
|
@ -139,8 +139,8 @@ impl View {
|
|||
sw: if r[2] { 8.0 } else { 0.0 },
|
||||
se: if r[3] { 8.0 } else { 0.0 },
|
||||
},
|
||||
Color32::WHITE,
|
||||
Stroke { width: 1.0, color: COLOR_GRAY_LIGHT },
|
||||
Colors::WHITE,
|
||||
Stroke { width: 1.0, color: Colors::ITEM_STROKE },
|
||||
);
|
||||
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
|
@ -150,7 +150,7 @@ impl View {
|
|||
// Draw box value
|
||||
let mut job = LayoutJob::single_section(value, TextFormat {
|
||||
font_id: FontId::proportional(18.0),
|
||||
color: Color32::BLACK,
|
||||
color: Colors::BLACK,
|
||||
.. Default::default()
|
||||
});
|
||||
job.wrap = TextWrapping {
|
||||
|
@ -162,7 +162,7 @@ impl View {
|
|||
ui.label(job);
|
||||
|
||||
// Draw box label
|
||||
ui.label(RichText::new(label).color(COLOR_GRAY).size(15.0));
|
||||
ui.label(RichText::new(label).color(Colors::GRAY).size(15.0));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue