BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) { float cursor_point[2]; LLCoordScreen screen_pos; if(mWindow == NULL) return FALSE; getCursorPos(mWindow, cursor_point); if(mCursorDecoupled) { // CGMouseDelta x, y; // If the cursor's decoupled, we need to read the latest movement delta as well. // CGGetLastMouseDelta( &x, &y ); // cursor_point.h += x; // cursor_point.v += y; // CGGetLastMouseDelta may behave strangely when the cursor's first captured. // Stash in the event handler instead. cursor_point[0] += mCursorLastEventDeltaX; cursor_point[1] += mCursorLastEventDeltaY; } position->mX = cursor_point[0]; position->mY = cursor_point[1]; return TRUE; }
long fx_numeric_field::change_on_digit(int sign) { FXString txt = getText(); int pos = getCursorPos(); int pow_exp, dot_pos; int norm = get_normalized_int (txt.text(), pow_exp, dot_pos); if (dot_pos < 0) return 0; int pos_exp = dot_pos - pos; if (pos_exp < 0) pos_exp ++; int inc_abs = ipow10 (pos_exp + pow_exp); norm += sign * inc_abs; FXString new_txt = denormalize (norm, pow_exp, dot_pos); int new_pos = dot_pos - pos_exp; if (pos_exp < 0) new_pos ++; setText(new_txt); setCursorPos(new_pos); if (target) target->tryHandle(this, FXSEL(SEL_CHANGED,message), (void*)new_txt.text()); return 1; }
bool CATextField::becomeFirstResponder() { bool result = CAView::becomeFirstResponder(); if (result) { attachWithIME(); this->showCursorMark(); if (m_nInputType == KEY_BOARD_INPUT_PASSWORD) { if (m_sText.empty()) { m_pCursorMark->setCenterOrigin(CCPoint(getCursorX() + m_iHoriMargins, m_obContentSize.height / 2)); } } calculateSelChars(CCPoint(this->getCursorX() + m_iHoriMargins, m_obContentSize.height / 2), m_iString_l_length, m_iString_r_length, m_iCurPos); m_pCursorMark->setCenterOrigin(CCPoint(getCursorX() + m_iHoriMargins, m_obContentSize.height / 2)); #if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif } return result; }
void QHexEditPrivate::mousePressEvent(QMouseEvent * event) { _blink = false; update(); int cursorPos = getCursorPos(event->pos()); resetSelection(cursorPos); setCursorPos(cursorPos); }
void QHexEditPrivate::mouseMoveEvent(QMouseEvent * event) { _blink = false; update(); int actPos = getCursorPos(event->pos()); setCursorPos(actPos); setSelection(actPos); }
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) { /// Left click is for adding a new point and draging a old one if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { Point cursorPos = getCursorPos(window); if (!movingAPoint) { float eps = 0.15; Point difference; for (int i = 0; i < controlPolygon.size() && !movingAPoint; i++) { difference = cursorPos - controlPolygon[i]; if (fabs(difference.x) <= eps && fabs(difference.y) <= eps) { movingAPoint = true; movingIndex = i; } } } if (!movingAPoint) { addNewPoint = true; controlPolygon.push_back(cursorPos); } } /// If we have moved a point and now released the left button we stop the /// moving else if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) { if (movingAPoint) { movingAPoint = false; movingIndex = -1; } } /// The right button is used to delete a point. else if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) { if (!movingAPoint) { Point cursorPos = getCursorPos(window); Point difference; double eps = 0.15; for (int i = 0; i < controlPolygon.size() && !delPoint; i++) { difference = cursorPos - controlPolygon[i]; if (fabs(difference.x) <= eps && fabs(difference.y) <= eps) { delPoint = true; controlPolygon.erase(controlPolygon.begin() + i); } } } } }
void update(float time_increase) { float x,y; getCursorPos(&x,&y); anglex=-4*3.14f*x/window_w; angley=1500*(y-300)/window_h; mgr->update(time_increase); }
void DailyForecast(wstring city) { WeatherInfo weather; int c = 0; ShowCursor(); while (c < 1 || c > 16) { cls(); Center(32, true); cout << "Input number of days to show(1-16): "; string temp; cin >> temp; if (!((temp[0] < 48 || temp[0] > 57) && (temp[1] < 48 || temp[0] > 57))) c = stoi(temp.substr(0,2)); } HideCursor(); wchar_t count[3]; _itow_s(c, count, 10); auto result(async(SendRequest, L"forecast/daily?q=" + city + L"&cnt=" + count)); cls(); Center(16, true); cout << "Fetching data"; cursorPos = getCursorPos(); for (int i = 0; result.wait_for(span) != future_status::ready; i++) { SetConsoleCursorPosition(ConsoleH, cursorPos); switch (i % 4) { case 0: cout << " "; break; case 1: cout << ". "; break; case 2: cout << ".. "; break; case 3: cout << "..."; } if (i > 50) { Center(16, true); cout << " Fetch failed "; SetConsoleTextAttribute(ConsoleH, 240); Center(4, 4); cout << "Back"; SetConsoleTextAttribute(ConsoleH, 15); while (_getch() != 13); return; } } weather = ParseDaily(result.get()); auto weatherI = DayMenu(weather); if (weatherI.main == "back") return; PrintDaily(weatherI, weather.cityName); }
void CATextView::pasteFromClipboard() { std::string cszText = CAClipboard::getText(); insertText(cszText.c_str(), (int)cszText.size()); #if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif }
void SciDoc::insertText(const QString& text) { if ( int_->curEdit_ == NULL ) return; int row, col; getCursorPos(row, col); int newLines = text.count(LineSeparatorRx); int_->curEdit_->insert(text); if ( newLines == 0 ) setCursorPos(row, col + text.length()); }
void SciDoc::reload() { if ( !isNoname() ) { int line, col; getCursorPos(line, col); int scroll = scrollPos(); readFile(); setModified(false); if ( line >= 0 && col >= 0 ) { setCursorPos(line, col); setScrollPos(scroll); } } }
// <FS:Ansariel> Fix linefeed pasting //virtual void LLChatEntry::paste() { LLTextEditor::paste(); if (mSingleLineMode) { S32 cursor_pos = getCursorPos(); LLWString content = getWText(); LLWStringUtil::replaceChar(content, '\n', llwchar(182)); setWText(content); setCursorPos(cursor_pos); } }
long MyText::onKeyPress(FXObject*o, FXSelector sel, void*p) { FXEvent*ev=(FXEvent*)p; if (ev) { switch (ev->code) { case KEY_ISO_Left_Tab: { if (tabup) { tabup->setFocus(); ClearCursor(getCursorPos()); return 1; } } case KEY_Tab: { if (tabdown) { tabdown->setFocus(); ClearCursor(getCursorPos()); return 1; } } } } return FXText::onKeyPress(o,sel,p); }
TextBox(Context& mContext, const Vec2f& mSize) : Widget{mContext, mSize / 2.f}, tBox(create<Widget>()), lblText(tBox.create<Label>("")), cursor(editStr), cursorShape{float(getStyle().getGlyphHeight())} { setFillColor(sf::Color::Transparent); lblText.onPostDraw += [this] { if(editing) render(cursorShape.getShape()); }; tBox.setOutlineColor(getStyle().colorOutline); tBox.setOutlineThickness(getStyle().outlineThickness); tBox.setFillColor(sf::Color::White); tBox.setScaling(Scaling::FitToNeighbor); lblText.setScaling(Scaling::FitToNeighbor); tBox.attach(At::Center, *this, At::Center); lblText.attach(At::Center, tBox, At::Center); onLeftClick += [this] { if(!editing) editStr = str; editing = true; if(isKeyPressed(ssvs::KKey::LShift)) cursor.setEnd(getCursorPos()); else cursor.setBoth(getCursorPos()); }; onLeftClickDown += [this] { cursor.setEnd(getCursorPos()); }; }
void CATextView::setText(const std::string& var) { CATextViewDelegate* pTemp = m_pTextViewDelegate; m_pTextViewDelegate = NULL; m_szText.clear(); m_iCurPos = 0; m_vLinesTextView.clear(); m_curSelCharRange = std::make_pair(0, 0); insertText(var.c_str(), (int)var.length()); m_pTextViewDelegate = pTemp; m_bUpdateImage = true; #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif }
long MyText::onTextCursor(FXObject*o, FXSelector sel, void*p) { if (hasFocus()||(p==this)) { static FXint oldpos=0; FXint newpos=getCursorPos(); if (oldpos!=newpos) { ClearCursor(oldpos); oldpos=newpos; } FXDCWindow dc(this); paintCursor(dc); getApp()->addTimeout(this,ID_TEXT_CURSOR,ONE_SECOND/30); } else { getApp()->addTimeout(this,ID_TEXT_CURSOR,ONE_SECOND); } return 1; }
void SciDoc::replaceSelectedText(const QString& text, bool cursorToTheEnd) { if ( int_->curEdit_ == NULL ) return; int line1, col1, line2, col2; if ( !int_->curEdit_->hasSelectedText() ) { // no selected text - just insert the text we have if ( !text.isEmpty() ) { getCursorPos(line1, col1); int_->curEdit_->beginUndoAction(); insertText(text); if ( cursorToTheEnd ) { moveCursorToTheEnd(line1, col1, text); } int_->curEdit_->endUndoAction(); } } else { int_->curEdit_->getSelection(&line1, &col1, &line2, &col2); int_->curEdit_->beginUndoAction(); // hack! hack! hack! disconnect(int_->edit1_, SIGNAL(textChanged()), this, SIGNAL(textChanged())); removeSelectedText(); // hack! hack! hack! connect(int_->edit1_, SIGNAL(textChanged()), this, SIGNAL(textChanged())); if ( text.isEmpty() ) { // need to emit the signal manually emit textChanged(); } else { insertText(text); } if ( cursorToTheEnd ) { moveCursorToTheEnd(line1, col1, text); } else { int_->curEdit_->setCursorPosition(line1, col1); } int_->curEdit_->endUndoAction(); } }
void CATextField::ccTouchEnded(CATouch *pTouch, CAEvent *pEvent) { CCPoint point = this->convertTouchToNodeSpace(pTouch); if (this->getBounds().containsPoint(point)) { becomeFirstResponder(); if (isFirstResponder()) { this->showCursorMark(); if (m_nInputType == KEY_BOARD_INPUT_PASSWORD) { if (!m_sText.empty()) { m_iCurPos =(int)m_vTextFiledChars.size(); m_iString_l_length = m_cImageSize.width; } m_pCursorMark->setCenterOrigin(CCPoint(getCursorX() + m_iHoriMargins, m_obContentSize.height / 2)); return; } calculateSelChars(point, m_iString_l_length, m_iString_r_length, m_iCurPos); m_pCursorMark->setCenterOrigin(CCPoint(getCursorX() + m_iHoriMargins, m_obContentSize.height / 2)); } #if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif } else { hideCursorMark(); if (resignFirstResponder()) { this->updateImage(); } } m_curSelCharRange = std::make_pair(m_iCurPos, m_iCurPos); execCurSelCharRange(); }
void CATextField::ccTouchEnded(CATouch *pTouch, CAEvent *pEvent) { CATouchView::ccTouchEnded(pTouch, pEvent); if (CATextToolBarView::isTextToolBarShow()) return; if (m_bMoved) { m_bMoved = false; return; } CCPoint point = this->convertTouchToNodeSpace(pTouch); if (this->getBounds().containsPoint(point)) { if (canAttachWithIME()) { becomeFirstResponder(); calculateSelChars(point, m_iString_l_length, m_iString_r_length, m_iCurPos); m_pCursorMark->setCenterOrigin(CCPoint(getCursorX() + m_iHoriMargins, m_obContentSize.height / 2)); #if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif } } else { if (canDetachWithIME()) { resignFirstResponder(); } } m_curSelCharRange = std::make_pair(m_iCurPos, m_iCurPos); execCurSelCharRange(); }
bool CATextField::becomeFirstResponder() { resignAllResponder(this); bool result = CAView::becomeFirstResponder(); if (result) { result = attachWithIME(); this->showCursorMark(); calculateSelChars(CCPoint(this->getCursorX() + m_iHoriMargins, m_obContentSize.height / 2), m_iString_l_length, m_iString_r_length, m_iCurPos); setCursorPosition(); #if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif } return result; }
/** * Handles changes in the cursor position. * Emits a signal with the new line and column numbers. */ void EditorPage::slotCursorPosChange() { uint nLine, nCol; // Find the new line and column number, and emit the signal if (!getCursorPos(nLine, nCol)) return; emit cursorPosChanged(nLine, nCol); // Select the relevant symbol in the tag list if (Config().getAutoTagHl() && (m_nLine != nLine)) { m_pCtagsList->gotoLine(nLine); m_nLine = nLine; } // Abort code completion on cursor changes during the completion // process m_pCompletion->abort(); }
void CATextField::setText(const std::string &var) { CATextFieldDelegate* pTemp = m_pDelegate; m_pDelegate = NULL; m_sText.clear(); m_iCurPos = 0; m_curSelCharRange = std::make_pair(0, 0); m_iString_o_length = 0; m_iString_l_length = 0; m_iString_r_length = 0; m_vTextFiledChars.clear(); CCPoint p = CCPoint(this->getCursorX() + m_iHoriMargins, m_obContentSize.height / 2); m_pCursorMark->setCenterOrigin(p); insertText(var.c_str(), (int)var.length()); m_pDelegate = pTemp; #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif }
void Game::updateMouseMovement() { if( _curScreen != nullptr ) { glm::vec2 cursorPos = getCursorPos(); cursorPos.x = ( cursorPos.x + 1 ) * 0.5f * _width; // Adjust cursor position.x from [-1, 1] to [0, width] cursorPos.y = ( cursorPos.y + 1 ) * 0.5f * _height; // Adjust cursor position.y from [-1, 1] to [0, height] glm::vec2 displacement = cursorPos - _mousePos; // Dispatch a "mouse move" event if the mouse is in a different position that before if( displacement.x * displacement.x + displacement.y * displacement.y > 0 ) { MouseEvent e( MouseEvent::MOUSE_MOVE, cursorPos.x, cursorPos.y, displacement.x, displacement.y ); _curScreen->onMouseMove( e ); } _mousePos = cursorPos; } }
void COSXScreen::fakeMouseButton(ButtonID id, bool press) const { // get button index UInt32 index = id - kButtonLeft; if (index >= sizeof(m_buttons) / sizeof(m_buttons[0])) { return; } // update state m_buttons[index] = press; CGPoint pos; if (!m_cursorPosValid) { SInt32 x, y; getCursorPos(x, y); } pos.x = m_xCursor; pos.y = m_yCursor; postMouseEvent(pos); }
void SciDoc::stripTrailingSpaces() { // LOGGER; if ( int_->curEdit_ == NULL ) return; int line, col; getCursorPos(line, col); QString text = int_->curEdit_->text(); QStringList lines = text.split(LineSeparatorRx); QRegExp rx("[ \t]+$"); int i = 0; beginUndoAction(); foreach (QString str, lines) { int pos = str.indexOf(rx); if ( pos >= 0 ) { int_->curEdit_->setSelection(i, 0, i, str.length()); str.truncate(pos); replaceSelectedText(str); } ++i; }
void Game::onMouseButtonChange( int button, int action, int mods ) { if( _curScreen != nullptr ) { if( button == GLFW_MOUSE_BUTTON_LEFT ) { glm::vec2 cursorPos = getCursorPos(); if( action == GLFW_PRESS ) { MouseEvent e( MouseEvent::MOUSE_DOWN, cursorPos.x, cursorPos.y ); _curScreen->onMouseDown( e ); } else { MouseEvent e( MouseEvent::MOUSE_UP, cursorPos.x, cursorPos.y ); _curScreen->onMouseUp( e ); } } } }
void CATextView::ccTouchEnded(CATouch *pTouch, CAEvent *pEvent) { if (CATextToolBarView::isTextToolBarShow()) return; if (m_bMoved) { m_bMoved = false; return; } CCPoint point = this->convertTouchToNodeSpace(pTouch); if (this->getBounds().containsPoint(point)) { if (!m_pTextSelView->isTextViewShow()) { becomeFirstResponder(); int iCurLine = 0; int iCurPosX = 0; calculateSelChars(point, iCurLine, iCurPosX, m_iCurPos); m_pCursorMark->setCenterOrigin(CCPoint(iCurPosX, m_iLineHeight*1.25f*iCurLine + m_iLineHeight / 2)); showCursorMark(); CCPoint pt = m_pCursorMark->getCenterOrigin(); m_pTextArrView->showTextArrView(CCPoint(pt.x, pt.y + m_iLineHeight*1.2f + m_pContainerView->getContentOffset().y)); m_curSelCharRange = std::pair<int,int>(m_iCurPos, m_iCurPos); #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID CCEGLView * pGlView = CAApplication::getApplication()->getOpenGLView(); pGlView->setIMECursorPos(getCursorPos(), getContentText()); #endif } } else { resignFirstResponder(); } CATouchView::ccTouchEnded(pTouch, pEvent); }
void update(float time_increase) { int newindex=-1; float x,y; getCursorPos(&x,&y); if (x >= 400 && y <= 300) { if (x-400 < (300-y)/2) newindex=0; else if (x-400 > (300-y)*2) newindex=2; else newindex=1; } else if (x < 400 && y <= 300) { if (400-x < (300-y)/2) newindex=0; else if (400-x > (300-y)*2) newindex=6; else newindex=7; } else if (x >= 400 && y > 300) { if (x-400 < (y-300)/2) newindex=4; else if (x-400 > (y-300)*2) newindex=2; else newindex=3; } else if (x < 400 && y > 300) { if (400-x < (y-300)/2) newindex=4; else if (400-x > (y-300)*2) newindex=6; else newindex=5; } if (newindex >= 0) { clips[cClip]->pause(); cClip=newindex; clips[cClip]->play(); } mgr->update(time_increase); }
void World::onUpdate() { screenCenter = screen.getPosition(); const je::Input input = getGame().getInput(); if (input.isKeyHeld(sf::Keyboard::Key::Left)) { screenCenter.x += -10; } if (input.isKeyHeld(sf::Keyboard::Key::Right)) { screenCenter.x += 10; } if (input.isKeyHeld(sf::Keyboard::Key::Up)) { screenCenter.y += -10; } if (input.isKeyHeld(sf::Keyboard::Key::Down)) { screenCenter.y += 10; } if (input.isButtonPressed(sf::Mouse::Button::Right)) { switch (currentlySelectedPower) { case Power::Rain: { addEntity(new Rain(this, sf::Vector2f(getCursorPos().x, 0.f))); } break; case Power::Lightning: { // why the hell do I have to multiply getWidth() by 2?! const sf::Vector2f start(je::randomf(getWidth() * 2), 0.f); mouseClickPoint = this->getCursorPos(); const sf::Vector2f end = mouseClickPoint; addEntity(new LightningBolt(this, start, end)); } break; } } else if (input.isButtonReleased(sf::Mouse::Button::Left)) { if (input.isKeyHeld(sf::Keyboard::Key::A)) light->shine(mouseClickPoint, getCursorPos()); } if (input.isKeyPressed(sf::Keyboard::Key::Q)) { if (currentlySelectedPower == Power::Rain) { currentlySelectedPower = Power::Lightning; } else if (currentlySelectedPower == Power::Lightning) { currentlySelectedPower = Power::Rain; } } if (input.isKeyPressed(sf::Keyboard::Key::E)) { if (currentlySelectedPower == Power::Rain) { currentlySelectedPower = Power::Lightning; } else if (currentlySelectedPower == Power::Lightning) { currentlySelectedPower = Power::Rain; } } // restart if (input.isKeyPressed(sf::Keyboard::Key::R)) { getGame().setLevel(new World(&getGame())); } screen.update(screenCenter); // check for if you achieved some things int minBuildingX = getWidth(); int maxBuildingX = 0; std::map<Building::Type, int> buildingCount; for (const je::Entity *entity : entities["Building"]) { const Building& building = *static_cast<const Building*>(entity); ++buildingCount[building.getBuildingType()]; if (building.getBuildingType() != Building::Type::Bonfire) { const int minX = building.getPos().x - building.getMask().getWidth(); if (minX < minBuildingX) { minBuildingX = minX; } const int maxX = building.getPos().x + building.getMask().getWidth(); if (maxX > maxBuildingX) { maxBuildingX = maxX; } } } // spawn initial house if (entities["Building"].empty()) { if (tree->getTrunk()->getMask().getHeight() > 32) { addEntity(new Building(this, sf::Vector2f(getWidth() / 2.f - 128 + je::randomf(256), groundLevel), Building::Type::BasicHouse)); } else { tree->grow(0.5f); } } const int gnomeCount = entities["Gnome"].size(); if (gnomeCount >= 3 && buildingCount[Building::Type::Bonfire] < gnomeCount / 9) { int count = 0; int x; bool bonfireHere = false; do { x = je::random(getWidth()); ++count; Building *b = static_cast<Building*>(testCollision(sf::Rect<int>(x, groundLevel - 32, 32, 32), "Building")); bonfireHere = b && b->getBuildingType() == Building::Type::Bonfire; } while (count < 32 && bonfireHere); if (count < 32) { addEntity(new Building(this, sf::Vector2f(x, groundLevel), Building::Type::Bonfire)); } } else if (gnomeCount >= 15 && buildingCount[Building::Type::Church] < gnomeCount / 17) { const int variance = je::random(10) - 5; const int buildingX = minBuildingX - 32 < 0 ? maxBuildingX + 32 : maxBuildingX > getWidth() + 32 ? minBuildingX - 32 : je::choose({minBuildingX - 32, maxBuildingX + 32}); addEntity(new Building(this, sf::Vector2f(buildingX + variance, groundLevel), Building::Type::Church)); } else if (buildingCount[Building::Type::BasicHouse] < gnomeCount / 7) { const int variance = je::random(8) - 4; const int buildingX = minBuildingX < 0 ? maxBuildingX : (maxBuildingX > getWidth() ? minBuildingX: je::choose({minBuildingX, maxBuildingX})); addEntity(new Building(this, sf::Vector2f(buildingX + variance, groundLevel), Building::Type::BasicHouse)); } }
void COSXScreen::fakeMouseButton(ButtonID id, bool press) { NXEventHandle handle = NXOpenEventStatus(); double clickTime = NXClickTime(handle); if ((ARCH->time() - m_lastDoubleClick) <= clickTime) { // drop all down and up fakes immedately after a double click. // TODO: perhaps there is a better way to do this, usually in // finder, if you tripple click a folder, it will open it and // then select a folder under the cursor -- and perhaps other // strange behaviour might happen? LOG((CLOG_DEBUG1 "dropping mouse button %s", press ? "press" : "release")); return; } // Buttons are indexed from one, but the button down array is indexed from zero UInt32 index = id - kButtonLeft; if (index >= NumButtonIDs) { return; } CGPoint pos; if (!m_cursorPosValid) { SInt32 x, y; getCursorPos(x, y); } pos.x = m_xCursor; pos.y = m_yCursor; // variable used to detect mouse coordinate differences between // old & new mouse clicks. Used in double click detection. SInt32 xDiff = m_xCursor - m_lastSingleClickXCursor; SInt32 yDiff = m_yCursor - m_lastSingleClickYCursor; double diff = sqrt(xDiff * xDiff + yDiff * yDiff); // max sqrt(x^2 + y^2) difference allowed to double click // since we don't have double click distance in NX APIs // we define our own defaults. const double maxDiff = sqrt(2) + 0.0001; if (press && (id == kButtonLeft) && ((ARCH->time() - m_lastSingleClick) <= clickTime) && diff <= maxDiff) { LOG((CLOG_DEBUG1 "faking mouse left double click")); // finder does not seem to detect double clicks from two separate // CGEventCreateMouseEvent calls. so, if we detect a double click we // use CGEventSetIntegerValueField to tell the OS. // // the caveat here is that findor will see this as a single click // followed by a double click (even though there should be only a // double click). this may cause weird behaviour in other apps. // // for some reason using the old CGPostMouseEvent function, doesn't // cause double clicks (though i'm sure it did work at some point). CGEventRef event = CGEventCreateMouseEvent( NULL, kCGEventLeftMouseDown, pos, kCGMouseButtonLeft); CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2); m_buttonState.set(index, kMouseButtonDown); CGEventPost(kCGHIDEventTap, event); CGEventSetType(event, kCGEventLeftMouseUp); m_buttonState.set(index, kMouseButtonUp); CGEventPost(kCGHIDEventTap, event); CFRelease(event); m_lastDoubleClick = ARCH->time(); } else { // ... otherwise, perform a single press or release as normal. MouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp; LOG((CLOG_DEBUG1 "faking mouse button %s", press ? "press" : "release")); MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index]; CGEventType type = thisButtonMap[state]; CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, index); m_buttonState.set(index, state); CGEventPost(kCGHIDEventTap, event); CFRelease(event); m_lastSingleClick = ARCH->time(); m_lastSingleClickXCursor = m_xCursor; m_lastSingleClickYCursor = m_yCursor; } }