예제 #1
0
void HoverController::setWrapPanAngle(bool value)
{
	if (value != m_wrapPanAngle)
	{
		m_wrapPanAngle = value;
		notifyUpdate();
	}
}
예제 #2
0
void HoverController::setDistance(float value)
{
	if (value != m_distance)
	{
		m_distance = value;
		notifyUpdate();
	}
}
예제 #3
0
void HoverController::setYFactor(float value)
{
	if (value != m_yFactor)
	{
		m_yFactor = value;
		notifyUpdate();
	}
}
예제 #4
0
void HoverController::update(bool interpolate)
{
	if (m_tiltAngle != m_currentTiltAngle || m_panAngle != m_currentPanAngle)
	{
		notifyUpdate();

		if (m_wrapPanAngle)
		{
			float temp = std::fmod(m_panAngle, 360.f);
			if (m_panAngle < 0)
			{
				m_currentPanAngle += temp + 360 - m_panAngle;
				m_panAngle = temp + 360;
			}
			else
			{
				m_currentPanAngle += temp - m_panAngle;
				m_panAngle = temp;
			}

			while (m_panAngle - m_currentPanAngle < -180)
				m_currentPanAngle -= 360;

			while (m_panAngle - m_currentPanAngle > 180)
				m_currentPanAngle += 360;
		}

		if (interpolate)
		{
			m_currentTiltAngle += (m_tiltAngle - m_currentTiltAngle) / (m_steps + 1);
			m_currentPanAngle += (m_panAngle - m_currentPanAngle) / (m_steps + 1);
		}
		else
		{
			m_currentPanAngle = m_panAngle;
			m_currentTiltAngle = m_tiltAngle;
		}

		// snap coords if angle differences are close
		if ((std::abs(m_tiltAngle - m_currentTiltAngle) < 0.01f) && (std::abs(m_panAngle - m_currentPanAngle) < 0.01f))
		{
			m_currentTiltAngle = m_tiltAngle;
			m_currentPanAngle = m_panAngle;
		}
	}

	if (!m_targetObject)
		return;

	float panAngleRadian = m_currentPanAngle * MathConsts::DEGREES_TO_RADIANS;
	float tiltAngleRadian = m_currentTiltAngle * MathConsts::DEGREES_TO_RADIANS;
	float cosTiltAngle = std::cos(tiltAngleRadian);
	m_targetObject->setX(m_lookAtPosition.m_x + m_distance * std::sin(panAngleRadian) * cosTiltAngle);
	m_targetObject->setZ(m_lookAtPosition.m_z + m_distance * std::cos(panAngleRadian) * cosTiltAngle);
	m_targetObject->setY(m_lookAtPosition.m_y + m_distance * std::sin(tiltAngleRadian) * m_yFactor);

	LookAtController::update();
}
예제 #5
0
void HoverController::setTiltAngle(float value)
{
	value = std::max(m_minTiltAngle, std::min(m_maxTiltAngle, value));

	if (value != m_tiltAngle)
	{
		m_tiltAngle = value;
		notifyUpdate();
	}
}
예제 #6
0
void HoverController::setPanAngle(float value)
{
	value = std::max(m_minPanAngle, std::min(m_maxPanAngle, value));

	if (value != m_panAngle)
	{
		m_panAngle = value;
		notifyUpdate();
	}
}
void ViewSphereRender::moveFromTo( ViewPoint* fromPoint, ViewPoint* toPoint )
{
	if (fromPoint == NULL || toPoint == NULL)
		return;

	m_currentPos = fromPoint;
	m_camera.lookAt(fromPoint->theta, fromPoint->phi);
	notifyUpdate();
	moveTo(toPoint);
}
예제 #8
0
파일: dlgViewports.cpp 프로젝트: Nau3D/nau
void DlgViewports::OnPropsChange(wxPropertyGridEvent& e) {

	nau::render::Viewport *elem = RENDERMANAGER->getViewport(m_Active).get();
	const wxString& name = e.GetPropertyName();
	unsigned int dotLocation = name.find_first_of(wxT("."),0);
	std::string topProp = std::string(name.substr(0,dotLocation).mb_str());
	std::string prop = std::string(name.substr(dotLocation+1,name.size()-dotLocation-1).mb_str());

	PropertyManager::updateProp(m_PG, topProp, Viewport::GetAttribs(), (AttributeValues *)elem);
	notifyUpdate(PROPS_CHANGED,m_Active,topProp);
}
예제 #9
0
void HoverController::setSteps(int value)
{
	if (value < 1)
		value = 1;

	if (value != m_steps)
	{
		m_steps = value;
		notifyUpdate();
	}
}
예제 #10
0
void Render::wheelEvent( QWheelEvent *e )
{
	int numDegrees = e->delta() / 8;
	int numSteps = numDegrees / 15;

	if (numSteps > 0)
	{
		m_camera.zoomOut(1.1 * numSteps);
	}
	else if(numSteps < 0)
	{
		m_camera.zoomIn(-1.1 * numSteps);
	}
	notifyUpdate();
}
예제 #11
0
파일: dlgViewports.cpp 프로젝트: Nau3D/nau
void DlgViewports::OnAdd(wxCommandEvent& event) {

	int result;
	bool nameUnique,exit = false;
	std::string name;

	do {
		wxTextEntryDialog dialog(this,
								 _T("(the name must be unique)\n")
								 _T("Please Input a Viewport Name"),
								 _T("Viewport Name\n"),
								 _T(""),
								 wxOK | wxCANCEL);

		result = dialog.ShowModal();
		name = std::string(dialog.GetValue().mb_str());
		nameUnique = !RENDERMANAGER->hasViewport(name);

		if (!nameUnique && (result == wxID_OK)){
			wxMessageBox(_T("Viewport name must be unique") , _T("Viewport Name Error"), wxOK | wxICON_INFORMATION, this);
		}
		if (name == "" && (result == wxID_OK)){
			wxMessageBox(_T("Viewport name must not be void"), _T("Viewport Name Error"), wxOK | wxICON_INFORMATION, this);
		}

		if (result == wxID_CANCEL) {
			exit = true;
		}
		else if (nameUnique && name != "") {
			exit = true;
		}

	} while (!exit);

	if (result == wxID_OK) {
		RENDERMANAGER->createViewport(name);
		updateList();
		m_List->Select(m_List->FindString((wxString)name.c_str()));
		m_Active = name;
		update();
		notifyUpdate(NEW_VIEWPORT,name,"");
	}
}
void ViewSphereRender::animate()
{
	if (m_targetPos != NULL)
	{
		if (m_recorder->hasNext())
		{
			const ViewPoint* next = m_recorder->next();//nextPointNearest(m_currentPos, m_targetPos);
			if (next != NULL)
			{
				m_camera.lookAt(next->theta, next->phi);
				//////////////////////////////////////////////////////////////////////////
				updateTF();
				//////////////////////////////////////////////////////////////////////////
			}
		}
		else
		{
			m_timer->stop();
		}
		notifyUpdate();
	}
}
void FmBkupEnginePrivate::notifyUpdateInternal( int aCount )
    {
    emit notifyUpdate( aCount ); 
    }
