Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/apple_remote/source/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 8 kB image not shown  

Quelle  MultiClickRemoteBehavior.m   Sprache: unbekannt

 
Spracherkennung für: .m vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

/* -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*****************************************************************************
 * MultiClickRemoteBehavior.m
 * RemoteControlWrapper
 *
 * Created by Martin Kahr on 11.03.06 under a MIT-style license.
 * Copyright (c) 2006 martinkahr.com. All rights reserved.
 *
 * Code modified and adapted to OpenOffice.org
 * by Eric Bachard on 11.08.2008 under the same License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 *****************************************************************************/

#import "MultiClickRemoteBehavior.h"

static const NSTimeInterval DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE = 0.35;
static const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL = 0.4;

@implementation MultiClickRemoteBehavior

- (id) init {
 if ( (self = [super init]) ) {
  maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE;
 }
 return self;
}

// Delegates are not retained!
// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html
// Delegating objects do not (and should not) retain their delegates.
// However, clients of delegating objects (applications, usually) are responsible for ensuring that their delegates are around
// to receive delegation messages. To do this, they may have to retain the delegate.
- (void) setDelegate: (id) _delegate {
 if ( _delegate && ( [_delegate respondsToSelector:@selector(remoteButton:pressedDown:clickCount:)] == NO )) return; // return what ?

 delegate = _delegate;
}
- (id) delegate {
 return delegate;
}

- (BOOL) simulateHoldEvent {
 return simulateHoldEvents;
}
- (void) setSimulateHoldEvent: (BOOL) value {
 simulateHoldEvents = value;
}

- (BOOL) simulatesHoldForButtonIdentifier: (RemoteControlEventIdentifier) identifier remoteControl: (RemoteControl*) remoteControl {
 // we do that check only for the normal button identifiers as we would check for hold support for hold events instead
 if (identifier > (1 << EVENT_TO_HOLD_EVENT_OFFSET)) return NO;

 return [self simulateHoldEvent] && [remoteControl sendsEventForButtonIdentifier: (identifier << EVENT_TO_HOLD_EVENT_OFFSET)]==NO;
}

- (BOOL) clickCountingEnabled {
 return clickCountEnabledButtons != 0;
}
- (void) setClickCountingEnabled: (BOOL) value {
 if (value) {
       [self setClickCountEnabledButtons: kRemoteButtonPlus | kRemoteButtonMinus | kRemoteButtonPlay | kRemoteButtonLeft | kRemoteButtonRight | kRemoteButtonMenu | kMetallicRemote2009ButtonPlay | kMetallicRemote2009ButtonMiddlePlay];
 } else {
  [self setClickCountEnabledButtons: 0];
 }
}

- (unsigned int) clickCountEnabledButtons {
 return clickCountEnabledButtons;
}
- (void) setClickCountEnabledButtons: (unsigned int)value {
 clickCountEnabledButtons = value;
}

- (NSTimeInterval) maximumClickCountTimeDifference {
 return maxClickTimeDifference;
}
- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff {
 maxClickTimeDifference = timeDiff;
}

- (void) sendSimulatedHoldEvent: (id) time {
 BOOL startSimulateHold = NO;
 RemoteControlEventIdentifier event = lastHoldEvent;
 @synchronized(self) {
  startSimulateHold = (lastHoldEvent>0 && lastHoldEventTime == [time doubleValue]);
 }
 if (startSimulateHold) {
  lastEventSimulatedHold = YES;
  event = (event << EVENT_TO_HOLD_EVENT_OFFSET);
  [delegate remoteButton:event pressedDown: YES clickCount: 1];
 }
}

- (void) executeClickCountEvent: (NSArray*) values {
 RemoteControlEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue];
 NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue];

 BOOL finishedClicking = NO;
 int finalClickCount = eventClickCount;

 @synchronized(self) {
  finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime);
  if (finishedClicking) {
   eventClickCount = 0;
   lastClickCountEvent = 0;
   lastClickCountEventTime = 0;
  }
 }

 if (finishedClicking) {
  [delegate remoteButton:event pressedDown: YES clickCount:finalClickCount];
  // trigger a button release event, too
  [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]];
  [delegate remoteButton:event pressedDown: NO clickCount:finalClickCount];
 }
}

- (void) sendRemoteButtonEvent: (RemoteControlEventIdentifier) event pressedDown: (BOOL) pressedDown remoteControl: (RemoteControl*) remoteControl {
 if (!delegate)  return;

 BOOL clickCountingForEvent = ([self clickCountEnabledButtons] & event) == event;

 if ([self simulatesHoldForButtonIdentifier: event remoteControl: remoteControl] && lastClickCountEvent==0) {
  if (pressedDown) {
   // wait to see if it is a hold
   lastHoldEvent = event;
   lastHoldEventTime = [NSDate timeIntervalSinceReferenceDate];
   [self performSelector:@selector(sendSimulatedHoldEvent:)
        withObject:[NSNumber numberWithDouble:lastHoldEventTime]
        afterDelay:HOLD_RECOGNITION_TIME_INTERVAL];
   return;
  } else {
   if (lastEventSimulatedHold) {
    // it was a hold
    // send an event for "hold release"
    event = (event << EVENT_TO_HOLD_EVENT_OFFSET);
    lastHoldEvent = 0;
    lastEventSimulatedHold = NO;

    [delegate remoteButton:event pressedDown: pressedDown clickCount:1];
    return;
   } else {
    RemoteControlEventIdentifier previousEvent = lastHoldEvent;
    @synchronized(self) {
     lastHoldEvent = 0;
    }

    // in case click counting is enabled we have to setup the state for that, too
    if (clickCountingForEvent) {
     lastClickCountEvent = previousEvent;
     lastClickCountEventTime = lastHoldEventTime;
     NSNumber* eventNumber;
     NSNumber* timeNumber;
     eventClickCount = 1;
     timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
     eventNumber= [NSNumber numberWithUnsignedInt:previousEvent];
     NSTimeInterval diffTime = maxClickTimeDifference-([NSDate timeIntervalSinceReferenceDate]-lastHoldEventTime);
     [self performSelector: @selector(executeClickCountEvent:)
          withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
          afterDelay: diffTime];
     // we do not return here because we are still in the press-release event
     // that will be consumed below
    } else {
     // trigger the pressed down event that we consumed first
     [delegate remoteButton:event pressedDown: YES clickCount:1];
    }
   }
  }
 }

 if (clickCountingForEvent) {
  if (pressedDown == NO) return;

  NSNumber* eventNumber;
  NSNumber* timeNumber;
  @synchronized(self) {
   lastClickCountEventTime = [NSDate timeIntervalSinceReferenceDate];
   if (lastClickCountEvent == event) {
    eventClickCount = eventClickCount + 1;
   } else {
    eventClickCount = 1;
   }
   lastClickCountEvent = event;
   timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
   eventNumber= [NSNumber numberWithUnsignedInt:event];
  }
  [self performSelector: @selector(executeClickCountEvent:)
       withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
       afterDelay: maxClickTimeDifference];
 } else {
  [delegate remoteButton:event pressedDown: pressedDown clickCount:1];
 }

}

@end

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

[ Dauer der Verarbeitung: 0.60 Sekunden  ]