/
pushamp
/
PACman
Обзор
Документация
Войти
/
pushamp
/
PACman
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
src/icons.rs
119 строк
3 KB
Dmitry Zhiltsov
feat(core): Init commit
19 фев 2026, 18:01
19 фев 2026, 18:01
1fadda9
Код
Авторство
О чём код?
use objc2::rc::Retained; use objc2::runtime::{AnyObject, Bool}; use objc2::{msg_send, AnyThread}; use objc2_app_kit::{NSColor, NSImage}; use objc2_foundation::{NSPoint, NSRect, NSSize}; const SIZE: f64 = 18.0; const PACMAN_CX: f64 = 7.0; const PACMAN_CY: f64 = SIZE / 2.0; const PACMAN_R: f64 = 7.0; const MOUTH_HALF: f64 = 35.0; /// PACman with mouth open + dot — VPN connected, proxy active pub fn connected() -> Retained<NSImage> { let img = create_image(); lock(&img); set_black(); // PACman body: arc with wedge mouth fill_arc(PACMAN_CX, PACMAN_CY, PACMAN_R, MOUTH_HALF, 360.0 - MOUTH_HALF); // Dot being eaten fill_oval(16.0, PACMAN_CY - 1.0, 2.0, 2.0); unlock(&img); img.setTemplate(true); img } /// Full circle PACman (mouth closed) — VPN disconnected pub fn disconnected() -> Retained<NSImage> { let img = create_image(); lock(&img); set_black(); // Closed PACman (full circle) with eye hole (even-odd fill) fill_circle_with_eye( PACMAN_CX, PACMAN_CY, PACMAN_R, 10.0, 12.0, 2.0, ); unlock(&img); img.setTemplate(true); img } fn create_image() -> Retained<NSImage> { let size = NSSize::new(SIZE, SIZE); unsafe { msg_send![NSImage::alloc(), initWithSize: size] } } fn lock(img: &NSImage) { #[allow(deprecated)] let _: () = unsafe { msg_send![img, lockFocus] }; } fn unlock(img: &NSImage) { #[allow(deprecated)] let _: () = unsafe { msg_send![img, unlockFocus] }; } fn set_black() { unsafe { let color = NSColor::blackColor(); let _: () = msg_send![&color, set]; } } fn bezier_path() -> Retained<AnyObject> { unsafe { let cls = objc2::runtime::AnyClass::get(c"NSBezierPath").unwrap(); msg_send![cls, bezierPath] } } fn bezier_oval(rect: NSRect) -> Retained<AnyObject> { unsafe { let cls = objc2::runtime::AnyClass::get(c"NSBezierPath").unwrap(); msg_send![cls, bezierPathWithOvalInRect: rect] } } fn fill_arc(cx: f64, cy: f64, r: f64, start_angle: f64, end_angle: f64) { let center = NSPoint::new(cx, cy); let path = bezier_path(); unsafe { let _: () = msg_send![&path, moveToPoint: center]; let _: () = msg_send![ &path, appendBezierPathWithArcWithCenter: center, radius: r, startAngle: start_angle, endAngle: end_angle, clockwise: Bool::NO ]; let _: () = msg_send![&path, closePath]; let _: () = msg_send![&path, fill]; } } /// Circle body with a transparent eye cutout via even-odd winding rule fn fill_circle_with_eye(cx: f64, cy: f64, r: f64, ex: f64, ey: f64, er: f64) { let path = bezier_path(); let body = NSRect::new(NSPoint::new(cx - r, cy - r), NSSize::new(r * 2.0, r * 2.0)); let eye = NSRect::new(NSPoint::new(ex - er / 2.0, ey - er / 2.0), NSSize::new(er, er)); unsafe { let _: () = msg_send![&path, appendBezierPathWithOvalInRect: body]; let _: () = msg_send![&path, appendBezierPathWithOvalInRect: eye]; // NSWindingRuleEvenOdd = 1 — inner oval becomes transparent hole let _: () = msg_send![&path, setWindingRule: 1_isize]; let _: () = msg_send![&path, fill]; } } fn fill_oval(x: f64, y: f64, w: f64, h: f64) { let rect = NSRect::new(NSPoint::new(x, y), NSSize::new(w, h)); let path = bezier_oval(rect); let _: () = unsafe { msg_send![&path, fill] }; }