예제 #14
0
void Render::mouseReleaseEvent( QMouseEvent *e )
{
	m_camera.endDrag(e->x(), e->y());
	notifyUpdate();
}
예제 #15
0
void Render::mouseMoveEvent( QMouseEvent *e )
{
	m_camera.mouseMove(e->x(), e->y());
	notifyUpdate();
}
예제 #16
0
void Render::mousePressEvent( QMouseEvent *e )
{
	m_camera.beginDrag(e->x(), e->y());
	notifyUpdate();
}
예제 #17
0
void Render::update()
{
	paint();
	notifyUpdate();
}
예제 #18
0
void notifyUpdateDefault() {
  notifyUpdate(DEFAULT_UPDATE_DEFER_TIME_MSEC);
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool RicBoxManipulatorEventHandler::eventFilter(QObject *obj, QEvent* inputEvent)
{
    if (inputEvent->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(inputEvent);

        if (mouseEvent->button() == Qt::LeftButton)
        {
            cvf::HitItemCollection hitItems;
            if (m_viewer->rayPick(mouseEvent->x(), mouseEvent->y(), &hitItems))
            {
                m_partManager->tryToActivateManipulator(hitItems.firstItem());

                if(m_partManager->isManipulatorActive())
                {
                    emit notifyRedraw();

                    return true;
                }
            }
        }
    }
    else if (inputEvent->type() == QEvent::MouseMove)
    {
        if (m_partManager->isManipulatorActive())
        {
            QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(inputEvent);

            //qDebug() << "Inside mouse move";
            //qDebug() << mouseEvent->pos();

            int translatedMousePosX = mouseEvent->pos().x();
            int translatedMousePosY = m_viewer->height() - mouseEvent->pos().y();

            cvf::ref<cvf::Ray> ray = m_viewer->mainCamera()->rayFromWindowCoordinates(translatedMousePosX, translatedMousePosY);
            {
                m_partManager->updateManipulatorFromRay(ray.p());

                cvf::Vec3d origin;
                cvf::Vec3d size;
                m_partManager->originAndSize(&origin, &size);

                emit notifyUpdate(origin, size);

                emit notifyRedraw();

                return true;
            }
        }
    }
    else if (inputEvent->type() == QEvent::MouseButtonRelease)
    {
        if (m_partManager->isManipulatorActive())
        {
            m_partManager->endManipulator();

            cvf::Vec3d origin;
            cvf::Vec3d size;
            m_partManager->originAndSize(&origin, &size);

            emit notifyUpdate(origin, size);

            return true;
        }
    }

    return false;
}
pp_int32 PatternEditorControl::dispatchEvent(PPEvent* event)
{ 
	if (pattern == NULL)
		return -1;

	if (eventListener == NULL)
		return -1;

	switch (event->getID())
	{
		case eFocusGained:
		case eFocusGainedNoRepaint:
		{	
			hasFocus = true;
			if (menuInvokeChannel != -1)
			{
				lastMenuInvokeChannel = menuInvokeChannel;
				menuInvokeChannel = -1;
				//parentScreen->paintControl(this);			
			}
			
			if (event->getID() == eFocusGained)
				parentScreen->paintControl(this);			
			
			//resetKeyModifier();
			goto leave;
		}

		case eFocusLost:
		{	
			hasFocus = false;	
			parentScreen->paintControl(this);			
			//resetKeyModifier();
			goto leave;
		}

		case eFocusLostNoRepaint:
		{	
			hasFocus = false;
			//resetKeyModifier();
			goto leave;
		}

		case eMouseWheelMoved:
		{
			TMouseWheelEventParams* params = (TMouseWheelEventParams*)event->getDataPtr();
			
			// Vertical scrolling takes priority over horizontal scrolling and is mutually
			// exclusive from horizontal scrolling.
			if (params->deltaY)
			{
				PPEvent e = params->deltaY < 0 ? PPEvent(eBarScrollDown) : PPEvent(eBarScrollUp);
				handleEvent(reinterpret_cast<PPObject*>(vLeftScrollbar), &e);
			}
			
			else if (params->deltaX)
			{
				PPEvent e = params->deltaX > 0 ? PPEvent(eBarScrollDown) : PPEvent(eBarScrollUp);
				handleEvent(reinterpret_cast<PPObject*>(hBottomScrollbar), &e);
			}
			
			event->cancel();
			
			break;
		}

		case eRMouseDown:
		{			
			PPPoint* p = (PPPoint*)event->getDataPtr();

			if (hTopScrollbar->hit(*p))
			{
				if (controlCaughtByLMouseButton)
					break;
				controlCaughtByRMouseButton = true;
				caughtControl = hTopScrollbar;
				caughtControl->dispatchEvent(event);
			}
			else if (hBottomScrollbar->hit(*p))
			{
				if (controlCaughtByLMouseButton)
					break;
				controlCaughtByRMouseButton = true;
				caughtControl = hBottomScrollbar;
				caughtControl->dispatchEvent(event);
			}
			// Clicked on vertical scrollbar -> route event to scrollbar and catch scrollbar control
			else if (vLeftScrollbar->hit(*p))
			{
				if (controlCaughtByLMouseButton)
					break;
				controlCaughtByRMouseButton = true;
				caughtControl = vLeftScrollbar;
				caughtControl->dispatchEvent(event);				
			}
			else if (vRightScrollbar->hit(*p))
			{
				if (controlCaughtByLMouseButton)
					break;
				controlCaughtByRMouseButton = true;
				caughtControl = vRightScrollbar;
				caughtControl->dispatchEvent(event);				
			}
			else 
			{
				RMouseDownInChannelHeading = -1;
				lastAction = RMouseDownActionFirstRClick;

				PPPoint cp = *p;
				
				cp.x-=location.x + SCROLLBARWIDTH + getRowCountWidth() + 4;
				cp.y-=location.y + SCROLLBARWIDTH + font->getCharHeight() + 4;
				
				if (cp.x < 0)
					break;

				// right click on channel number
				if ((RMouseDownInChannelHeading = pointInChannelHeading(cp)) != -1)
				{
					goto leave;
				}
				else if (cp.y < 0) break;

				pp_int32 i = (cp.x / slotSize) + startPos;
				if (i < 0 || i > patternEditor->getNumChannels()-1)
					break;

				invokeMenu(i, *p);
			}
			
			goto leave;
		}

		case eRMouseUp:
		{
			controlCaughtByRMouseButton = false;
			if (caughtControl && !controlCaughtByLMouseButton && !controlCaughtByRMouseButton)
			{
				caughtControl->dispatchEvent(event);
				caughtControl = NULL;			
				break;
			}

			PPPoint cp = *((PPPoint*)event->getDataPtr());
			
			cp.x-=location.x + SCROLLBARWIDTH + getRowCountWidth() + 4;
			cp.y-=location.y + SCROLLBARWIDTH + font->getCharHeight() + 4;
			
			if (cp.x < 0 || RMouseDownInChannelHeading == -1)
				break;
			
			// right click on channel number
			if ((menuInvokeChannel = pointInChannelHeading(cp)) != -1 && 
				menuInvokeChannel == RMouseDownInChannelHeading &&
				lastAction == RMouseDownActionFirstRClick)
			{
				RMouseDownInChannelHeading = -1;
				parentScreen->paintControl(this);
				executeMenuCommand(MenuCommandIDMuteChannel);
				menuInvokeChannel = lastMenuInvokeChannel = -1;
				parentScreen->paintControl(this);
				goto leave;
			}
			RMouseDownInChannelHeading = -1;
			menuInvokeChannel = -1;
			parentScreen->paintControl(this);

			break;
		}

		case eLMouseDown:
		{
			hasDragged = false;

			PPPoint* p = (PPPoint*)event->getDataPtr();

			// Clicked on horizontal scrollbar -> route event to scrollbar and catch scrollbar control
			if (hTopScrollbar->hit(*p))
			{
				if (controlCaughtByRMouseButton)
					break;
				controlCaughtByLMouseButton = true;
				caughtControl = hTopScrollbar;
				caughtControl->dispatchEvent(event);
			}
			else if (hBottomScrollbar->hit(*p))
			{
				if (controlCaughtByRMouseButton)
					break;
				controlCaughtByLMouseButton = true;
				caughtControl = hBottomScrollbar;
				caughtControl->dispatchEvent(event);
			}
			// Clicked on vertical scrollbar -> route event to scrollbar and catch scrollbar control
			else if (vLeftScrollbar->hit(*p))
			{
				if (controlCaughtByRMouseButton)
					break;
				controlCaughtByLMouseButton = true;
				caughtControl = vLeftScrollbar;
				caughtControl->dispatchEvent(event);				
			}
			else if (vRightScrollbar->hit(*p))
			{
				if (controlCaughtByRMouseButton)
					break;
				controlCaughtByLMouseButton = true;
				caughtControl = vRightScrollbar;
				caughtControl->dispatchEvent(event);				
			}
			// Clicked in client area
			else
			{
				PPPoint cp = *p;
				
				cp.x-=location.x + SCROLLBARWIDTH + getRowCountWidth() + 4;
				cp.y-=location.y + SCROLLBARWIDTH + font->getCharHeight() + 4;
				
				if (cp.y <  -((pp_int32)font->getCharHeight() + 6))
					break;

				if (cp.x < -(getRowCountWidth() + 4))
					break;
				
				// select new row by clicking on row number
				if (cp.x < -3)
				{			
					pp_int32 newStartIndex = cp.y / font->getCharHeight();					
					pp_int32 newStartPos = cp.x / slotSize;
					
					pp_int32 visibleRows = (visibleHeight) / font->getCharHeight();
					pp_int32 visibleChannels = (visibleWidth) / slotSize;
					
					// copy of current selection
					patternEditor->getSelection().backup();
					
					preCursor = patternEditor->getCursor();
					
					if (newStartIndex < visibleRows && newStartIndex >= 0)
					{
						if (newStartIndex + startIndex < 0)
							break;
						
						preCursor.row = newStartIndex + startIndex;
					}
					
					ppreCursor = &preCursor;
					break;
				}
				else if (cp.x < 0)
				{
					break;
				}

				pp_int32 i;
				if ((i = pointInChannelHeading(cp)) != -1)
				{
				
					// Special commands
					// Right button is pressed and left button is pressed
					if (::getKeyModifier() & KeyModifierALT)
					{
						RMouseDownInChannelHeading = i;
						lastAction = RMouseDownActionSecondLClick;
					}
					
					if (RMouseDownInChannelHeading == i)
					{
						if (lastAction == RMouseDownActionFirstRClick ||
							lastAction == RMouseDownActionSecondLClick)
						{
							if (isSoloChannel(i))
								goto unmuteAll;
							menuInvokeChannel = i;
							executeMenuCommand(MenuCommandIDSoloChannel);
							parentScreen->paintControl(this);
							lastAction = RMouseDownActionFirstLClick;
							hasDragged = true;
							goto leave;
						}
						else if (lastAction == RMouseDownActionFirstLClick)
						{
unmuteAll:
							menuInvokeChannel = i;
							executeMenuCommand(MenuCommandIDUnmuteAll);
							parentScreen->paintControl(this);
							lastAction = RMouseDownActionSecondLClick;
							hasDragged = true;
							goto leave;
						}
					}
				
					if (i == lastMenuInvokeChannel)
					{
						lastMenuInvokeChannel = -1;
						goto leave;
					}
				
					// show menu
					pp_int32 menuPosY = location.y + SCROLLBARWIDTH + 1 + font->getCharHeight();
					pp_int32 menuPosX = location.x + SCROLLBARWIDTH + getRowCountWidth() + 4 + slotSize * (i - startPos);
				
					PPPoint p2(menuPosX, menuPosY);

					invokeMenu(i, p2);
					goto leave;					
				}
				else if (cp.y < 0) break;

				pp_int32 newStartIndex = cp.y / font->getCharHeight();

				pp_int32 newStartPos = cp.x / slotSize;
				
				pp_int32 visibleRows = (visibleHeight) / font->getCharHeight();
				pp_int32 visibleChannels = (visibleWidth) / slotSize;
				
				// copy of current selection
				patternEditor->getSelection().backup();
				
				// If we're pressing the shift key start selection 
				// at current cursor position
				if (::getKeyModifier() & selectionKeyModifier)
				{
					if (patternEditor->getSelection().start.isValid())
						patternEditor->getSelection().end = patternEditor->getCursor();
					else
						patternEditor->getSelection().start = patternEditor->getCursor();
				}

				preCursor = patternEditor->getCursor();

				if (newStartIndex < visibleRows && newStartIndex >= 0)
				{
					if (newStartIndex + startIndex < 0)
						break;

					preCursor.row = newStartIndex + startIndex;
				}

				if (newStartPos < visibleHeight && newStartPos >= 0)
				{
					selectionTicker = 0;
					startSelection = true;

					if (newStartPos + startPos < 0)
						break;

					preCursor.channel = newStartPos + startPos;
				
					if (preCursor.channel >= patternEditor->getNumChannels())
						break;
				
					// start selecting row
					if (!(::getKeyModifier() & selectionKeyModifier))
					{
						patternEditor->getSelection().start.channel = patternEditor->getSelection().end.channel = preCursor.channel;
						patternEditor->getSelection().start.row = patternEditor->getSelection().end.row = preCursor.row;
					}
					else
					{
						patternEditor->getSelection().end.channel = preCursor.channel;
						patternEditor->getSelection().end.row = preCursor.row;
					}

					pp_int32 innerPos = cp.x % slotSize;

					preCursor.inner = 0;
					if (!(::getKeyModifier() & selectionKeyModifier))
						patternEditor->getSelection().start.inner = 0;
					patternEditor->getSelection().end.inner = 0;
					for (pp_uint32 i = 0; i < sizeof(cursorPositions) - 1; i++)
					{
						if (innerPos >= cursorPositions[i] &&
							innerPos < cursorPositions[i+1])
						{
							preCursor.inner = i;
							if (!(::getKeyModifier() & selectionKeyModifier))
								patternEditor->getSelection().start.inner = i;
							patternEditor->getSelection().end.inner = i;
							break;
						}
					}
				}

				ppreCursor = &preCursor;

				//parentScreen->paintControl(this);
			}

			break;
		}

		case eLMouseUp:
			controlCaughtByLMouseButton = false;
			if (caughtControl && !controlCaughtByLMouseButton && !controlCaughtByRMouseButton)
			{
				caughtControl->dispatchEvent(event);
				caughtControl = NULL;			
				break;
			}
			
			menuInvokeChannel = -1;

			if (!hasDragged && !(::getKeyModifier() & selectionKeyModifier) && ppreCursor)
			{
				if (properties.clickToCursor)
				{
					patternEditor->setCursor(*ppreCursor);
			
					notifyUpdate(AdvanceCodeSelectNewRow);
					
					switch (properties.scrollMode)
					{
						case ScrollModeToCenter:
						case ScrollModeStayInCenter:
							assureCursorVisible();
							break;
						case ScrollModeToEnd:
							break;
					}
				}
				
				patternEditor->resetSelection();
			}
			
			parentScreen->paintControl(this);

			startSelection = false;
			ppreCursor = NULL;

			break;

		case eLMouseDrag:
		{
			if (caughtControl && controlCaughtByLMouseButton)
			{
				caughtControl->dispatchEvent(event);
				break;
			}			
			
			if (!startSelection)
				break;
			
			hasDragged = true;

			goto markSelection;
			//break;
		}

		case eRMouseDrag:
		{
			if (caughtControl && controlCaughtByRMouseButton)
				caughtControl->dispatchEvent(event);

			break;
		}
		
		case eRMouseRepeat:
		{
			if (caughtControl && controlCaughtByRMouseButton)
				caughtControl->dispatchEvent(event);

			break;
		}

		case eLMouseRepeat:
		{
			if (caughtControl && controlCaughtByLMouseButton)
			{
				caughtControl->dispatchEvent(event);
				break;
			}		

			// for slowing down mouse pressed events
			selectionTicker++;

			if (selectionTicker&1)
				break;
			
			// no selection has been made or mouse hasn't been dragged
			if (!startSelection || !hasDragged)
			{
				// mouse hasn't been dragged and selection ticker has reached threshold value
				if (!hasDragged && selectionTicker > 0)
				{
					// get point
					PPPoint* p = (PPPoint*)event->getDataPtr();
					
					// make sure scrollbars weren't pressed
					if (!hTopScrollbar->hit(*p) &&
						!hBottomScrollbar->hit(*p) &&
						!vLeftScrollbar->hit(*p) &&
						!vRightScrollbar->hit(*p))
					{
						// translate into local coordinate system
						PPPoint cp = *p;
						
						cp.x-=location.x + SCROLLBARWIDTH + getRowCountWidth() + 4;
						cp.y-=location.y + SCROLLBARWIDTH + font->getCharHeight() + 4;
						
						// not in our local CS
						if (cp.x < 0 || cp.y < 0)
							break;
						
						// valid channel?
						pp_int32 i = (cp.x / slotSize) + startPos;
						if (i < 0 || i > patternEditor->getNumChannels()-1)
							break;

						// restore last selection
						// will be made when mouse left mouse button is pressed
						if (patternEditor->getSelection().isCopyValid())
						{
							patternEditor->getSelection().restore();
						}
						
						// No more cursor positioning
						ppreCursor = NULL;
						
						invokeMenu(i, *p);
						// we're finished with event handling here
						goto leave;
					}
				}
				break;
			}

markSelection:
			PPPoint cp = *((PPPoint*)event->getDataPtr());

			PPPoint cp2 = cp;

			cp.x-=location.x + SCROLLBARWIDTH + getRowCountWidth() + 4;
			cp.y-=location.y + SCROLLBARWIDTH + font->getCharHeight() + 4;
			
			cp2.x-=location.x;
			cp2.y-=location.y;

			if (cp2.x > size.width - SCROLLBARWIDTH /*- (slotSize>>1)*/)
			{
				if (startPos + (visibleWidth / slotSize) < patternEditor->getNumChannels())
					startPos++;
			}
			else if (cp2.x < SCROLLBARWIDTH + (signed)getRowCountWidth() + 4)
			{
				if (startPos > 0)
					startPos--;
			}
	
			if (cp2.y > size.height - SCROLLBARWIDTH /*- ((signed)font->getCharHeight()*3)*/)
			{
				if (properties.scrollMode != ScrollModeStayInCenter)
				{
					if (startIndex + (visibleHeight / font->getCharHeight()) < pattern->rows)
						startIndex++;
				}
				else
				{
					scrollCursorDown();
					assureCursorVisible(true, false);
				}
			}
			else if (cp2.y < SCROLLBARWIDTH + ((signed)font->getCharHeight()*4 /*+ 4*/))
			{
				if (properties.scrollMode != ScrollModeStayInCenter)
				{
					if (startIndex > 0)
						startIndex--;
				}
				else
				{
					scrollCursorUp();
					assureCursorVisible(true, false);
				}
			}

			if (cp.x < 0)
			{
				cp.x = 0;
				//goto leave;
			}

			if (cp.y < 0)
			{
				cp.y = 0;
				//goto leave;
			}

			pp_int32 newStartIndex = cp.y / font->getCharHeight();
			
			pp_int32 newStartPos = cp.x / slotSize;
			
			pp_int32 visibleRows = (visibleHeight) / font->getCharHeight();
			pp_int32 visibleChannels = (visibleWidth) / slotSize;
			
			//if (newStartIndex < visibleRows && 
			//	newStartPos < visibleChannels)
			//{
				mp_sint32 cursorPositionRow = newStartIndex + startIndex;				
				mp_sint32 cursorPositionChannel = newStartPos + startPos;

				if (cursorPositionRow < 0) cursorPositionRow = 0;
				if (cursorPositionChannel < 0) cursorPositionChannel = 0;

				//if (cursorPositionRow < 0 || cursorPositionChannel < 0) 
				//	break;

				if (cursorPositionChannel >= patternEditor->getNumChannels())
				{
					patternEditor->getSelection().end.channel = patternEditor->getNumChannels()-1;
					patternEditor->getSelection().end.inner = 7;
				}
				else
				{
					
					// start selecting row
					patternEditor->getSelection().end.channel = cursorPositionChannel;
					patternEditor->getSelection().end.row = cursorPositionRow;			
					
					pp_int32 innerPos = cp.x % slotSize;
					
					//selectionEnd.inner = 7;
					for (pp_uint32 i = 0; i < sizeof(cursorPositions) - 1; i++)
					{
						if (innerPos >= cursorPositions[i] &&
							innerPos < cursorPositions[i+1])
						{
							patternEditor->getSelection().end.inner = i;
							break;
						}
					}
				}
				
				setScrollbarPositions(startIndex, startPos);
				
			//}
			
			parentScreen->paintControl(this);

			break;
		}

		case eKeyDown:
		{	
			//assureCursorVisible();
			
			pp_uint16 keyCode = *((pp_uint16*)event->getDataPtr());
			pp_uint16 scanCode = *(((pp_uint16*)event->getDataPtr())+1);
			pp_uint16 character = *(((pp_uint16*)event->getDataPtr())+2);

			assureCursor = true;
			assureUpdate = false;

			bool keyboadStartSelectionFlipped = false;
			// start selection
			if (keyCode == VK_LEFT ||
				keyCode == VK_RIGHT ||
				keyCode == VK_UP ||
				keyCode == VK_DOWN ||
				keyCode == VK_PRIOR ||
				keyCode == VK_NEXT ||
				keyCode == VK_HOME ||
				keyCode == VK_END ||
				keyCode == VK_TAB)
			{
				if ((::getKeyModifier() == (unsigned)selectionKeyModifier) && keyboardStartSelection)
				{
					patternEditor->getSelection().start = patternEditor->getSelection().end = patternEditor->getCursor();
					keyboardStartSelection = false;
					if (keyCode == VK_LEFT ||
						keyCode == VK_RIGHT ||
						keyCode == VK_UP ||
						keyCode == VK_DOWN)
					{
						keyboadStartSelectionFlipped = true;
					}
				}
			}

			switch (keyCode)
			{
				// store key modifiers
				case VK_ALT:
					assureCursor = false;
					if (selectionKeyModifier & KeyModifierALT)
						keyboardStartSelection = true;
					break;
				case VK_SHIFT:
					assureCursor = false;
					if (selectionKeyModifier & KeyModifierSHIFT)
						keyboardStartSelection = true;
					break;
				case VK_CONTROL:
					assureCursor = false;
					if (selectionKeyModifier & KeyModifierCTRL)
						keyboardStartSelection = true;
					break;
			
				default:
				{
					bool res = executeBinding(scanCodeBindings, scanCode);

					if (!res)
						res = executeBinding(eventKeyDownBindings, keyCode);
					
					if (!res)
						handleKeyDown(keyCode, scanCode, character);
					
					break;
				}
			}
			
			// normal selection
			if (keyCode == VK_LEFT ||
				keyCode == VK_RIGHT ||
				keyCode == VK_UP ||
				keyCode == VK_DOWN ||
				keyCode == VK_PRIOR ||
				keyCode == VK_NEXT ||
				keyCode == VK_HOME ||
				keyCode == VK_END ||
				keyCode == VK_TAB)
			{
				if ((::getKeyModifier() == (unsigned)selectionKeyModifier) && 
					!keyboardStartSelection && 
					!keyboadStartSelectionFlipped)
				{
					patternEditor->getSelection().end = patternEditor->getCursor();
				}
				else if (::getKeyModifier() == (KeyModifierALT|KeyModifierSHIFT) &&
						 patternEditor->getSelection().start.isValid())
				{
					patternEditor->getSelection().end = patternEditor->getCursor();
				}
			}						
												
			if (assureCursor)
			{
				assureCursorVisible();
				parentScreen->paintControl(this);
			}
			else if (assureUpdate)
			{
				parentScreen->paintControl(this);
			}

			break;
		}

		case eKeyChar:
		{
			assureUpdate = false;

			pp_uint8 character = *((pp_uint8*)event->getDataPtr());

			handleKeyChar(character);

			if (assureUpdate)
				parentScreen->paintControl(this);

			break;
		}

		case eKeyUp:
		{	
			pp_uint16 keyCode = *((pp_uint16*)event->getDataPtr());

			switch (keyCode)
			{
				case VK_SHIFT:
					if (selectionKeyModifier & KeyModifierSHIFT)
						keyboardStartSelection = false;					
					break;
				case VK_ALT:
					if (selectionKeyModifier & KeyModifierALT)
						keyboardStartSelection = false;					
					break;
				case VK_CONTROL:
					if (selectionKeyModifier & KeyModifierCTRL)
						keyboardStartSelection = false;					
					break;
			}
			break;
		}

		default:
			if (caughtControl == NULL)
				break;

			caughtControl->dispatchEvent(event);
			goto leave;
		
	}

leave:
	return 0;
}