diff --git a/100_core/src/gplx/Err_.java b/100_core/src/gplx/Err_.java index d662a54a5..d71e6dae1 100644 --- a/100_core/src/gplx/Err_.java +++ b/100_core/src/gplx/Err_.java @@ -54,7 +54,7 @@ public class Err_ { public static String Message_gplx_full(Exception e) {return Cast_or_make(e).To_str__full();} public static String Message_gplx_log(Exception e) {return Cast_or_make(e).To_str__log();} public static String Message_lang(Throwable e) { - return (e.getClass() == Error.class) + return Error.class.isAssignableFrom(e.getClass()) ? e.toString() // error has null for "getMessage()" return "toString()" instead : e.getMessage(); } diff --git a/400_xowa/src/gplx/xowa/apps/apis/xowa/gui/Xoapi_browser.java b/400_xowa/src/gplx/xowa/apps/apis/xowa/gui/Xoapi_browser.java index a5cae5c1a..42a13d4c8 100644 --- a/400_xowa/src/gplx/xowa/apps/apis/xowa/gui/Xoapi_browser.java +++ b/400_xowa/src/gplx/xowa/apps/apis/xowa/gui/Xoapi_browser.java @@ -36,10 +36,14 @@ public class Xoapi_browser implements Gfo_invk { public Xoapi_prog Prog() {return prog;} private Xoapi_prog prog = new Xoapi_prog(); public Xoapi_info Info() {return info;} private Xoapi_info info = new Xoapi_info(); public Xoapi_prog_log Prog_log() {return prog_log;} private Xoapi_prog_log prog_log = new Xoapi_prog_log(); - private void Nightmode_toggle() { + public void Nightmode_toggle() { // toggle nightmode - app.Gui_mgr().Nightmode_mgr().Enabled_toggle(); - + boolean val = !app.Gui_mgr().Nightmode_mgr().Enabled(); + app.Gui_mgr().Nightmode_mgr().Enabled_(val); + app.Cfg().Set_bool_app(gplx.xowa.guis.views.nightmodes.Xog_nightmode_mgr.Cfg__enabled, val); + this.Nightmode_reload(); + } + public void Nightmode_reload() { // toggle nightmode for all other tabs gplx.xowa.guis.views.Xog_tab_mgr tab_mgr = app.Gui_mgr().Browser_win().Tab_mgr(); int len = tab_mgr.Tabs_len(); diff --git a/400_xowa/src/gplx/xowa/guis/Xoa_gui_mgr.java b/400_xowa/src/gplx/xowa/guis/Xoa_gui_mgr.java index 8a31209f9..bccc079f7 100644 --- a/400_xowa/src/gplx/xowa/guis/Xoa_gui_mgr.java +++ b/400_xowa/src/gplx/xowa/guis/Xoa_gui_mgr.java @@ -91,6 +91,7 @@ public class Xoa_gui_mgr implements Gfo_evt_itm, Gfo_invk { menu_mgr.Menu_bldr().Init_by_kit(app, kit, app.Fsys_mgr().Bin_xowa_file_dir().GenSubDir_nest("app.menu")); menu_mgr.Init_by_kit(); bnd_mgr.Init_by_kit(app); + nightmode_mgr.Init_by_kit(app); Gfo_evt_mgr_.Sub_same_many(app.Usere(), this, Xoue_user.Evt_lang_changed); app.Sys_cfg().Lang_(app.Sys_cfg().Lang()); // NOTE: force refresh of lang. must occur after after gui_mgr init, else menu lbls will break } diff --git a/400_xowa/src/gplx/xowa/guis/views/nightmodes/Xog_nightmode_mgr.java b/400_xowa/src/gplx/xowa/guis/views/nightmodes/Xog_nightmode_mgr.java index 803f4c430..fa2ce9077 100644 --- a/400_xowa/src/gplx/xowa/guis/views/nightmodes/Xog_nightmode_mgr.java +++ b/400_xowa/src/gplx/xowa/guis/views/nightmodes/Xog_nightmode_mgr.java @@ -16,49 +16,23 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt package gplx.xowa.guis.views.nightmodes; import gplx.*; import gplx.xowa.*; import gplx.xowa.guis.*; import gplx.xowa.guis.views.*; import gplx.gfui.controls.elems.*; import gplx.gfui.draws.*; import gplx.xowa.specials.xowa.default_tab.*; -public class Xog_nightmode_mgr { +public class Xog_nightmode_mgr implements Gfo_invk { private Xoae_app app; private boolean enabled; private Xog_win_itm win; + private GfuiElemBase[] backcolor_elems, forecolor_elems; public void Init_by_app(Xoae_app app) { this.app = app; this.win = app.Gui_mgr().Browser_win(); + app.Cfg().Sub_many_app(this + , Cfg__enabled + , Cfg__night_back, Cfg__night_fore, Cfg__night_edge + , Cfg__day_back, Cfg__day_fore, Cfg__day_edge + ); } - public boolean Enabled() {return enabled;} - public void Enabled_by_cfg() { - Enabled_(app.Cfg().Get_bool_app_or(Cfg__nightmode_enabled, false)); - } - public void Enabled_toggle() { - boolean val = !enabled; - Enabled_(val); - app.Cfg().Set_bool_app(Cfg__nightmode_enabled, val); - } - private void Enabled_(boolean v) { - this.enabled = v; - - // get colors - ColorAdp backcolor, forecolor, edgecolor; - if (enabled) { - backcolor = Parse_from_cfg(app, "xowa.gui.nightmode.nightcolors.backcolor", ColorAdp_.White); - forecolor = Parse_from_cfg(app, "xowa.gui.nightmode.nightcolors.forecolor", ColorAdp_.Black); - edgecolor = Parse_from_cfg(app, "xowa.gui.nightmode.nightcolors.edgecolor", ColorAdp_.LightGray); - } - else { - backcolor = Parse_from_cfg(app, "xowa.gui.nightmode.daycolors.backcolor", ColorAdp_.Black); - forecolor = Parse_from_cfg(app, "xowa.gui.nightmode.daycolors.forecolor", ColorAdp_.White); - edgecolor = Parse_from_cfg(app, "xowa.gui.nightmode.daycolors.edgecolor", ColorAdp_.Black); - } - - // set back / fore for window and tab - win.Win_box().BackColor_(backcolor); - win.Tab_mgr().Tab_mgr().BackColor_(backcolor); - win.Tab_mgr().Tab_mgr().Btns_selected_background_(backcolor); - win.Tab_mgr().Tab_mgr().Btns_selected_foreground_(forecolor); - win.Tab_mgr().Tab_mgr().Btns_unselected_background_(backcolor); - win.Tab_mgr().Tab_mgr().Btns_unselected_foreground_(forecolor); - + public void Init_by_kit(Xoae_app app) { // set back / fore for other elems - GfuiElemBase[] elems = new GfuiElemBase[] + this.backcolor_elems = this.forecolor_elems = new GfuiElemBase[] { win.Toolbar_grp() , win.Go_bwd_btn() , win.Go_fwd_btn() @@ -73,16 +47,58 @@ public class Xog_nightmode_mgr { , win.Find_box() , win.Prog_box() }; - for (GfuiElemBase elem : elems) - elem.BackColor_(backcolor).ForeColor_(forecolor); - - // set edge colors - win.Url_box().Border_color_(edgecolor); - win.Search_box().Border_color_(edgecolor); - win.Find_box().Border_color_(edgecolor); - win.Prog_box().Border_color_(backcolor); + } + private void Set_color(int color_group_type, ColorAdp color) { + if (color == null) return; // null passed by invk + switch (color_group_type) { + case COLOR_GROUP_BACK: + win.Win_box().BackColor_(color); + win.Tab_mgr().Tab_mgr().BackColor_(color); + win.Tab_mgr().Tab_mgr().Btns_selected_background_(color); + win.Tab_mgr().Tab_mgr().Btns_unselected_background_(color); + for (GfuiElemBase elem : backcolor_elems) + elem.BackColor_(color); + win.Prog_box().Border_color_(color); + break; + case COLOR_GROUP_FORE: + win.Tab_mgr().Tab_mgr().Btns_selected_foreground_(color); + win.Tab_mgr().Tab_mgr().Btns_unselected_foreground_(color); + for (GfuiElemBase elem : forecolor_elems) + elem.ForeColor_(color); + break; + case COLOR_GROUP_EDGE: + win.Url_box().Border_color_(color); + win.Search_box().Border_color_(color); + win.Find_box().Border_color_(color); + break; + } - // change button icons + } + public boolean Enabled() {return enabled;} + public void Enabled_by_cfg() { + Enabled_(app.Cfg().Get_bool_app_or(Cfg__enabled, false)); + } + public void Enabled_(boolean v) { + // set enabled + this.enabled = v; + + // set colors + ColorAdp backcolor, forecolor, edgecolor; + if (enabled) { + backcolor = Parse_from_cfg(app, Cfg__night_back, ColorAdp_.White); + forecolor = Parse_from_cfg(app, Cfg__night_fore, ColorAdp_.Black); + edgecolor = Parse_from_cfg(app, Cfg__night_edge, ColorAdp_.LightGray); + } + else { + backcolor = Parse_from_cfg(app, Cfg__day_back, ColorAdp_.Black); + forecolor = Parse_from_cfg(app, Cfg__day_fore, ColorAdp_.White); + edgecolor = Parse_from_cfg(app, Cfg__day_edge, ColorAdp_.Black); + } + Set_color(COLOR_GROUP_BACK, backcolor); + Set_color(COLOR_GROUP_FORE, forecolor); + Set_color(COLOR_GROUP_EDGE, edgecolor); + + // set button icons // note that nightmode needs 16px and unresized b/c swt interpolates white pixels when resizing images (even when downsizing?) // note that daymode needs 32px and resized b/c resizing "blurs" image which looks better Io_url img_dir = app.Fsys_mgr().Bin_xowa_file_dir().GenSubDir_nest("app.window", enabled ? "16px" : "32px"); @@ -94,8 +110,32 @@ public class Xog_nightmode_mgr { win.Find_bwd_btn().Btn_img_(app.Gui_mgr().Kit().New_img_load(img_dir.GenSubFil("find_bwd.png"))); win.Find_fwd_btn().Btn_img_(app.Gui_mgr().Kit().New_img_load(img_dir.GenSubFil("find_fwd.png"))); } + public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + if (ctx.Match(k, Cfg__enabled)) {this.Enabled_(m.ReadBool("v")); app.Api_root().Gui().Browser().Nightmode_reload();} + else if (ctx.MatchIn(k, Cfg__night_back)) {if (enabled) this.Set_color(COLOR_GROUP_BACK, Parse(k, m.ReadStr("v"), null));} + else if (ctx.MatchIn(k, Cfg__night_fore)) {if (enabled) this.Set_color(COLOR_GROUP_FORE, Parse(k, m.ReadStr("v"), null));} + else if (ctx.MatchIn(k, Cfg__night_edge)) {if (enabled) this.Set_color(COLOR_GROUP_EDGE, Parse(k, m.ReadStr("v"), null));} + else if (ctx.MatchIn(k, Cfg__day_back)) {if (!enabled) this.Set_color(COLOR_GROUP_BACK, Parse(k, m.ReadStr("v"), null));} + else if (ctx.MatchIn(k, Cfg__day_fore)) {if (!enabled) this.Set_color(COLOR_GROUP_FORE, Parse(k, m.ReadStr("v"), null));} + else if (ctx.MatchIn(k, Cfg__day_edge)) {if (!enabled) this.Set_color(COLOR_GROUP_EDGE, Parse(k, m.ReadStr("v"), null));} + else return Gfo_invk_.Rv_unhandled; + return this; + } + public static final String + Cfg__enabled = "xowa.gui.nightmode.enabled" + , Cfg__night_back = "xowa.gui.nightmode.nightcolors.backcolor" + , Cfg__night_fore = "xowa.gui.nightmode.nightcolors.forecolor" + , Cfg__night_edge = "xowa.gui.nightmode.nightcolors.edgecolor" + , Cfg__day_back = "xowa.gui.nightmode.daycolors.backcolor" + , Cfg__day_fore = "xowa.gui.nightmode.daycolors.forecolor" + , Cfg__day_edge = "xowa.gui.nightmode.daycolors.edgecolor" + ; + + private static final int COLOR_GROUP_BACK = 0, COLOR_GROUP_FORE = 1, COLOR_GROUP_EDGE = 2; private static ColorAdp Parse_from_cfg(Xoa_app app, String key, ColorAdp or) { - String val = app.Cfg().Get_str_app_or(key, null); + return Parse(key, app.Cfg().Get_str_app_or(key, null), or); + } + private static ColorAdp Parse(String key, String val, ColorAdp or) { try { return val == null ? or : ColorAdp_.parse_hex_("#00" + val); // parse_hex requires leading "#00" } catch (Exception e) { @@ -103,5 +143,4 @@ public class Xog_nightmode_mgr { return or; } } - private static final String Cfg__nightmode_enabled = "xowa.gui.nightmode.enabled"; } diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_mgr_tst.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_mgr_tst.java index b5c2e679d..f8f8e0f0a 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_mgr_tst.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_mgr_tst.java @@ -26,7 +26,7 @@ public class Xoh_page_wtr_mgr_tst { portal_mgr.Init_assert(); Xoh_page_wtr_mgr page_wtr_mgr = new Xoh_page_wtr_mgr(true); page_wtr_mgr.Gen(wiki.Parser_mgr().Ctx().Page(), Xopg_page_.Tid_read); - Tfds.Eq(String_.new_a7(portal_mgr.Div_logo_bry()), "/site/en.wikipedia.org/wiki/"); + Tfds.Eq(String_.new_a7(portal_mgr.Div_logo_bry(true)), "/site/en.wikipedia.org/wiki/"); } @Test public void Skip__math__basic() { Xop_fxt fxt = Xop_fxt.New_app_html(); diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java index 6423a88ca..6bb4c5cc4 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java @@ -93,13 +93,14 @@ public class Xoh_page_wtr_wkr { byte[] page_display_title = Xoh_page_wtr_wkr_.Bld_page_name(tmp_bfr, page_ttl, page.Html_data().Display_ttl()); page.Html_data().Custom_tab_name_(page_name); // set tab_name to page_name; note that if null, gui code will ignore and use Ttl.Page_txt; PAGE: zh.w:釣魚臺列嶼主權問題 DATE:2015-10-05 Xow_portal_mgr portal_mgr = wiki.Html_mgr().Portal_mgr().Init_assert(); + boolean nightmode_enabled = app.Gui_mgr().Nightmode_mgr().Enabled(); fmtr.Bld_bfr_many(bfr , root_dir_bry, Xoa_app_.Version, Xoa_app_.Build_date, app.Tcp_server().Running_str() , page.Db().Page().Id(), page.Ttl().Full_db() , page_name, page.Html_data().Page_heading().Init(wiki, html_gen_tid == Xopg_page_.Tid_read, page.Html_data(), page.Ttl().Full_db(), page_display_title) , modified_on_msg , mgr.Css_common_bry(), mgr.Css_wiki_bry() - , mgr.Css_night_bry(app.Gui_mgr().Nightmode_mgr().Enabled()) + , mgr.Css_night_bry(nightmode_enabled) , page.Html_data().Head_mgr().Init(app, wiki, page).Init_dflts() , page.Lang().Dir_ltr_bry(), page.Html_data().Indicators(), page_content_sub, wiki.Html_mgr().Portal_mgr().Div_jump_to(), wiki.Xtn_mgr().Xtn_pgbnr().Write_html(page, ctx, hctx), page_body_class, html_content_editable , page_data, wdata_lang_wtr @@ -108,7 +109,7 @@ public class Xoh_page_wtr_wkr { , portal_mgr.Div_personal_bry() , portal_mgr.Div_ns_bry(wiki.Utl__bfr_mkr(), page_ttl, wiki.Ns_mgr()) , portal_mgr.Div_view_bry(wiki.Utl__bfr_mkr(), html_gen_tid, page.Html_data().Xtn_search_text()) - , portal_mgr.Div_logo_bry(), portal_mgr.Div_home_bry(), new Xopg_xtn_skin_fmtr_arg(page, Xopg_xtn_skin_itm_tid.Tid_sidebar) + , portal_mgr.Div_logo_bry(nightmode_enabled), portal_mgr.Div_home_bry(), new Xopg_xtn_skin_fmtr_arg(page, Xopg_xtn_skin_itm_tid.Tid_sidebar) , portal_mgr.Div_sync_bry(tmp_bfr, wiki.Page_mgr().Sync_mgr().Manual_enabled(), wiki, page) , portal_mgr.Div_wikis_bry(wiki.Utl__bfr_mkr()) , portal_mgr.Sidebar_mgr().Html_bry() diff --git a/400_xowa/src/gplx/xowa/htmls/portal/Xow_portal_mgr.java b/400_xowa/src/gplx/xowa/htmls/portal/Xow_portal_mgr.java index d19a6cb92..7a690fe11 100644 --- a/400_xowa/src/gplx/xowa/htmls/portal/Xow_portal_mgr.java +++ b/400_xowa/src/gplx/xowa/htmls/portal/Xow_portal_mgr.java @@ -66,7 +66,8 @@ public class Xow_portal_mgr implements Gfo_invk { byte[] wiki_user_name = wiki.User().Name(); div_personal_bry = Init_fmtr(tmp_bfr, eval_mgr, div_personal_fmtr, Bry_.Add(Xoh_href_.Bry__wiki, wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Tid__user).Name_db_w_colon(), wiki_user_name), wiki_user_name, Ns_cls_by_id(wiki.Ns_mgr(), Xow_ns_.Tid__user), Bry_.Add(Xoh_href_.Bry__wiki, wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Tid__user_talk).Name_db_w_colon(), wiki_user_name), Ns_cls_by_id(wiki.Ns_mgr(), Xow_ns_.Tid__user_talk)); byte[] main_page_href_bry = tmp_bfr.Add(Xoh_href_.Bry__site).Add(wiki.Domain_bry()).Add(Xoh_href_.Bry__wiki).To_bry_and_clear(); // NOTE: build /site/en.wikipedia.org/wiki/ href; no Main_Page, as that will be inserted by Xoh_href_parser - div_logo_bry = Init_fmtr(tmp_bfr, eval_mgr, div_logo_fmtr, main_page_href_bry, fsys_lnx_encoder.Encode_to_file_protocol(wiki.Appe().Usere().Fsys_mgr().Wiki_root_dir().GenSubFil_nest(wiki.Domain_str(), "html", "logo.png"))); + div_logo_day = Init_fmtr(tmp_bfr, eval_mgr, div_logo_fmtr, main_page_href_bry, fsys_lnx_encoder.Encode_to_file_protocol(wiki.Appe().Usere().Fsys_mgr().Wiki_root_dir().GenSubFil_nest(wiki.Domain_str(), "html", "logo.png"))); + div_logo_night = Init_fmtr(tmp_bfr, eval_mgr, div_logo_fmtr, main_page_href_bry, fsys_lnx_encoder.Encode_to_file_protocol(wiki.Appe().Fsys_mgr().Bin_xowa_dir().GenSubFil_nest("html", "css", "nightmode", "logo.png"))); div_home_bry = Init_fmtr(tmp_bfr, eval_mgr, div_home_fmtr); div_wikis_fmtr.Eval_mgr_(eval_mgr); Xow_msg_mgr msg_mgr = wiki.Msg_mgr(); @@ -116,7 +117,7 @@ public class Xow_portal_mgr implements Gfo_invk { div_view_fmtr.Bld_bfr_many(tmp_bfr, read_cls, edit_cls, html_cls, search_text); return tmp_bfr.To_bry_and_rls(); } public static final byte[] Cls_selected_y = Bry_.new_a7("selected"), Cls_new = Bry_.new_a7("new"), Cls_display_none = Bry_.new_a7("xowa_display_none"); - public byte[] Div_logo_bry() {return div_logo_bry;} private byte[] div_logo_bry = Bry_.Empty; + public byte[] Div_logo_bry(boolean nightmode) {return nightmode ? div_logo_night : div_logo_day;} private byte[] div_logo_day = Bry_.Empty, div_logo_night = Bry_.Empty; public byte[] Div_home_bry() {return sidebar_enabled ? div_home_bry : Bry_.Empty;} private byte[] div_home_bry = Bry_.Empty; public byte[] Div_sync_bry(Bry_bfr tmp_bfr, boolean manual_enabled, Xow_wiki wiki, Xoa_page page) { // only show update_html if wmf; DATE:2016-08-31