From f6a10475cace54189d4b375500f00ff133d3c53d Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Sat, 31 Oct 2026 00:40:04 -0400 Subject: [PATCH] Flash an X instead of a status window when the user inputs the wrong answer --- package.json | 7 ++++++ resources-base/ATTRIBUTION.md | 3 +++ resources-base/x.svg | 39 +++++++++++++++++++++++++++++++ resources/x.png | Bin 0 -> 5091 bytes src/c/main.c | 42 ++++++++++++++++++++++++++-------- src/c/main.h | 3 +-- 6 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 resources-base/x.svg create mode 100644 resources/x.png diff --git a/package.json b/package.json index c265943..ec42c44 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,13 @@ "spaceOptimization": "storage", "type": "bitmap" }, + { + "file": "x.png", + "memoryFormat": "Smallest", + "name": "X", + "spaceOptimization": "storage", + "type": "bitmap" + }, { "file": "check.png", "memoryFormat": "Smallest", diff --git a/resources-base/ATTRIBUTION.md b/resources-base/ATTRIBUTION.md index ebfbf89..d8b28ed 100644 --- a/resources-base/ATTRIBUTION.md +++ b/resources-base/ATTRIBUTION.md @@ -1,3 +1,6 @@ +# X Icon +Modified version of [x mark by Lewen Design](https://thenounproject.com/icon/x-mark-7924184/) (CC BY 3.0) + # Check Icon Modified version of [checkmark by Asmuh](https://thenounproject.com/icon/checkmark-2193586/) (CC BY 3.0) diff --git a/resources-base/x.svg b/resources-base/x.svg new file mode 100644 index 0000000..813dfdd --- /dev/null +++ b/resources-base/x.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/resources/x.png b/resources/x.png new file mode 100644 index 0000000000000000000000000000000000000000..b5bdd33633029ad6f8db09d06a54f6ae3dade701 GIT binary patch literal 5091 zcmeI0_dgVl5ABF%B(L-F{l9Rza47rKZ29EB6^rD?@y`u^TPu42}&G;?t z>SPEcc@gDGFQ;#A#qPBv37>Z*LfI|czIh(A=FGQh(AJL_Vs?@e)xdL5dWwtuPleku59LiVTr?}Gi; ztBbk;=4TEisV=IKR$*v?1}DZ1$|jL`27BwQ9vk=U7=;gQREppZo)vMfua$p)#1_5J zz&bwu^-fJ)GcPWpI8!AA&S^z94FJ%hG?Wz#J`xPf5}V-GmPz+%X<9t^-(%Tnm*qn}t_9e{(!45D@UN*W| z8}GjQ*r2);jC}-2gS6))47y|T3I7)AFDjZAe!e3T?5vRYfe6Bbgen z^b(r_FkUzOfo%Pt5B{4t`bDy`FCo}fg#bM9$G86>P>x#*c>pG4%gN6)zQ(*r$@UFZi-MmdM8}TKrjR&O7vKsFI zQt=GrJO!TdDXYXr#$@NKAhN>-%qiYLNzAQPgO)6m3xx5E*^a!?Cu5XdZS@havHkFg9&a#rT8(GVbNu2nQ%V$qN4- z>lw33ozZJrP%kym#)h)-QrgL}E}X~QLBT*+vz*1J?v~T0!C6qn@f9r+&!nFg$>(9e zz6|xt>D71gAKKkua9-yHM~rBQTL!+EG{n99sY9jTn)GIu1p@ z9U%UKIpYUJ-c&I;@LEFsC11u8y%$eafT>&MUmUVGMvelb&fR{dSUg1_q~^OmC`kPQWH7wT=>$`_P&NniEaNOo^rWoLO%kb4i8?5%X7E)l)h@&iB94n z{VnsU9h}Fn!k7hewWb_`VQ8MVSFD(5o1(V$ISffz+n{jr1o;ZrZttRrl}Eyx!^PKM zmYIci&FT5Fvor6|xQL|goXbwJJUhHt!-&8fSU0NzeR z6ow=@T7jm*TXeRp!0FETJF541IxR7B&yJnb!3r?Pzxp=c(-GNScG{w+3qn0Q6{|>C z;@$}RAfD^C)&;!rVe$5uU8LxZ7c}^-)%(h6>QRAPGo>UvEM?m_9-X`D!Pf)#Hgm2# zgpPlIv6F01*1xxQ0EJ&t*d6vemIow52d1dC;dTgd<3H9ZD+GueTT03T)#a0|eyAK$ z0Ig{I`yR$s>K6?YS{*HQ-XBE##8#K#qNS2)Sb5E$oPYddiuGf`Z8qi<^EV=bPAM|c z66REbWq@dmbEKddIV)mCngx66mtuWTpz2rU3A{`a>O^XDV=JOq z^b6``N6)K~Zpb_WBBNaF6jYpZxob?82gl`G{{_C{=gOPDCau(W)BLs&E(oom&3hdz zn6R$ibIQF{*QqD%Notu)K?7}5vi$Zm+LkH|0+{23P|WRtng&x%-}IA( z{h$G61bsttdB6e^XMZb*JIDqe9W{8jU%R7L3sgFCdk-8M^dfcxb&*~J{tp{O#mYn@ zUq|_4Fkt_dH0OzXaW_IW_IR)77tO8C31F|&qmm{O=2r(RcGX@^E8xFeLV1=tW~#m7 zIQy6v8b60d`eHu_=(I6BPSOb(#O;=;fPZ;nF1v3g-icCb>1PIyE3F7m!vrUJGEm2X z_$fr@;bEr|(e-0(``XY^gMf`<0C!^0?ihoHBi9UAKCVyY}rmmPHJ? z?>eQPQD2gaJu+3TUmi$;Z*3&(WvZKY{<8&G>_o{|vr+q`lj(d~>6gFVV=o-X^&k~^ zqTGGw?54apw1W*f`iXUBG(=@l0`KJ%c;p&{M0u>m_iW;r^(wF!Uzw~lCB}@!L=@fn^F=b z!ugPZ56!o1MbiyqanyS$-C3qYiQ?bhds;_$? znr-)CuTP9|;%FW(s~G;gl#A);{nb}L~K6N`2Z1;6JKWKRM z-|d+1^%(^wsm!r+dS(T;ze%h?lR6%BTt^1CvXCZ@H`!AlsAmzi>EJRPtckPj zaUXBj08A*V&sP>Jl#67cpRWSJcNExww3Y+&;Z^Mn2>V3&M?&;*`PudGkkfkAEuTpe z%nv@X5-#(~8{Jh6_)0GO2A#7hPHHfWeIx^l*XZ=}i7mXX)7ypf-;E718Y`TFI2uS2 z>&XdjTMvNWB-uz-XuM;VkCOkaYI95bEV(mS>*YZ9btHccNZC4`sx-HjJ5%@SO*w6o zh59jm;?N86eyZW|;J)Y0M2#LMm0{w7KW>YMuSv?l+#A2GWj0LvYhE9h_f*7Dr^wyb zSq=4kH2{;iUp?rJNhJpa{?d4TmPU6O%SYvtGph<02AP?CQ@t7~rR{--xezn~ROkAJ zfI{b4I9>H$r@*Qo%>A&PX2C$pvX01`H#YVe< zy$0W-#jAMGg_Q8t20;oLRX|g zBPA+l(+~aY{H7T~eHpYAvfHihkAX-ROg#h~5-Wu)Lo#aV4%~qEjWeA~20i0m8rLwk zbQ?8;wNUb-5gbv?aD#{;<{dvat#;9#KT?9+{Dzb4rJut zJ&1}qrJPTPT8sPG|IGsM2hA_aK%^bJ0 zpE;w812@Ecwf{!hlB6D+9u{fzmM|UjESLYxBu5ajE|3JQA^}z0sT?d?sGEOs zgaMcurS$g9M9KT4JC=?7y;i(YD89*_Lj(c;JA%NgLLRlmT5bBn9)^Gte>&&S*z4V& z64jdu@V>GZV+-H+AH9_5lU?Ssuhtx!wF)(AQEn}n6Dy-t&cq+FinO)|Y{WIR0V9wl zs~eO$24X<@Ggl(MEM3yeB|d(AW_&K29=#nZ9xaeBtxX?lfCjt@-^&2Ut)$!CY-I({ zbj*Oys?Yqx<4yOIYk&rvk9s~m*x>O~&UC?|In|6i{&v)q%-q^HcV9f}+E@hTyL zGM7d7$mNS8P7Vfly5DtAF-FEvf8Dsc&th_tm9!r!f{&fS`n}GiAGe<`>V0mJVr9#1 zBN`IKIL|5m&-z#?N$8VVMJf_d$?JI3h@L94F0`f_H`3iztMsLN6m{u3z_5{_*AIM? zBqV5mY$*&dA|xpGY@E%sW4iZoz*GsP^l!|VJn#!?c~is5It4-X#hQcDh<;?IyQwmSrEG7jHj+ zZgGoIY%c7~1=;oNwQN+xed3pdW2@zCK77# zCFDe{FiAkX;0S?x)t0PlVpj2O-XnL?zj=G6UaxVXEsLCT3kvA^^9$1K+SbH)FQPRS z7PXHKYv_9%n>xwQ_gH+s7z0XA?T`1 zsS*iS7*8@4;O*~E{#bIf6UAo_S-yT=U7oCC!|X*MCZ#eZ#n~&Z+u%_8YDOW9Pm3m7 zqd4e!gI8l+eh@w(Bcjf5i*#GZG9?6&zbJe7OKd!=FMb$i?La)9OCna=Z~x&Jq`yFo zMUc%c?t~GC6rKKQjyhO**G=-bDLJBwPNcSAGGjdVIfD!!QbW4m70W~8gU1D4;0N^t zT~y?90?)_#dM-Oi3tlW~GUIM@pYWJ-9qydTjA26Z~RAR@GhUz{mZQuaj(1yez4KvF7)6{Ds1MUnff| zj94c{xxkRQ{Lp(*U(Zd0&D?tn-WyZ_{?8Y;mRX_X03QiJfOGfy9l$E^yxb^*W9h&1 O4xpg|Q!Z6B3;I7HI6vtC literal 0 HcmV?d00001 diff --git a/src/c/main.c b/src/c/main.c index 585b279..b70c78c 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -25,6 +25,8 @@ static BitmapLayer *s_check_bmp_layer; static TextLayer *s_setter_txt_layer; static Layer *s_setter_highlight_layer; //// alarm +static BitmapLayer *s_x_bmp_layer; +static Animation *s_x_anim_master; static Layer *s_graph_layer; static TextLayer *s_theta_txt_layer; static TextLayer *s_parenthesis_txt_layer; @@ -54,6 +56,8 @@ GFont s_font_mansalva_small; //// setter static GBitmap *s_clock_bmp; static GBitmap *s_check_bmp; +//// alarm +static GBitmap *s_x_bmp; // global vars static WakeupReason s_alarm_reason; @@ -129,10 +133,6 @@ static void status_set_failure_click_config_provider(void *ctx) { window_single_click_subscribe(BUTTON_ID_DOWN, click_handler_push_setter); } -static void status_math_failure_click_config_provider(void *ctx) { - window_single_click_subscribe(BUTTON_ID_SELECT, click_handler_retry); -} - static void status_window_load(StatusWindowPurpose purpose) { Layer *window_layer = window_get_root_layer(s_status_window); s_status_txt_layer = text_layer_create(GRect(0, 0, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT)); @@ -149,10 +149,6 @@ static void status_window_load(StatusWindowPurpose purpose) { case STATUS_SET_FAILURE: text_layer_set_text(s_status_txt_layer, "Failed to set an alarm.\nPress any button to return to alarm setter."); window_set_click_config_provider(s_status_window, status_set_failure_click_config_provider); - break; - case STATUS_MATH_FAILURE: - text_layer_set_text(s_status_txt_layer, "Incorrect equation.\nTry again!"); - window_set_click_config_provider(s_status_window, status_math_failure_click_config_provider); } text_layer_set_background_color(s_status_txt_layer, GColorClear); layer_set_frame(text_layer_get_layer(s_status_txt_layer), GRect(0, (PBL_DISPLAY_HEIGHT / 2) - (text_layer_get_content_size(s_status_txt_layer).h / 2), PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT)); @@ -542,7 +538,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) { // check solution for (int i = 0; i < 3; ++i) { if (s_selected_indices[i] != s_solution_indices[i]) { - push_status_window(STATUS_MATH_FAILURE); + animation_schedule(animation_clone(s_x_anim_master)); return; } } @@ -634,6 +630,16 @@ static void live_wakeup_handler_for_alarm(WakeupId id, int32_t wakeup_reason) { } } +static void anim_handler_flash_x_start(Animation *animation, void *context) { + layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), false); +} +static void anim_handler_flash_x_end(Animation *animation, bool finished, void *context) { + layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), true); + animation_destroy(animation); +} +static void anim_update_flash_x(Animation *animation, const AnimationProgress progress) {} // dummy +static const AnimationImplementation s_x_anim_impl = {.update = anim_update_flash_x}; + static void alarm_window_load() { wakeup_service_subscribe(live_wakeup_handler_for_alarm); @@ -761,6 +767,20 @@ static void alarm_window_load() { text_layer_set_font(s_progress_txt_layer, s_font_lecoish_small); layer_add_child(window_layer, text_layer_get_layer(s_progress_txt_layer)); + // x (incorrect equation icon) + s_x_bmp = gbitmap_create_with_resource(RESOURCE_ID_X); + s_x_bmp_layer = bitmap_layer_create(GRect(20, 24, 160, 179)); + bitmap_layer_set_bitmap(s_x_bmp_layer, s_x_bmp); + bitmap_layer_set_compositing_mode(s_x_bmp_layer, GCompOpSet); + layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), true); // hide until needed + layer_add_child(window_layer, bitmap_layer_get_layer(s_x_bmp_layer)); + + // x flash animation init + s_x_anim_master = animation_create(); + animation_set_implementation(s_x_anim_master, &s_x_anim_impl); + animation_set_duration(s_x_anim_master, 1500); + animation_set_handlers(s_x_anim_master, (AnimationHandlers){.started = anim_handler_flash_x_start, .stopped = anim_handler_flash_x_end}, NULL); + // configure UI around current triangle in s_triangle_layer s_current_triangle_num = 1; s_secs_since_last_input = MAX_SECS_WITHOUT_INPUT; @@ -775,6 +795,10 @@ static void alarm_window_load() { static void alarm_window_unload() { tick_timer_service_unsubscribe(); accel_tap_service_unsubscribe(); + animation_destroy(s_x_anim_master); + gbitmap_destroy(s_x_bmp); + bitmap_layer_destroy(s_x_bmp_layer); + text_layer_destroy(s_progress_txt_layer); text_layer_destroy(s_countdown_txt_layer); window_destroy(s_drop_window); text_layer_destroy(s_side_a_txt_layer); diff --git a/src/c/main.h b/src/c/main.h index 447f9c8..498ff4e 100644 --- a/src/c/main.h +++ b/src/c/main.h @@ -3,8 +3,7 @@ typedef enum { STATUS_CONFIRMATION = 1, - STATUS_SET_FAILURE = 2, - STATUS_MATH_FAILURE = 3 + STATUS_SET_FAILURE = 2 } StatusWindowPurpose; static void push_setter_window();