blob: ccc0b37e5d026d7642c499d73a6836b58857225b [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/input/key_repeat_filter.h"
#include "cobalt/base/tokens.h"
namespace cobalt {
namespace input {
namespace {
const base::TimeDelta kRepeatInitialDelay =
base::TimeDelta::FromMilliseconds(500);
const float kRepeatRateInHertz = 20.0f;
const base::TimeDelta kRepeatRate = base::TimeDelta::FromMilliseconds(
base::Time::kMillisecondsPerSecond / kRepeatRateInHertz);
} // namespace
KeyRepeatFilter::KeyRepeatFilter(const KeyboardEventCallback& callback)
: KeyEventHandler(callback) {}
KeyRepeatFilter::KeyRepeatFilter(KeyEventHandler* filter)
: KeyEventHandler(filter) {}
void KeyRepeatFilter::HandleKeyboardEvent(
const dom::KeyboardEvent::Data& keyboard_event) {
if (keyboard_event.type == dom::KeyboardEvent::kTypeKeyDown) {
HandleKeyDown(keyboard_event);
}
if (keyboard_event.type == dom::KeyboardEvent::kTypeKeyUp) {
HandleKeyUp(keyboard_event);
}
}
void KeyRepeatFilter::HandleKeyDown(
const dom::KeyboardEvent::Data& keyboard_event) {
// Record the information of the KeyboardEvent for firing repeat events.
last_event_data_ = keyboard_event;
DispatchKeyboardEvent(keyboard_event);
// This key down event is triggered for the first time, so start the timer
// with |kRepeatInitialDelay|.
key_repeat_timer_.Start(FROM_HERE, kRepeatInitialDelay, this,
&KeyRepeatFilter::FireKeyRepeatEvent);
}
void KeyRepeatFilter::HandleKeyUp(
const dom::KeyboardEvent::Data& keyboard_event) {
DispatchKeyboardEvent(keyboard_event);
// If it is a key up event and it matches the previous one, stop the key
// repeat timer.
if (last_event_data_->key_code == keyboard_event.key_code) {
key_repeat_timer_.Stop();
}
}
void KeyRepeatFilter::FireKeyRepeatEvent() {
dom::KeyboardEvent::Data repeat_event(*last_event_data_);
repeat_event.repeat = true;
DispatchKeyboardEvent(repeat_event);
// If |FireKeyRepeatEvent| is triggered for the first time then reset the
// timer to the repeat rate instead of the initial delay.
if (key_repeat_timer_.GetCurrentDelay() == kRepeatInitialDelay) {
key_repeat_timer_.Stop();
key_repeat_timer_.Start(FROM_HERE, kRepeatRate, this,
&KeyRepeatFilter::FireKeyRepeatEvent);
}
}
} // namespace input
} // namespace cobalt