Bagaimana menerima klik mouse untuk satu bagian dan membiarkan klik di seluruh NSWindow

Saya memiliki kode di bawah ini untuk subkelas NSWindow, ada tampilan animasi yang dapat diskalakan dan saya ingin menerima klik ketika diklik di tempat yang tepat dan menolak (klik) jika di luar.

Kode di bawah ini berfungsi dengan baik kecuali jendelanya tidak membiarkan klik masuk.

- (void)mouseDragged:(NSEvent *)theEvent {
  if (allowDrag) {
    NSRect screenVisibleFrame = [[NSScreen mainScreen] visibleFrame];
    NSRect windowFrame = [self frame];
    NSPoint newOrigin = windowFrame.origin;

    // Get the mouse location in window coordinates.
    NSPoint currentLocation = [theEvent locationInWindow];
    // Update the origin with the difference between the new mouse location and the old mouse location.
    newOrigin.x += (currentLocation.x - initialMouseLocation.x);
    newOrigin.y += (currentLocation.y - initialMouseLocation.y);

    if ((newOrigin.y + windowFrame.size.height) > (screenVisibleFrame.origin.y + screenVisibleFrame.size.height)) {
        newOrigin.y = screenVisibleFrame.origin.y + (screenVisibleFrame.size.height - windowFrame.size.height);
    }

    // Move the window to the new location
    [self setFrameOrigin:newOrigin];
  }
}



- (void)mouseDown:(NSEvent *)theEvent
{
    screenResolution = [[NSScreen mainScreen] frame];

   initialMouseLocation = [theEvent locationInWindow];

    float scale = [[NSUserDefaults standardUserDefaults] floatForKey:@"widgetScale"]/100;

    float pX = initialMouseLocation.x;
    float pY = initialMouseLocation.y;
    float fX = self.frame.size.width;
    float fY = self.frame.size.height;

    if (pX>(fX-fX*scale)/2 && pX<(fX+fX*scale)/2 && pY>(fY+fY*scale)/2) {
        allowDrag = YES;
    } else {
        allowDrag = NO;
    }
}

person Tibidabo    schedule 03.03.2013    source sumber


Jawaban (2)


Di Cocoa, Anda memiliki dua pilihan dasar: 1) Anda dapat membuat seluruh jendela melewati klik dengan [window setIgnoresMouseEvents:YES], atau 2) Anda dapat membuat sebagian jendela Anda transparan dan klik akan melewatinya secara default.

Batasannya adalah server jendela membuat keputusan tentang aplikasi mana yang akan mengirimkan acara satu kali. Setelah acara dikirimkan ke aplikasi Anda, tidak ada cara untuk mengembalikan acara tersebut dan mengirimkannya ke aplikasi lain.

Salah satu solusi yang mungkin adalah dengan menggunakan Quartz Event Taps. Idenya adalah Anda membuat jendela Anda mengabaikan peristiwa mouse, tetapi menyiapkan ketukan peristiwa yang akan melihat semua peristiwa untuk sesi login. Jika Anda ingin membuat acara yang melewati jendela Anda benar-benar berhenti di jendela Anda, Anda memprosesnya secara manual lalu membuangnya. Anda tidak membiarkan acara berlanjut ke aplikasi yang seharusnya dijangkau. Saya perkirakan hal ini akan sangat sulit untuk dilakukan dengan benar. Misalnya, Anda tidak ingin mencegat peristiwa untuk jendela aplikasi lain yang ada di depan jendela Anda.

Jika memungkinkan, saya menyarankan Anda menggunakan teknik yang didukung Kakao. Saya pikir Anda hanya ingin klik melewati jendela Anda yang transparan, karena jika tidak, bagaimana pengguna tahu apa yang mereka klik?

person Ken Thomases    schedule 03.03.2013
comment
Sayangnya tidak ada yang berjalan sesuai harapan saya. Ketika saya menskalakan tampilan jendela dengan animasi dasar, itu membuat banyak bagian transparan, tetapi bagian itu masih menerima klik mouse karena transparansi asli tidak penting pada lapisan animasi. Itu juga harus ramah App Store sehingga jebakan acara tidak bagus. Saya sudah mengirimkan aplikasi apa adanya, dengan bug jika saya mendapat banyak keluhan mungkin hal terbaik jika saya mengubah ukuran jendela terlampir ke ukuran yang sama dengan tampilan berskala. Terima kasih. - person Tibidabo; 09.03.2013
comment
Saya tidak tahu selama animasi, tapi yang pasti setelah pengubahan ukuran animasi selesai coba panggil -[NSWindow invalidateShadow]. Itu harus memastikan server jendela memperbarui gagasannya tentang bentuk jendela. - person Ken Thomases; 09.03.2013

Silakan aktifkan overlay transparan CHILD WINDOW untuk menerima kontrol dan buat jendela utama -setIgnoresMouseEvents:YES sesuai arahan Ken.

Saya menggunakan trik ini pada aplikasi saya yang bernama "Overlay".

person Jiulong Zhao    schedule 23.10.2013