From 2803b91e8a1b1f50e540f8bb91807adeacd2952b Mon Sep 17 00:00:00 2001 From: CParasuraman Date: Sat, 11 Apr 2026 17:20:14 +0530 Subject: [PATCH] Added alignments --- .../ai_training_window.cpython-310.pyc | Bin 9100 -> 9105 bytes .../analytics_window.cpython-310.pyc | Bin 23080 -> 23084 bytes .../hash_cracker_window.cpython-310.pyc | Bin 16023 -> 16030 bytes .../hybrid_attack_window.cpython-310.pyc | Bin 22484 -> 22489 bytes ui/__pycache__/launcher.cpython-310.pyc | Bin 9372 -> 9405 bytes ui/__pycache__/nav_manager.cpython-310.pyc | Bin 2656 -> 3965 bytes .../rainbow_table_window.cpython-310.pyc | Bin 22361 -> 22359 bytes ui/__pycache__/reports_window.cpython-310.pyc | Bin 23201 -> 23121 bytes .../rule_engine_window.cpython-310.pyc | Bin 19904 -> 20014 bytes .../wordlist_generator_window.cpython-310.pyc | Bin 18856 -> 18864 bytes ui/ai_training_window.py | 18 +-- ui/analytics_window.py | 17 ++- ui/app_ui.py | 3 +- ui/hash_cracker_window.py | 10 +- ui/hybrid_attack_window.py | 14 +-- ui/launcher.py | 26 ++--- ui/nav_manager.py | 108 +++++++++++++----- ui/rainbow_table_window.py | 10 +- ui/reports_window.py | 19 +-- ui/rule_engine_window.py | 24 ++-- ui/wordlist_generator_window.py | 16 +-- 21 files changed, 157 insertions(+), 108 deletions(-) diff --git a/ui/__pycache__/ai_training_window.cpython-310.pyc b/ui/__pycache__/ai_training_window.cpython-310.pyc index 38a17bee6f96e9289d83766c4b5eb933362212be..2186b2b91a99f69ac1b7151e6cae192329361d13 100644 GIT binary patch delta 1430 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 diff --git a/ui/__pycache__/hash_cracker_window.cpython-310.pyc b/ui/__pycache__/hash_cracker_window.cpython-310.pyc index c83357ffffc912e4d5fd378f6d580bc49d919280..f89db3a226ec8be42d42d13b7890655ada8461b8 100644 GIT binary patch delta 2293 zcmZvdYiv|S6vvtEcH8atK}$>D-EC>wZcCSKk)@P^kbn;;$}@(VSTDP`?b_|$X71f? zDUTLN&`L^xsgM{_)Zn9vO1UU6m4|?!l8{K$TtJE#rD{?j(Zt{f=RY?VY`hn_zNa!*I?gVzRtc<3KNWzF|liJNpwz2IQoid$> zhCnK;b^4O*7YI?=(VVT8kz_V6wulMhY_=7PMal_Okeb#Wryiuj{J|Rul3B)19-)1vcuWlH3tuGUBKx!GC)+JV^|0Y7PIB~6aiWDMl~j_MF>Z%1BT8elN@jQ& zH~CEc=y?VB8Q2Z{0^9~hfM0>%*g#21fu^$0; z;7#W8qMwf`LxMimOX|cX`WJ>hK){L~V}4IstfqBOFGo)TGJOu*=~{n@lBc+u+06hApHh zt&w&*O$3INs7&cgY`u4Wg_ZB9Awkt7u5>NP2Y!M(BM->_f1yzlHhQ3jD+nZ19 z%vM!gpU6iU_V$nz3~O?yMw8LDnffxU7-v2;adJp%SLJ{a)9%;A3u+!lERUz6`WB*h zR9z&?McqEcI(GOHfL=5mu&^FY0dtT(X;Rnm7Zfer~A5bMYl!wm}5#Ive0YdRdx#f;G6_0;`I8d66q;dc! z-~w!b5ST+yY&26}_DDOieUFj%xi-_;9bY`VHKWWX_H~A(`X-b8tjza3xy*WfE+2#0Qz1$t zrbmF8$Aet6^yg|0kbG#ND>kAvRo1vIMqF5qhJs<4zJ(>?S!r!ufp{Bmml{$fwN;fm zWJzrbhUBos6|A#OwR4L$AsS*fY*8BIw_*HZH`vYEdrruOo&-(-JSl#Nz&F5dc5im+ zbfK5SXnzC@0OH<@hp7k6@mgW^bwy;DDRtds9UHC7Di-y@TS%`17VJI~$O3MlZ0MSaH}ntnI!#vq delta 2297 zcmZ9Ndr(wW9LG7k%Pwzu$cQ`y!GRWH1qmd4qy<@uj(}!vGp#FJU~}0^zq<>F5olwY zL!}*@9LKD&%uq{d)sjl_QEG!ay_~!{(~Mfmm}B{eGv=tB@3}KVF~etnuXE4u{Lb&3 zv$f;hjuj9SK+#+A69oPY?SZ&@FCngGwF2jQDCm1YPly(Q4gs0#AizI~#im6pf4c}H44 zbMjqjxyk=6wM>aLd@6=-NJ)$|VelqkGaof>j#cj4`@tpS7Be=R_oq)`-}2k(#Ex@M zhI7U*2qXY|H54OYx6m9IDuHtXdZ?$_UDxIeeafr2$!<2>@X)WkJ0-ci4dPiuT3wpo zO@2LG{`d!Mh=crecA8Z-Y&ZWaTM_koF6W8Hb;74dk)j2>e$C}4MWOc)z7_Up zzq`RztNQ9a4FOW zJ^W|;govHO;1lPGc5zc~Pqoup=T@3jpFNfw!b5q$9$*LXC}08h0tJBVzKf7_0Q2hM z{zg*Vbsk@XlV8i7&CUml@`g+?+Yk^Ad?>*C#*B5)cBt}nd<^N6hwAW&L5^KUjxRf^ zB1eqiryc2X39AhEZO5GW!y;Pr(FuGA>!*XfW}>@hH^e^$7SJ(>3UC9sE)XyaTyIE7}baQj9UtY3Cx$onH z@^Ql zDk|y3iD-|i4)}bcA4EMfGVBrbH{$joE=u;Rt4VE9{OZVUL&Oijj{y3L4hY!8jDE&* zA@`2rkyHXO21o)Pz$;rQa=4LVgU>(K%&b4bcblInE>Dx|8Gw#{m?uYw2PO-aZG7hR z1pZ{nTsFwpmt?RW-dBSOrH$r+x9CyMsNlP{o~wLsH|x}YRR)o@Im z3AHLI4o%TCkLq)I)rJPqW?5n?-6Gp)s3(DkH>~l%;2n|&m~QY%)4l%! Dq2ExG diff --git a/ui/__pycache__/hybrid_attack_window.cpython-310.pyc b/ui/__pycache__/hybrid_attack_window.cpython-310.pyc index 3cb9e3d17fc444413ba90bb14fb2ab677b378c4b..e6532ff79ab2ef0248bf54cad1f09446961348ff 100644 GIT binary patch delta 5418 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 SuS7otRo^EuDKEP_Gv5IAA{xv9 delta 1401 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 delta 1316 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 rXU;z{`Wb+KmE3^D)I@_a9MqRW>Y!#gy-||?Q zCisW-UG!L~bwvE5?cg|8y3^6>R7a<_wj&j>Rs8JK!BNLdsrE7LIAh25{LU9xCLNjK zm-C%_&bg2CJLleg?^*T!v#K&#QBhXF|3;RaiT>xF)0Mqt%Aea&R_s!{>DG#<3eam6 zA+?X1D``QN?erahAqLx%He+VkG9!Mav-F3`Yt`)!S2eGm;ITkae>7%Jy}_d2r6>81 zPBTnxcN9mVumE>EiaQ}^C|FfDdmqG&45y0pI>;%yyK3BXJBu7@AAMPMLPh9!^@i(g zmvzX}m9V*s!7d6XV`n9sD`wc!QlVtN2tB4fezP~=elOqxaxLe5Ca@J3^@WY zY4@Ckt41Mi0muwvkfMP7fCR&cPC{G@*aqkW1nBe}Z(WE*f1$I1O;FztI7FY#xxVv3 zh%rDMFa)>}&;uA}@E7ZT$kY2DtgTlM&}ePr5^;rtU2TM|=m9fig!hl>WF`^O--E{h zKqfp!r)$soFFRZ@;Y>rgJVejTjZXwhqlvIK<7UFrKY@AyV35JC4rMGWnYd!Ud}u75 zH!GPt1-V|gz;PJh13V1a1-Kco6R-n740drJ&v#h+=?8UHbB;q((mxRF*}AJwKLMl1 z=%qTN=_JIbFj^ctsjNrF(^Dd)xeIvz9DC&vOcWJU!<>x(PVC2!x2?^s?bTVf-XR>F6iy~Muv35 zMiMRryNN%iRzmkw$dGd&XX%Gm zH@i<_B%FKw>X!@M??8T(?(wavI>Dk{GH#>|%hLJ-dfV5n&gQBXeP6kM2de-*y?A)h zpCHQ0gvwaYh*TVJS!kD{g-!F-8Cu!2v^>Ab5T%+L)dzH}X;^!T-fC&A zegvWFyc(YknsZXQvqZ|VHVv}L4V zXMw+ANH-v|)bMRAF^#2)B|ibW(CXXtCJg=#$fxx8{FyCTJSzV*GUzYYTVZp#Vw}2` zB8g!jPMiG=i=_6B;oCX(hah6cOC_J8@A{ivQ{@HpQ~$iiE8JoD3?LukM|9D@-Yq3^ zj=I_wx+Nn-BW=y|gbHQBaLhDx(1^u&V?yVXxrf{St=xwY=^wcVmn>7NGWY7zI=pI>9_px>Fa0mioFt6EZhb$!+|i*Pq|ZARmdozs7`~*ro!7La zU{JwzW2?iw3SpQuw)c2|uZ}w~Zd15(eMGuJ(TK@y{ds7yAG;)$91Dh$hwRdwVV#V{ zLWZ`B47ziP7j-Mw|M#@Wv5HAzdovldvRr*Ndu-UhPV5t-+#P zW+Gy%GChkw*sy{BNLqhQtZv2lZ=kpq(iWOrtp`^?TnShOSPfVM zkicsp{S_{x6rg>r)9vsz^uw6$_4b>=j?!VpZizF$!9ey5+b<$8zp9d>u zQr}FE_dHYY!(bsG$Z)DqPtQVK0}Yhz4K(05vZdaGNgYYIx3@b@_>YM86@Ae=*VEy+ zou`V8i-y1HjI%Yndv@Klb>kjyZ!(^WnU?AEdUY?R?P17Na=f$`C+tld2ZTWLFxX9# z8wYO8(@%1E$XLwM^}BJx|@O@ZAX51^@-^()4)pAe$z&-VJ3lVn}(Fnu$!@)Lc2X zE6Pukk6}LdQZa=xbatR(LJF^q9c@qC*l$LnI<5QgSro~{Q+f+RE=I@!NKKFiAq_G3 zYve=&6<|Uvnzn)|!y3QhyurpmiM(q@6M^EmaVTi&?d%yS7V_w~<+-|tHFimQf0Qeq zn^;uO#tfffxvo^$3V4#4>CihdAf=8n;mdiF|L6>~GZPG*G=Q<(E1OOzb)NQaZrX>m zW=nfA(O4v!81rV!y_OM*napA)-}{JJ#B^ZSeBzPYOV5A_mhIv&KU6J^RXbD5B4*TW zmM(5SGk*zeevLKG8204e*>by@vlp=ovt^riZX5EB@^6i_zLRbp>~BE{=}tfrCQ56_ z(xs%JoK{7@8uXVpVZ`AseL1*nHmby5=_Cyd(P3IUwBRP84Kk~b0P>_liup$nvnZMv zO*$+_kLAjddXc7yq)GqRBhpMtb3Y%ts7h{x`mF-m)>B8XY;SFpyFj+O3nO;}V!Z diff --git a/ui/__pycache__/reports_window.cpython-310.pyc b/ui/__pycache__/reports_window.cpython-310.pyc index d61f3e7ab11eff78465672d33633b0209452f8cb..0dd40cff6e91f644970463f2f0a7bc517f702c18 100644 GIT binary patch delta 5110 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 W3Q{ki53n2H5x&4|rBzf1`u+#`48|P* delta 5005 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 Nv7Cx8^}8o({};4N+kXH6 delta 7671 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 diff --git a/ui/__pycache__/wordlist_generator_window.cpython-310.pyc b/ui/__pycache__/wordlist_generator_window.cpython-310.pyc index 22738a627f130637ba05a2fe13918654ae114f4f..aff97d664c6a33d08bed6730ac7b76d3de2544fe 100644 GIT binary patch delta 4693 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", lambda e, n=name: self._select_mode(n)) @@ -148,7 +148,7 @@ def _select_mode(self, name): def _build_module_grid(self): outer = tk.Frame(self, bg=BG_DARK) - outer.pack(fill="x", padx=20, pady=(16, 0)) + outer.pack(fill="x", padx=20, pady=(0, 0)) tk.Label(outer, text="OPEN MODULE", bg=BG_DARK, fg=FG_MUTED, font=("Courier", 8)).pack( @@ -193,10 +193,10 @@ def _build_module_grid(self): highlightbackground=BORDER, cursor="hand2") card.grid(row=i // 2, column=i % 2, - sticky="ew", padx=4, pady=4) + sticky="ew", padx=4, pady=2) inner = tk.Frame(card, bg=BG_CARD) - inner.pack(fill="x", padx=12, pady=10) + inner.pack(fill="x", padx=12, pady=6) tk.Label(inner, text=name, bg=BG_CARD, fg=FG_PRIMARY, @@ -226,7 +226,7 @@ def _build_module_grid(self): def _build_quick_start(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=20, pady=16) + frame.pack(fill="x", padx=20, pady=(2, 12)) tk.Button(frame, text="▶ Start Quick Crack", bg=BTN_BLUE, fg="#e0f0ff", @@ -236,12 +236,12 @@ def _build_quick_start(self): activeforeground="#ffffff", cursor="hand2", command=self._open_hash_cracker - ).pack(fill="x", ipady=10) + ).pack(fill="x", ipady=4) def _build_statusbar(self): bar = tk.Frame(self, bg=BG_CARD, - height=30) - bar.pack(fill="x", side="bottom") + height=28) + bar.pack(fill="x", side="bottom", pady=(0, 10)) # Added bottom padding for balance bar.pack_propagate(False) tk.Label(bar, text="●", bg=BG_CARD, fg=FG_GREEN, diff --git a/ui/nav_manager.py b/ui/nav_manager.py index 460a11a..ba26e3f 100644 --- a/ui/nav_manager.py +++ b/ui/nav_manager.py @@ -7,25 +7,51 @@ FG_PRIMARY = "#cbd5e1" FG_MUTED = "#64748b" FG_BLUE = "#7dd3fc" +BG_ACCENT = "#1e3a4a" BORDER = "#3a3a50" class NavigationManager(tk.Tk): def __init__(self): super().__init__() + self.withdraw() # Hide immediately to prevent launch flicker + self.title("CryptX v2.0") - self.geometry("900x750") - self.minsize(800, 700) + + self.width = 1100 + self.height = 750 + self.minsize(950, 500) self.configure(bg=BG_DARK) # History stack (list of frames) self.history = [] self.current_frame = None + + # View cache to make switching near-instant + self.views = {} self._init_ui() + def _center_window(self): + """Dynamic centering: snaps window height to content requirements.""" + self.update_idletasks() + screen_width = self.winfo_screenwidth() + screen_height = self.winfo_screenheight() + + req_height = self.winfo_reqheight() + req_width = self.winfo_reqwidth() + + self.height = min(req_height + 4, screen_height - 80) + self.width = max(1100, min(req_width, screen_width - 40)) + + x = (screen_width // 2) - (self.width // 2) + y = (screen_height // 2) - (self.height // 2) + + y = max(20, y) + self.geometry(f"{self.width}x{self.height}+{x}+{y}") + def _init_ui(self): # ── Navbar (Header) ────── - self.navbar = tk.Frame(self, bg=BG_CARD, height=44) + self.navbar = tk.Frame(self, bg=BG_CARD, height=36) self.navbar.pack(fill="x") self.navbar.pack_propagate(False) @@ -42,7 +68,7 @@ def _init_ui(self): padx=15 ) self.back_btn.pack(side="left", fill="y") - self.back_btn.pack_forget() # Hide initially + self.back_btn.pack_forget() # App Title in Navbar self.title_label = tk.Label( @@ -54,38 +80,70 @@ def _init_ui(self): ) self.title_label.pack(side="left", padx=20) - # Main Container for views - self.container = tk.Frame(self, bg=BG_DARK) - self.container.pack(fill="both", expand=True) + # ── Main Container (Standard Frame) ────── + self.main_area = tk.Frame(self, bg=BG_DARK) + self.main_area.pack(fill="both", expand=True, padx=0, pady=0) def show_view(self, view_class, *args, **kwargs): - """Clears the current view and shows a new one. History is NOT pushed.""" + """High-performance view switcher with caching and smart state transitions.""" + target_name = view_class.__name__ + is_home = (target_name == "LauncherFrame") + + # 1. Determine if we need to hide the window + # We only withdraw if we are changing between 'zoomed' and 'normal' states + current_state = self.state() + target_state = "normal" if is_home else "zoomed" + needs_masking = (current_state != target_state) or (current_state == "withdrawn") + + if needs_masking and current_state != "withdrawn": + self.withdraw() + self.update_idletasks() + + # 2. Swap the frame (Optimized with caching) if self.current_frame: - self.current_frame.destroy() + # We don't destroy cached views, just unmap them + self.current_frame.pack_forget() + + if target_name in self.views: + self.current_frame = self.views[target_name] + else: + # Create and cache + self.current_frame = view_class(self.main_area, self, *args, **kwargs) + self.views[target_name] = self.current_frame - self.current_frame = view_class(self.container, self, *args, **kwargs) self.current_frame.pack(fill="both", expand=True) - # Update back button visibility + # 3. Update navigation state if self.history: self.back_btn.pack(side="left", fill="y") else: self.back_btn.pack_forget() + # 4. Handle State & Geometry + if is_home: + if self.state() == "zoomed": + self.state("normal") + self._center_window() + else: + if self.state() != "zoomed": + self.state("zoomed") + + # 5. Show window (Instant if no state change, otherwise fast reveal) + if needs_masking: + # Reduced delay to 50ms for snappy feel + self.after(50, lambda: ( + self.deiconify(), + self.lift(), + self.focus_force(), + self.update_idletasks() + )) + else: + self.update_idletasks() + self.lift() + self.focus_force() + def push_view(self, view_class, *args, **kwargs): """Pushes current view to history stack and shows new view.""" - # Note: In Tkinter, we might want to store the class and its state, - # but for simplicity, we destroy the old frame and just store the class for navigation back. - # If we need state preservation, we could hide instead of destroy. - - # Here we only store the "Home" view for now as we transition. - # Later, we can make it more generic. - if self.current_frame: - # We don't store the actual frame object usually because of resource management, - # but we can store the class type if we want to re-instantiate it. - # For this simple app, we just need a way to go back to Home. - pass - self.history.append(view_class) self.show_view(view_class, *args, **kwargs) @@ -94,12 +152,10 @@ def pop_view(self): if not self.history: return - self.history.pop() # Remove current + self.history.pop() if not self.history: - # Go back to launcher (Home) from ui.launcher import LauncherFrame self.show_view(LauncherFrame) else: prev_view = self.history[-1] - # Since we destroy frames to save resources, we re-instantiate. self.show_view(prev_view) diff --git a/ui/rainbow_table_window.py b/ui/rainbow_table_window.py index 8cffc44..3454e51 100644 --- a/ui/rainbow_table_window.py +++ b/ui/rainbow_table_window.py @@ -316,7 +316,7 @@ def _select_algo(self, algo): # ── Lookup bar ──────────────────────────────────── def _build_lookup_bar(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10, 0)) + frame.pack(fill="x", padx=16, pady=(12, 0)) tk.Label(frame, text="INSTANT LOOKUP — " @@ -404,7 +404,7 @@ def _lookup_hash(self): # ── Stats bar ───────────────────────────────────── def _build_stats_bar(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10, 0)) + frame.pack(fill="x", padx=16, pady=(12, 0)) self.stat_vars = { "Total entries": tk.StringVar(value="0"), @@ -463,7 +463,7 @@ def _build_progress(self): # ── Buttons ─────────────────────────────────────── def _build_buttons(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10, 6)) + frame.pack(fill="x", padx=16, pady=(10, 8)) self.build_btn = tk.Button( frame, @@ -479,7 +479,7 @@ def _build_buttons(self): command=self._build_table) self.build_btn.pack( side="left", expand=True, - fill="x", padx=(0, 6), ipady=10) + fill="x", padx=(0, 6), ipady=11) # increased ipady tk.Button(frame, text="Load Table", @@ -521,7 +521,7 @@ def _build_buttons(self): command=self._clear_all ).pack(side="left", expand=True, fill="x", padx=(3, 0), - ipady=10) + ipady=11) # ── Status bar ──────────────────────────────────── def _build_statusbar(self): diff --git a/ui/reports_window.py b/ui/reports_window.py index 39cefd1..ae7340f 100644 --- a/ui/reports_window.py +++ b/ui/reports_window.py @@ -66,7 +66,7 @@ def _build_titlebar(self): tk.Label(bar, bg=color, width=2).pack( side="left", padx=(8 if color == "#ff5f57" else 4, 0), - pady=10) + pady=7) tk.Label(bar, text="Window 8 — Reports & Logs · Compliance-ready audit trail", bg=BG_CARD, fg=FG_MUTED, @@ -108,7 +108,7 @@ def _build_summary_cards(self): # ── Main 2-column area ──────────────────────────── def _build_main_area(self): outer = tk.Frame(self, bg=BG_DARK) - outer.pack(fill="x", padx=16, pady=(10, 0)) + outer.pack(fill="both", expand=True, padx=16, pady=(12, 0)) outer.columnconfigure(0, weight=3) outer.columnconfigure(1, weight=2) @@ -149,7 +149,7 @@ def _build_session_log(self, parent): self.log_tree = ttk.Treeview(card, columns=cols, show="headings", style="Log.Treeview", - height=10) + height=8) # Reduced from 10 to fit vertical budget for col, txt, w in [ ("id", "#", 35), @@ -266,9 +266,6 @@ def _out(e, ent=entry, p=ph): btn.pack(side="left", padx=(0, 6)) self.fmt_btns[fmt] = btn - # ── FIX: guard so _update_preview is not called before - # preview_box exists (it is built in _build_preview, - # which runs after _build_main_area). self._select_format("TXT") tk.Label(inner, text="INCLUDE IN REPORT", @@ -290,7 +287,6 @@ def _out(e, ent=entry, p=ph): activeforeground=FG_BLUE, font=("Courier", 8)).pack(anchor="w") - # ── FIX: guard _update_preview until preview_box exists ────────── def _select_format(self, fmt): self.report_format.set(fmt) for f, btn in self.fmt_btns.items(): @@ -300,7 +296,7 @@ def _select_format(self, fmt): else: btn.configure(bg=BG_DARK, fg=FG_MUTED, highlightbackground=BORDER) - if self.preview_box is not None: # ← GUARD + if self.preview_box is not None: self._update_preview() # ── Report preview ──────────────────────────────── @@ -322,19 +318,16 @@ def _build_preview(self): font=("Courier", 9), relief="flat", state="disabled", - height=7, + height=5, padx=10, pady=8) - self.preview_box.pack(fill="x", expand=True) + self.preview_box.pack(fill="x", expand=False) - # Now that preview_box exists, do the first real preview render self._update_preview() for var in [self.analyst_var, self.target_var, self.scope_var]: var.trace_add("write", lambda *a: self._update_preview()) def _update_preview(self): - # Safety guard — should never be needed after the fix above, - # but kept as a belt-and-braces check. if self.preview_box is None: return diff --git a/ui/rule_engine_window.py b/ui/rule_engine_window.py index 8e617c6..4805db5 100644 --- a/ui/rule_engine_window.py +++ b/ui/rule_engine_window.py @@ -87,7 +87,7 @@ def _build_titlebar(self): tk.Label(bar, bg=color, width=2).pack( side="left", padx=(8 if color=="#ff5f57" else 4,0), - pady=10) + pady=8) tk.Label(bar, text="Window 5 — Rule Engine " "(Hashcat-compatible syntax)", @@ -98,7 +98,7 @@ def _build_titlebar(self): # ── File + ruleset selector ─────────────────────── def _build_files_section(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(12,0)) + frame.pack(fill="x", padx=16, pady=(12, 0)) row = tk.Frame(frame, bg=BG_DARK) row.pack(fill="x") @@ -168,7 +168,7 @@ def _load_preset(self, event=None): # ── Main 2-column area ──────────────────────────── def _build_main_area(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10,0)) + frame.pack(fill="both", expand=True, padx=16, pady=(12, 0)) frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) @@ -238,9 +238,11 @@ def _build_main_area(self): self._add_token(t) ).pack(side="right", padx=4) - inner.update_idletasks() - canvas.configure( - scrollregion=canvas.bbox("all")) + # Delayed update ensures the scrollregion is calculated after the transition + self.after(200, lambda: ( + inner.update_idletasks(), + canvas.configure(scrollregion=canvas.bbox("all")) + )) # ── Right: rule editor + live preview ───────── right = tk.Frame(frame, bg=BG_DARK) @@ -401,8 +403,8 @@ def _update_live_preview(self): # ── Stats bar ───────────────────────────────────── def _build_stats_bar(self): - frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10,0)) + outer = tk.Frame(self, bg=BG_DARK) + outer.pack(fill="x", padx=16, pady=(12, 0)) self.stat_vars = { "Rules": tk.StringVar(value="0"), @@ -436,7 +438,7 @@ def _build_stats_bar(self): # ── Progress bar ────────────────────────────────── def _build_progress(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(8,0)) + frame.pack(fill="x", padx=16, pady=(6,0)) style = ttk.Style() style.theme_use("clam") @@ -459,7 +461,7 @@ def _build_progress(self): # ── Buttons ─────────────────────────────────────── def _build_buttons(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10,6)) + frame.pack(fill="x", padx=16, pady=(6,6)) self.apply_btn = tk.Button( frame, @@ -520,7 +522,7 @@ def _build_buttons(self): # ── Status bar ──────────────────────────────────── def _build_statusbar(self): bar = tk.Frame(self, bg=BG_CARD, - height=28) + height=25) bar.pack(fill="x", side="bottom") bar.pack_propagate(False) diff --git a/ui/wordlist_generator_window.py b/ui/wordlist_generator_window.py index 0c9bcb4..f50a4b3 100644 --- a/ui/wordlist_generator_window.py +++ b/ui/wordlist_generator_window.py @@ -86,7 +86,7 @@ def _build_titlebar(self): # ── Target info — 2 column grid ────────────────── def _build_target_section(self): outer = tk.Frame(self, bg=BG_DARK) - outer.pack(fill="x", padx=16, pady=(12, 0)) + outer.pack(fill="x", padx=16, pady=(16, 0)) tk.Label(outer, text="TARGET INFORMATION — fill what you know", @@ -190,7 +190,7 @@ def on_out(e, ent=entry, ph=placeholder): # ── Generation options ──────────────────────────── def _build_options_section(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10, 0)) + frame.pack(fill="x", padx=16, pady=(6, 0)) tk.Label(frame, text="GENERATION OPTIONS", bg=BG_DARK, fg=FG_MUTED, @@ -239,7 +239,7 @@ def _toggle_opt(self, opt): # ── Stats bar ───────────────────────────────────── def _build_stats_bar(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10, 0)) + frame.pack(fill="x", padx=16, pady=(12, 0)) self.stat_vars = { "Words": tk.StringVar(value="0"), @@ -301,7 +301,7 @@ def _build_progress(self): # ── Buttons ─────────────────────────────────────── def _build_buttons(self): frame = tk.Frame(self, bg=BG_DARK) - frame.pack(fill="x", padx=16, pady=(10, 6)) + frame.pack(fill="x", padx=16, pady=(8, 6)) # Tightened pady self.gen_btn = tk.Button( frame, @@ -317,7 +317,7 @@ def _build_buttons(self): command=self._generate) self.gen_btn.pack(side="left", expand=True, fill="x", padx=(0, 6), - ipady=10) + ipady=11) tk.Button(frame, text="Save to File", @@ -408,12 +408,12 @@ def _build_preview(self): self.preview_box = tk.Text( box_frame, - bg="#1a1a2e", fg=FG_PRIMARY, + bg="#0f0f1e", fg=FG_GREEN, font=("Courier", 10), relief="flat", state="disabled", - wrap="word", - padx=10, pady=8) + height=4, + padx=8, pady=6) sb = tk.Scrollbar(box_frame, command=self.preview_box.yview,