1// Copyright 2010-2018, Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Google Inc. nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30#include <Carbon/Carbon.h> 31#include <objc/message.h> 32 33#import "InfolistView.h" 34 35#include "base/coordinates.h" 36#include "base/logging.h" 37#include "client/client_interface.h" 38#include "protocol/commands.pb.h" 39#include "renderer/mac/InfolistWindow.h" 40 41using mozc::commands::Candidates; 42using mozc::commands::Output; 43using mozc::commands::SessionCommand; 44 45@interface InfolistWindowTimerHandler : NSObject { 46@private 47 mozc::renderer::mac::InfolistWindow* infolist_window_; 48} 49- (InfolistWindowTimerHandler*)initWithInfolistWindow: 50 (mozc::renderer::mac::InfolistWindow*) infolist_window; 51- (void)onTimer:(NSTimer*) timer; 52@end 53 54@implementation InfolistWindowTimerHandler 55- (InfolistWindowTimerHandler*)initWithInfolistWindow: 56 (mozc::renderer::mac::InfolistWindow*) infolist_window { 57 [super init]; 58 infolist_window_ = infolist_window; 59 return self; 60} 61- (void)onTimer:(NSTimer*) timer { 62 if(infolist_window_) { 63 infolist_window_->onTimer(timer); 64 } 65} 66@end 67 68namespace mozc { 69namespace renderer { 70namespace mac { 71 72namespace { 73bool SendUsageStatsEvent(client::SendCommandInterface *command_sender, 74 const SessionCommand::UsageStatsEvent &event) { 75 if (command_sender == nullptr) { 76 return false; 77 } 78 SessionCommand command; 79 command.set_type(SessionCommand::USAGE_STATS_EVENT); 80 command.set_usage_stats_event(event); 81 Output dummy_output; 82 return command_sender->SendCommand(command, &dummy_output); 83} 84} // namespace 85 86InfolistWindow::InfolistWindow() 87 : lasttimer_(nullptr), 88 command_sender_(nullptr) { 89 timer_handler_.reset([[InfolistWindowTimerHandler alloc] 90 initWithInfolistWindow:this]); 91} 92 93InfolistWindow::~InfolistWindow() { 94} 95 96void InfolistWindow::SetSendCommandInterface( 97 client::SendCommandInterface *send_command_interface) { 98 command_sender_ = send_command_interface; 99} 100 101void InfolistWindow::SetCandidates(const Candidates &candidates) { 102 if (candidates.candidate_size() == 0) { 103 return; 104 } 105 106 if (!window_) { 107 InitWindow(); 108 } 109 InfolistView* infolist_view = (InfolistView*) view_.get(); 110 [infolist_view setCandidates:&candidates]; 111 [infolist_view setNeedsDisplay:YES]; 112 NSSize size = [infolist_view updateLayout]; 113 ResizeWindow(size.width, size.height); 114} 115 116void InfolistWindow::DelayHide(int delay) { 117 DLOG(INFO) << "InfolistWindow::DelayHide()"; 118 if(lasttimer_) { 119 [lasttimer_ invalidate]; 120 } 121 visible_ = false; 122 const NSTimeInterval interval = delay / 1000.0; 123 lasttimer_ = [NSTimer scheduledTimerWithTimeInterval:interval 124 target:timer_handler_.get() 125 selector:@selector(onTimer:) 126 userInfo:nil 127 repeats:NO]; 128} 129 130void InfolistWindow::DelayShow(int delay) { 131 DLOG(INFO) << "InfolistWindow::DelayShow()"; 132 if(lasttimer_) { 133 [lasttimer_ invalidate]; 134 } 135 visible_ = true; 136 const NSTimeInterval interval = delay / 1000.0; 137 lasttimer_ = [NSTimer scheduledTimerWithTimeInterval:interval 138 target:timer_handler_.get() 139 selector:@selector(onTimer:) 140 userInfo:nil 141 repeats:NO]; 142} 143 144void InfolistWindow::Hide() { 145 bool visible = IsVisible(); 146 RendererBaseWindow::Hide(); 147 if (visible) { 148 SendUsageStatsEvent(command_sender_, SessionCommand::INFOLIST_WINDOW_HIDE); 149 } 150 visible_ = false; 151} 152 153void InfolistWindow::Show() { 154 bool visible = IsVisible(); 155 RendererBaseWindow::Show(); 156 if (!visible) { 157 SendUsageStatsEvent(command_sender_, SessionCommand::INFOLIST_WINDOW_SHOW); 158 } 159 visible_ = true; 160} 161 162void InfolistWindow::onTimer(NSTimer* timer) { 163 DLOG(INFO) << "InfolistWindow::onTimer()"; 164 if (visible_) { 165 Show(); 166 } else { 167 Hide(); 168 } 169 lasttimer_ = nil; 170} 171 172void InfolistWindow::ResetView(){ 173 DLOG(INFO) << "InfolistWindow::ResetView()"; 174 view_.reset([[InfolistView alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)]); 175} 176 177 178} // namespace mozc::renderer::mac 179} // namespace mozc::renderer 180} // namespace mozc 181