Esempio n. 1
0
LRESULT CALLBACK WindowBase::WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	WindowBase* pWindow = (WindowBase*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (pWindow)
	{
		bool bHandled = false;
		switch (message)
		{
		case WM_MOUSEMOVE:
			bHandled = pWindow->HandleMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
			break;
		case WM_LBUTTONDOWN:
			captureMouse(hWnd, pWindow->m_mouseCaptureCount);
			::SetFocus(hWnd);
			bHandled = pWindow->HandleMouseDown(0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
			break;
		case WM_LBUTTONUP:
			bHandled = pWindow->HandleMouseUp(0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
			releaseMouse(pWindow->m_mouseCaptureCount);
			break;
		case WM_RBUTTONDOWN:
			captureMouse(hWnd, pWindow->m_mouseCaptureCount);
			::SetFocus(hWnd);
			bHandled = pWindow->HandleMouseDown(1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
			break;
		case WM_RBUTTONUP:
			bHandled = pWindow->HandleMouseUp(1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
			releaseMouse(pWindow->m_mouseCaptureCount);
			break;
		case WM_KEYDOWN:
			bHandled = pWindow->HandleKeyDown((int)wParam);
			break;
		case WM_KEYUP:
			bHandled = pWindow->HandleKeyUp((int)wParam);
			break;
		case WM_SIZE:
			pWindow->m_width = LOWORD(lParam);
			pWindow->m_height = HIWORD(lParam);
			bHandled = pWindow->HandleResize(pWindow->m_width, pWindow->m_height);
			break;
		case WM_COMMAND:
			if (pWindow->m_pMenu)
			{
				bHandled = pWindow->m_pMenu->HandleMenuCommand((int)wParam);
			}
			break;
		case WM_CLOSE:
			bHandled = pWindow->HandleClose();
			break;
		}

		if (bHandled)
			return 0;
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}
// Capture a control point or the background (if index == -1)
void GLUICurveEditor::captureControlPoint( int index, int x, int y ) {
	if( hasCapture() ) return;
	pointHeldIdx = index;
	holdPosX = x;
	holdPosY = y;
	captureMouse();
}
Esempio n. 3
0
// **********************************************
bool CToolPick::validate()
{
	//H_AUTO(R2_CToolPick_validate)
	if (!_CandidateInstance)
	{
		if (_ValidPos)
		{
			captureMouse();
			pick(_Intersection);
			return true;
		}
		return false; // ... else, do not handle, this allow to control the camera
	}
	if (!_WantMouseUp) captureMouse();
	pick(*_CandidateInstance);
	return true;
}
Esempio n. 4
0
bool LinkLabel::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kSetCursorMessage:
      // TODO theme stuff
      if (isEnabled() && hasMouseOver()) {
        set_mouse_cursor(kHandCursor);
        return true;
      }
      break;

    case kMouseEnterMessage:
    case kMouseLeaveMessage:
      if (isEnabled()) {
        if (hasCapture())
          setSelected(msg->type() == kMouseEnterMessage);

        invalidate();           // TODO theme specific
      }
      break;

    case kMouseMoveMessage:
      if (isEnabled() && hasCapture())
        setSelected(hasMouseOver());
      break;

    case kMouseDownMessage:
      if (isEnabled()) {
        captureMouse();
        setSelected(true);
      }
      break;

    case kMouseUpMessage:
      if (hasCapture()) {
        releaseMouse();

        setSelected(false);
        invalidate();           // TODO theme specific

        if (hasMouseOver())
          onClick();
      }
      break;
  }

  return CustomLabel::onProcessMessage(msg);
}
Esempio n. 5
0
void Editor::editor_click_start(int mode, int *x, int *y, int *b)
{
  click_mode = mode;
  click_first = true;

  click_start_x = click_last_x = jmouse_x(0);
  click_start_y = click_last_y = jmouse_y(0);
  click_start_b = click_last_b = jmouse_b(0) ? jmouse_b(0): 1;

  click_prev_last_b = click_last_b;

  screenToEditor(click_start_x, click_start_y, x, y);
  *b = click_start_b;

  captureMouse();
}
Esempio n. 6
0
///////////////////
// Mouse down event
int CDialog::MouseDown(mouse_t *tMouse)
{
    // Drag the dialog
    if( bGrabbed ) {
        pcParent->moveWidgets(tMouse->X-GrabX, GrabY-tMouse->Y);
        GrabX = tMouse->X;
        GrabY = tMouse->Y;
    } else {
        bGrabbed = true;
        GrabX = tMouse->X;
        GrabY = tMouse->Y;
    }

    captureMouse();

    return -1;
}
Esempio n. 7
0
bool BaseApp::onMouseButton(const int x, const int y, const MouseButton button, const bool pressed) {
    if (!mouseCaptured) {
        if (widgets.goToFirst()) {
            do {
                Widget *widget = widgets.getCurrent();
                if (widget->isEnabled() && widget->isVisible() && (widget->isInWidget(x, y) || widget->isCapturing())) {
                    widgets.moveCurrentToTop();
                    return widget->onMouseButton(x, y, button, pressed);
                }
            } while (widgets.goToNext());
        }

        if (button == MOUSE_LEFT && pressed) {
            captureMouse(true);
            return true;
        }
    }
    return false;
}
Esempio n. 8
0
ColorPickerWidget::ColorPickerWidget(QWidget *parent):
    QFrame(parent)
{
    QFontMetrics fm (mLineEdit.font());
    mLineEdit.setFixedWidth ( 10*fm.width ("a") );

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setContentsMargins (0, 0, 0, 0);
    layout->setSpacing (1);
    setLayout(layout);
    layout->addWidget (&mButton);
    layout->addWidget (&mLineEdit);


    mButton.setAutoRaise(true);
    mButton.setIcon(XdgIcon::fromTheme("color-picker", "kcolorchooser"));

    mCapturing = false;
    connect(&mButton, SIGNAL(clicked()), this, SLOT(captureMouse()));

}
Esempio n. 9
0
bool BaseApp::onJoystickButton(const int button, const bool pressed){
	if (button >= 32) return false;

	bool processed = false;

	if (widgets.goToFirst()){
		do {
			Widget *widget = widgets.getCurrent();
			if (widget->isVisible() || widget->isCapturing()){
				widgets.moveCurrentToTop();
				processed = widget->onJoystickButton(button, pressed);
				break;
			}
		} while (widgets.goToNext());
	}

	if (!processed){
		if (pressed){
			processed = true;
			if (button == optionsButton){
				if (configDialog->isVisible()){
					configDialog->setVisible(false);
					if (keysDialog) keysDialog->setVisible(false);
					if (joystickDialog) joystickDialog->setVisible(false);
				} else {
					captureMouse(false);
					configDialog->setVisible(true);
					if (keysDialog) keysDialog->setVisible(true);
					if (joystickDialog) joystickDialog->setVisible(true);
				}
			} else {
				processed = false;
			}
		}
	}

	joystickButtons[button] = pressed;

	return processed;
}
Esempio n. 10
0
/* Mouse capability-change handler: */
void UIMouseHandler::sltMouseCapabilityChanged()
{
    /* If mouse supports absolute pointing and mouse-integration activated: */
    if (uisession()->isMouseSupportsAbsolute() && uisession()->isMouseIntegrated())
    {
        /* Release the mouse: */
        releaseMouse();
        /* Also we should switch guest mouse to the absolute mode: */
        CMouse mouse = session().GetConsole().GetMouse();
        mouse.PutMouseEventAbsolute(-1, -1, 0, 0, 0);
    }
#if 0 /* current team's decision is NOT to capture mouse on mouse-absolute mode loosing! */
    /* If mouse-integration deactivated or mouse doesn't supports absolute pointing: */
    else
    {
        /* Search for the machine-view focused now: */
        int iFocusedView = -1;
        QList<ulong> screenIds = m_views.keys();
        for (int i = 0; i < screenIds.size(); ++i)
        {
            if (m_views[screenIds[i]]->hasFocus())
            {
                iFocusedView = screenIds[i];
                break;
            }
        }
        /* If there is no focused view but views are present we will use the first one: */
        if (iFocusedView == -1 && !screenIds.isEmpty())
            iFocusedView = screenIds[0];
        /* Capture mouse using that view: */
        if (iFocusedView != -1)
            captureMouse(iFocusedView);
    }
#else /* but just to switch the guest mouse into relative mode! */
    /* If mouse-integration deactivated or mouse doesn't supports absolute pointing: */
    else
    {
Esempio n. 11
0
LRESULT CALLBACK Window::wndProc( WindowHandle handle, UINT message, WPARAM wParam, LPARAM lParam )
{
	switch ( message )
	{
	case WM_CLOSE:
	{
		// create close message and push it to the queue
		InputMessage msg( InputMessage::Type::Close );
		_messages.push( msg );
		break;
	}
	case WM_ACTIVATEAPP:
	{
		if ( wParam && _mouseCaptured )
		{
			captureMouse( );
		}
		break;
	}
	case WM_KEYDOWN:
	case WM_SYSKEYDOWN:
	{
		if ( !_oldKeyStates[wParam] )
		{
			InputMessage msg( InputMessage::Type::KeyDown );
			msg.key.type = ( Key ) wParam;
			msg.key.lCtrl = HIWORD( GetKeyState( VK_RCONTROL ) ) != 0;
			msg.key.rCtrl = HIWORD( GetKeyState( VK_RCONTROL ) ) != 0;
			msg.key.lAlt = HIWORD( GetKeyState( VK_LMENU ) ) != 0;
			msg.key.rAlt = HIWORD( GetKeyState( VK_RMENU ) ) != 0;
			msg.key.lShift = HIWORD( GetKeyState( VK_LSHIFT ) ) != 0;
			msg.key.rShift = HIWORD( GetKeyState( VK_RSHIFT ) ) != 0;
			_messages.push( msg );
			_oldKeyStates[wParam] = true;
		}
		break;
	}
	case WM_KEYUP:
	case WM_SYSKEYUP:
	{
		InputMessage msg( InputMessage::Type::KeyUp );
		msg.key.type = ( Key ) wParam;
		msg.key.lCtrl = HIWORD( GetKeyState( VK_RCONTROL ) ) != 0;
		msg.key.rCtrl = HIWORD( GetKeyState( VK_RCONTROL ) ) != 0;
		msg.key.lAlt = HIWORD( GetKeyState( VK_LMENU ) ) != 0;
		msg.key.rAlt = HIWORD( GetKeyState( VK_RMENU ) ) != 0;
		msg.key.lShift = HIWORD( GetKeyState( VK_LSHIFT ) ) != 0;
		msg.key.rShift = HIWORD( GetKeyState( VK_RSHIFT ) ) != 0;
		_messages.push( msg );
		_oldKeyStates[wParam] = false;
		break;
	}
	case WM_CHAR:
	{
		InputMessage msg( InputMessage::Type::Text );
		msg.text.unicode = wParam;
		_messages.push( msg );
		break;
	}
	case WM_MOUSEMOVE:
	{
		InputMessage msg( InputMessage::Type::MouseMove );
		msg.mouseMove.x = LOWORD( lParam );
		msg.mouseMove.y = HIWORD( lParam );
		msg.mouseMove.ctrl = ( wParam & MK_CONTROL ) != 0;
		msg.mouseMove.lButton = ( wParam & MK_LBUTTON ) != 0;
		msg.mouseMove.mButton = ( wParam & MK_MBUTTON ) != 0;
		msg.mouseMove.rButton = ( wParam & MK_RBUTTON ) != 0;
		msg.mouseMove.shift = ( wParam & MK_SHIFT ) != 0;
		msg.mouseMove.xButton1 = ( wParam & MK_XBUTTON1 ) != 0;
		msg.mouseMove.xButton2 = ( wParam & MK_XBUTTON2 ) != 0;
		_messages.push( msg );
		break;
	}
	case WM_LBUTTONDOWN:
	{
		InputMessage msg( InputMessage::Type::MouseButtonDown );
		msg.mouseButton.type = MouseButton::LeftButton;
		msg.mouseButton.ctrl = ( wParam & MK_CONTROL ) != 0;
		msg.mouseButton.lButton = ( wParam & MK_LBUTTON ) != 0;
		msg.mouseButton.mButton = ( wParam & MK_MBUTTON ) != 0;
		msg.mouseButton.rButton = ( wParam & MK_RBUTTON ) != 0;
		msg.mouseButton.shift = ( wParam & MK_SHIFT ) != 0;
		msg.mouseButton.xButton1 = ( wParam & MK_XBUTTON1 ) != 0;
		msg.mouseButton.xButton2 = ( wParam & MK_XBUTTON2 ) != 0;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		captureMouse( );
		break;
	}
	case WM_LBUTTONUP:
	{
		InputMessage msg( InputMessage::Type::MouseButtonUp );
		msg.mouseButton.type = MouseButton::LeftButton;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		releaseMouse( );
		break;
	}
	case WM_RBUTTONDOWN:
	{
		InputMessage msg( InputMessage::Type::MouseButtonDown );
		msg.mouseButton.type = MouseButton::RightButton;
		msg.mouseButton.ctrl = ( wParam & MK_CONTROL ) != 0;
		msg.mouseButton.lButton = ( wParam & MK_LBUTTON ) != 0;
		msg.mouseButton.mButton = ( wParam & MK_MBUTTON ) != 0;
		msg.mouseButton.rButton = ( wParam & MK_RBUTTON ) != 0;
		msg.mouseButton.shift = ( wParam & MK_SHIFT ) != 0;
		msg.mouseButton.xButton1 = ( wParam & MK_XBUTTON1 ) != 0;
		msg.mouseButton.xButton2 = ( wParam & MK_XBUTTON2 ) != 0;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		captureMouse( );
		break;
	}
	case WM_RBUTTONUP:
	{
		InputMessage msg( InputMessage::Type::MouseButtonUp );
		msg.mouseButton.type = MouseButton::RightButton;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		releaseMouse( );
		break;
	}
	case WM_MBUTTONDOWN:
	{
		InputMessage msg( InputMessage::Type::MouseButtonDown );
		msg.mouseButton.type = MouseButton::MiddleButton;
		msg.mouseButton.ctrl = ( wParam & MK_CONTROL ) != 0;
		msg.mouseButton.lButton = ( wParam & MK_LBUTTON ) != 0;
		msg.mouseButton.mButton = ( wParam & MK_MBUTTON ) != 0;
		msg.mouseButton.rButton = ( wParam & MK_RBUTTON ) != 0;
		msg.mouseButton.shift = ( wParam & MK_SHIFT ) != 0;
		msg.mouseButton.xButton1 = ( wParam & MK_XBUTTON1 ) != 0;
		msg.mouseButton.xButton2 = ( wParam & MK_XBUTTON2 ) != 0;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		captureMouse( );
		break;
	}
	case WM_MBUTTONUP:
	{
		InputMessage msg( InputMessage::Type::MouseButtonUp );
		msg.mouseButton.type = MouseButton::MiddleButton;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		releaseMouse( );
		break;
	}
	case WM_MOUSEWHEEL:
	{
		POINT screenPos;
		screenPos.x = static_cast< LONG >( LOWORD( lParam ) );
		screenPos.y = static_cast< LONG >( HIWORD( lParam ) );
		ScreenToClient( handle, &screenPos );
		InputMessage msg( InputMessage::Type::MouseWheel );
		msg.mouseWheel.ctrl = ( wParam & MK_CONTROL ) != 0;
		msg.mouseWheel.lButton = ( wParam & MK_LBUTTON ) != 0;
		msg.mouseWheel.mButton = ( wParam & MK_MBUTTON ) != 0;
		msg.mouseWheel.rButton = ( wParam & MK_RBUTTON ) != 0;
		msg.mouseWheel.shift = ( wParam & MK_SHIFT ) != 0;
		msg.mouseWheel.xButton1 = ( wParam & MK_XBUTTON1 ) != 0;
		msg.mouseWheel.xButton2 = ( wParam & MK_XBUTTON2 ) != 0;
		msg.mouseWheel.x = static_cast< uint16_t >( screenPos.x );
		msg.mouseWheel.y = static_cast< uint16_t >( screenPos.y );
		msg.mouseWheel.delta = HIWORD( wParam ) / 120;
		_messages.push( msg );
		break;
	}
	case WM_XBUTTONDOWN:
	{
		InputMessage msg( InputMessage::Type::MouseButtonDown );
		msg.mouseButton.type = HIWORD( wParam ) == XBUTTON1 ? MouseButton::XButton1 : MouseButton::XButton2;
		msg.mouseButton.ctrl = ( wParam & MK_CONTROL ) != 0;
		msg.mouseButton.lButton = ( wParam & MK_LBUTTON ) != 0;
		msg.mouseButton.mButton = ( wParam & MK_MBUTTON ) != 0;
		msg.mouseButton.rButton = ( wParam & MK_RBUTTON ) != 0;
		msg.mouseButton.shift = ( wParam & MK_SHIFT ) != 0;
		msg.mouseButton.xButton1 = ( wParam & MK_XBUTTON1 ) != 0;
		msg.mouseButton.xButton2 = ( wParam & MK_XBUTTON2 ) != 0;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		break;
	}
	case WM_XBUTTONUP:
	{
		InputMessage msg( InputMessage::Type::MouseButtonUp );
		msg.mouseButton.type = HIWORD( wParam ) == XBUTTON1 ? MouseButton::XButton1 : MouseButton::XButton2;
		msg.mouseButton.x = LOWORD( lParam );
		msg.mouseButton.y = HIWORD( lParam );
		_messages.push( msg );
		break;
	}
	default:
		// default window procedure
		return DefWindowProc( handle, message, wParam, lParam );
	}
	return 0;
}
Esempio n. 12
0
void BaseApp::onClose(){
	updateConfig();

	captureMouse(false);
}
Esempio n. 13
0
// Window event handler - Use as less as possible
LRESULT CALLBACK WinProc(HWND _hwnd, UINT _id, WPARAM wParam, LPARAM lParam)
{
	WindowsDesc* gCurrentWindow = NULL;
	tinystl::unordered_hash_node<void*, WindowsDesc*>* pNode = gHWNDMap.find(_hwnd).node;
	if (pNode)
		gCurrentWindow = pNode->second;
	else
		return DefWindowProcW(_hwnd, _id, wParam, lParam);

	switch (_id)
	{
	case WM_ACTIVATE:
		if (LOWORD(wParam) == WA_INACTIVE)
		{
			captureMouse(_hwnd, false);
		}
		break;

	case WM_DISPLAYCHANGE:
	{
		if (gCurrentWindow)
		{
			if (gCurrentWindow->fullScreen)
			{
				adjustWindow(gCurrentWindow);
			}
			else
			{
				adjustWindow(gCurrentWindow);
			}
		}
		break;
	}

	case WM_SIZE:
		if (gCurrentWindow)
		{
			RectDesc rect = { 0 };
			if (gCurrentWindow->fullScreen)
			{
				gCurrentWindow->fullscreenRect = { 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) };
				rect = gCurrentWindow->fullscreenRect;
			}
			else
			{
				if (IsIconic(_hwnd))
					return 0;

				RECT windowRect;
				GetClientRect(_hwnd, &windowRect);
				rect = { (int)windowRect.left, (int)windowRect.top, (int)windowRect.right, (int)windowRect.bottom };
				gCurrentWindow->windowedRect = rect;
			}

			WindowResizeEventData eventData = { rect, gCurrentWindow };
			PlatformEvents::onWindowResize(&eventData);
		}
		break;

	case WM_CLOSE:
	case WM_QUIT:
		gAppRunning = false;
		break;

	case WM_CHAR:
	{
		KeyboardCharEventData eventData;
		eventData.unicode = (unsigned)wParam;
		PlatformEvents::onKeyboardChar(&eventData);
		break;
	}
	case WM_MOUSEMOVE:
	{
		static int lastX = 0, lastY = 0;
		int x, y;
		x = GETX(lParam);
		y = GETY(lParam);

		MouseMoveEventData eventData;
		eventData.x = x;
		eventData.y = y;
		eventData.deltaX = x - lastX;
		eventData.deltaY = y - lastY;
		eventData.captured = isCaptured;
		PlatformEvents::onMouseMove(&eventData);

		lastX = x;
		lastY = y;
		break;
	}
	case WM_INPUT:
	{
		UINT dwSize;
		static BYTE lpb[128] = {};

		GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));

		RAWINPUT* raw = (RAWINPUT*)lpb;

		if (raw->header.dwType == RIM_TYPEMOUSE)
		{
			static int lastX = 0, lastY = 0;

			int xPosRelative = raw->data.mouse.lLastX;
			int yPosRelative = raw->data.mouse.lLastY;

			RawMouseMoveEventData eventData;
			eventData.x = xPosRelative;
			eventData.y = yPosRelative;
			eventData.captured = isCaptured;
			PlatformEvents::onRawMouseMove(&eventData);

			lastX = xPosRelative;
			lastY = yPosRelative;
		}

		return 0;
	}
	case WM_LBUTTONDOWN:
	{
		MouseButtonEventData eventData;
		eventData.button = MOUSE_LEFT;
		eventData.pressed = true;
		eventData.x = GETX(lParam);
		eventData.y = GETY(lParam);
		if (PlatformEvents::wantsMouseCapture && !PlatformEvents::skipMouseCapture && !isCaptured)
		{
			captureMouse(_hwnd, true);
		}
		PlatformEvents::onMouseButton(&eventData);
		break;
	}
	case WM_LBUTTONUP:
	{
		MouseButtonEventData eventData;
		eventData.button = MOUSE_LEFT;
		eventData.pressed = false;
		eventData.x = GETX(lParam);
		eventData.y = GETY(lParam);
		PlatformEvents::onMouseButton(&eventData);
		break;
	}
	case WM_RBUTTONDOWN:
	{
		MouseButtonEventData eventData;
		eventData.button = MOUSE_RIGHT;
		eventData.pressed = true;
		eventData.x = GETX(lParam);
		eventData.y = GETY(lParam);
		PlatformEvents::onMouseButton(&eventData);
		break;
	}
	case WM_RBUTTONUP:
	{
		MouseButtonEventData eventData;
		eventData.button = MOUSE_RIGHT;
		eventData.pressed = false;
		eventData.x = GETX(lParam);
		eventData.y = GETY(lParam);
		PlatformEvents::onMouseButton(&eventData);
		break;
	}
	case WM_MBUTTONDOWN:
	{
		MouseButtonEventData eventData;
		eventData.button = MOUSE_MIDDLE;
		eventData.pressed = true;
		eventData.x = GETX(lParam);
		eventData.y = GETY(lParam);
		PlatformEvents::onMouseButton(&eventData);
		break;
	}
	case WM_MBUTTONUP:
	{
		MouseButtonEventData eventData;
		eventData.button = MOUSE_MIDDLE;
		eventData.pressed = false;
		eventData.x = GETX(lParam);
		eventData.y = GETY(lParam);
		PlatformEvents::onMouseButton(&eventData);
		break;
	}
	case WM_MOUSEWHEEL:
	{
		static int scroll;
		int s;

		scroll += GET_WHEEL_DELTA_WPARAM(wParam);
		s = scroll / WHEEL_DELTA;
		scroll %= WHEEL_DELTA;

		POINT point;
		point.x = GETX(lParam);
		point.y = GETY(lParam);
		ScreenToClient(_hwnd, &point);

		if (s != 0)
		{
			MouseWheelEventData eventData;
			eventData.scroll = s;
			eventData.x = point.x;
			eventData.y = point.y;
			PlatformEvents::onMouseWheel(&eventData);
		}
		break;
	}
	case WM_SYSKEYDOWN:
		if ((lParam & (1 << 29)) && (wParam == KEY_ENTER))
		{
			toggleFullscreen(gCurrentWindow);
		}
		updateKeyArray(_id, (unsigned)wParam);
		break;

	case WM_SYSKEYUP:
		updateKeyArray(_id, (unsigned)wParam);
		break;

	case WM_KEYUP:
		if (wParam == KEY_ESCAPE)
		{
			if (!isCaptured)
			{
				gAppRunning = false;
			}
			else
			{
				captureMouse(_hwnd, false);
			}
		}
		updateKeyArray(_id, (unsigned)wParam);
		break;

	case WM_KEYDOWN:
		updateKeyArray(_id, (unsigned)wParam);
		break;
	default:
		return DefWindowProcW(_hwnd, _id, wParam, lParam);
		break;
	}

	return 0;
}
Esempio n. 14
0
bool BaseApp::onKey(const uint key, const bool pressed){
//#if defined(DEBUG) && defined(WIN32)
#ifdef WIN32
	if (pressed && key == KEY_F12){
		if (OpenClipboard(hwnd)){
			EmptyClipboard();

			char str[256];
			int len = sprintf(str, "camPos = vec3(%.15ff, %.15ff, %.15ff);\r\nwx = %.15ff;\r\nwy = %.15ff;\r\n", camPos.x, camPos.y, camPos.z, wx, wy);

			HGLOBAL handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len + 1);
			char *mem = (char *) GlobalLock(handle);
			if (mem != NULL){
				strcpy(mem, str);
				GlobalUnlock(handle);
				SetClipboardData(CF_TEXT, handle);
			}
			CloseClipboard();
		}
	}
#endif

	if (pressed && key == screenshotKey){
		if (!saveScreenshot()){
			ErrorMsg("Couldn't save screenshot");
		}
		return true;
	}

	if (pressed && key == benchmarkKey){
		if (benchMarkFile){
			fclose(benchMarkFile);
			benchMarkFile = NULL;
		} else {
			benchMarkFile = fopen("Benchmark.xls", "w");
			fprintf(benchMarkFile, "Frames/s\n");
		}
		return true;
	}


	bool processed = false;

	if (!mouseCaptured){
		if (widgets.goToFirst()){
			do {
				Widget *widget = widgets.getCurrent();
				if (widget->isVisible() || widget->isCapturing()){
					widgets.moveCurrentToTop();
					processed = widget->onKey(key, pressed);
					break;
				}
			} while (widgets.goToNext());
		}
	}

	if (!processed){
		if (pressed){
			processed = true;
			if (key == KEY_ESCAPE){
				if (!mouseCaptured || (fullscreen && mouseCaptured)){
					closeWindow(true, true);
				} else {
					captureMouse(false);
				}
			} else if (key == fpsKey){
				showFPS = !showFPS;
			} else if (key == resetKey){
				resetCamera();
			} else if (key == optionsKey){
				if (configDialog->isVisible()){
					configDialog->setVisible(false);
					if (keysDialog) keysDialog->setVisible(false);
					if (joystickDialog) joystickDialog->setVisible(false);
				} else {
					captureMouse(false);
					configDialog->setVisible(true);
					if (keysDialog) keysDialog->setVisible(true);
					if (joystickDialog) joystickDialog->setVisible(true);
				}
			} else {
				processed = false;
			}
		}
	}

	if (key < elementsOf(keys)) keys[key] = pressed;

	return processed;
}
Esempio n. 15
0
bool ColorShades::onProcessMessage(ui::Message* msg)
{
  switch (msg->type()) {

    case ui::kOpenMessage:
      if (m_click == DragAndDropEntries) {
        // TODO This connection should be in the ContextBar
        m_conn = ColorBar::instance()->ChangeSelection.connect(
          base::Bind<void>(&ColorShades::onChangeColorBarSelection, this));
      }
      break;

    case ui::kSetCursorMessage:
      if (hasCapture()) {
        ui::set_mouse_cursor(ui::kMoveCursor);
        return true;
      }
      else if (m_click == ClickEntries &&
               m_hotIndex >= 0 &&
               m_hotIndex < int(m_shade.size())) {
        ui::set_mouse_cursor(ui::kHandCursor);
        return true;
      }
      break;

    case ui::kMouseEnterMessage:
    case ui::kMouseLeaveMessage:
      if (!hasCapture())
        m_hotIndex = -1;

      invalidate();
      break;

    case ui::kMouseDownMessage:
      if (m_hotIndex >= 0 &&
          m_hotIndex < int(m_shade.size())) {
        switch (m_click) {
          case ClickEntries:
            Click();
            m_hotIndex = -1;
            invalidate();
            break;
          case DragAndDropEntries:
            m_dragIndex = m_hotIndex;
            m_dropBefore = false;
            captureMouse();
            break;
        }
      }
      break;

    case ui::kMouseUpMessage: {
      if (m_click == ClickWholeShade) {
        setSelected(true);
        Click();
        closeWindow();
      }

      if (m_dragIndex >= 0) {
        ASSERT(m_dragIndex < int(m_shade.size()));

        auto color = m_shade[m_dragIndex];
        m_shade.erase(m_shade.begin()+m_dragIndex);
        if (m_hotIndex >= 0)
          m_shade.insert(m_shade.begin()+m_hotIndex, color);

        m_dragIndex = -1;
        invalidate();

        // Relayout the context bar if we have removed an entry.
        if (m_hotIndex < 0)
          parent()->parent()->layout();
      }

      if (hasCapture())
        releaseMouse();
      break;
    }

    case ui::kMouseMoveMessage: {
      ui::MouseMessage* mouseMsg = static_cast<ui::MouseMessage*>(msg);
      gfx::Point mousePos = mouseMsg->position() - bounds().origin();
      gfx::Rect bounds = clientBounds();
      int hot = -1;

      bounds.shrink(3*ui::guiscale());

      if (bounds.contains(mousePos)) {
        int count = size();
        hot = (mousePos.x - bounds.x) / (m_boxSize*ui::guiscale());
        hot = MID(0, hot, count-1);
      }

      if (m_hotIndex != hot) {
        m_hotIndex = hot;
        invalidate();
      }

      bool dropBefore =
        (hot >= 0 && mousePos.x < (bounds.x+m_boxSize*ui::guiscale()*hot)+m_boxSize*ui::guiscale()/2);
      if (m_dropBefore != dropBefore) {
        m_dropBefore = dropBefore;
        invalidate();
      }
      break;
    }
  }
  return Widget::onProcessMessage(msg);
}
Esempio n. 16
0
bool Slider::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kFocusEnterMessage:
    case kFocusLeaveMessage:
      if (isEnabled())
        invalidate();
      break;

    case kMouseDownMessage:
      if (!isEnabled() || isReadOnly())
        return true;

      setSelected(true);
      captureMouse();

      {
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
        slider_press_x = mousePos.x;
        slider_press_value = m_value;
        slider_press_left = static_cast<MouseMessage*>(msg)->left();
      }

      setupSliderCursor();

      // Fall through

    case kMouseMoveMessage:
      if (hasCapture()) {
        int value, accuracy, range;
        gfx::Rect rc = getChildrenBounds();
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();

        range = m_max - m_min + 1;

        // With left click
        if (slider_press_left) {
          value = m_min + range * (mousePos.x - rc.x) / rc.w;
        }
        // With right click
        else {
          accuracy = MID(1, rc.w / range, rc.w);

          value = slider_press_value +
            (mousePos.x - slider_press_x) / accuracy;
        }

        value = MID(m_min, value, m_max);

        if (m_value != value) {
          setValue(value);
          onChange();
        }

        return true;
      }
      break;

    case kMouseUpMessage:
      if (hasCapture()) {
        setSelected(false);
        releaseMouse();
        setupSliderCursor();

        onSliderReleased();
      }
      break;

    case kMouseEnterMessage:
    case kMouseLeaveMessage:
      // TODO theme stuff
      if (isEnabled())
        invalidate();
      break;

    case kKeyDownMessage:
      if (hasFocus() && !isReadOnly()) {
        int min = m_min;
        int max = m_max;
        int value = m_value;

        switch (static_cast<KeyMessage*>(msg)->scancode()) {
          case kKeyLeft:     value = MAX(value-1, min); break;
          case kKeyRight:    value = MIN(value+1, max); break;
          case kKeyPageDown: value = MAX(value-(max-min+1)/4, min); break;
          case kKeyPageUp:   value = MIN(value+(max-min+1)/4, max); break;
          case kKeyHome:     value = min; break;
          case kKeyEnd:      value = max; break;
          default:
            goto not_used;
        }

        if (m_value != value) {
          setValue(value);
          onChange();
        }

        return true;
      }
      break;

    case kMouseWheelMessage:
      if (isEnabled() && !isReadOnly()) {
        int value = m_value
          + static_cast<MouseMessage*>(msg)->wheelDelta().x
          - static_cast<MouseMessage*>(msg)->wheelDelta().y;

        value = MID(m_min, value, m_max);

        if (m_value != value) {
          this->setValue(value);
          onChange();
        }
        return true;
      }
      break;

    case kSetCursorMessage:
      setupSliderCursor();
      return true;
  }

not_used:;
  return Widget::onProcessMessage(msg);
}
Esempio n. 17
0
bool Entry::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kTimerMessage:
      if (hasFocus() && static_cast<TimerMessage*>(msg)->timer() == &m_timer) {
        // Blinking caret
        m_state = m_state ? false: true;
        invalidate();
      }
      break;

    case kFocusEnterMessage:
      m_timer.start();

      m_state = true;
      invalidate();

      if (m_lock_selection) {
        m_lock_selection = false;
      }
      else {
        selectAllText();
        m_recent_focused = true;
      }
      break;

    case kFocusLeaveMessage:
      invalidate();

      m_timer.stop();

      if (!m_lock_selection)
        deselectText();

      m_recent_focused = false;
      break;

    case kKeyDownMessage:
      if (hasFocus() && !isReadOnly()) {
        // Command to execute
        EntryCmd cmd = EntryCmd::NoOp;
        KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
        KeyScancode scancode = keymsg->scancode();

        switch (scancode) {

          case kKeyLeft:
            if (msg->ctrlPressed())
              cmd = EntryCmd::BackwardWord;
            else
              cmd = EntryCmd::BackwardChar;
            break;

          case kKeyRight:
            if (msg->ctrlPressed())
              cmd = EntryCmd::ForwardWord;
            else
              cmd = EntryCmd::ForwardChar;
            break;

          case kKeyHome:
            cmd = EntryCmd::BeginningOfLine;
            break;

          case kKeyEnd:
            cmd = EntryCmd::EndOfLine;
            break;

          case kKeyDel:
            if (msg->shiftPressed())
              cmd = EntryCmd::Cut;
            else
              cmd = EntryCmd::DeleteForward;
            break;

          case kKeyInsert:
            if (msg->shiftPressed())
              cmd = EntryCmd::Paste;
            else if (msg->ctrlPressed())
              cmd = EntryCmd::Copy;
            break;

          case kKeyBackspace:
            cmd = EntryCmd::DeleteBackward;
            break;

          default:
            // Map common Windows shortcuts for Cut/Copy/Paste
#if defined __APPLE__
            if (msg->onlyCmdPressed())
#else
            if (msg->onlyCtrlPressed())
#endif
            {
              switch (scancode) {
                case kKeyX: cmd = EntryCmd::Cut; break;
                case kKeyC: cmd = EntryCmd::Copy; break;
                case kKeyV: cmd = EntryCmd::Paste; break;
              }
            }
            else if (keymsg->unicodeChar() >= 32) {
              // Ctrl and Alt must be unpressed to insert a character
              // in the text-field.
              if ((msg->keyModifiers() & (kKeyCtrlModifier | kKeyAltModifier)) == 0) {
                cmd = EntryCmd::InsertChar;
              }
            }
            break;
        }

        if (cmd == EntryCmd::NoOp)
          break;

        executeCmd(cmd, keymsg->unicodeChar(),
                   (msg->shiftPressed()) ? true: false);
        return true;
      }
      break;

    case kMouseDownMessage:
      captureMouse();

    case kMouseMoveMessage:
      if (hasCapture()) {
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
        base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin());
        base::utf8_const_iterator utf8_end = base::utf8_const_iterator(getText().end());
        int textlen = base::utf8_length(getText());
        int c, x;

        bool move = true;
        bool is_dirty = false;

        // Backward scroll
        if (mousePos.x < getBounds().x) {
          if (m_scroll > 0) {
            m_caret = --m_scroll;
            move = false;
            is_dirty = true;
            invalidate();
          }
        }
        // Forward scroll
        else if (mousePos.x >= getBounds().x2()) {
          if (m_scroll < textlen - getAvailableTextLength()) {
            m_scroll++;
            x = getBounds().x + this->border_width.l;
            for (c=m_scroll; utf8_begin != utf8_end; ++c) {
              int ch = (c < textlen ? *(utf8_begin+c) : ' ');

              x += getFont()->charWidth(ch);
              if (x > getBounds().x2()-this->border_width.r) {
                c--;
                break;
              }
            }
            m_caret = c;
            move = false;
            is_dirty = true;
            invalidate();
          }
        }

        c = getCaretFromMouse(static_cast<MouseMessage*>(msg));

        if (static_cast<MouseMessage*>(msg)->left() ||
            (move && !isPosInSelection(c))) {
          // Move caret
          if (move) {
            if (m_caret != c) {
              m_caret = c;
              is_dirty = true;
              invalidate();
            }
          }

          // Move selection
          if (m_recent_focused) {
            m_recent_focused = false;
            m_select = m_caret;
          }
          else if (msg->type() == kMouseDownMessage)
            m_select = m_caret;
        }

        // Show the caret
        if (is_dirty) {
          m_timer.start();
          m_state = true;
        }

        return true;
      }
      break;

    case kMouseUpMessage:
      if (hasCapture()) {
        releaseMouse();

        MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
        if (mouseMsg->right()) {
          // This flag is disabled in kFocusEnterMessage message handler.
          m_lock_selection = true;

          showEditPopupMenu(mouseMsg->position());
          requestFocus();
        }
      }
      return true;

    case kDoubleClickMessage:
      forwardWord();
      m_select = m_caret;
      backwardWord();
      invalidate();
      return true;

    case kMouseEnterMessage:
    case kMouseLeaveMessage:
      // TODO theme stuff
      if (isEnabled())
        invalidate();
      break;
  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 18
0
bool Window::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kOpenMessage:
      m_killer = NULL;
      break;

    case kCloseMessage:
      saveLayout();
      break;

    case kMouseDownMessage: {
      if (!m_isMoveable)
        break;

      clickedMousePos = static_cast<MouseMessage*>(msg)->position();
      m_hitTest = hitTest(clickedMousePos);

      if (m_hitTest != HitTestNowhere &&
          m_hitTest != HitTestClient) {
        if (clickedWindowPos == NULL)
          clickedWindowPos = new gfx::Rect(getBounds());
        else
          *clickedWindowPos = getBounds();

        captureMouse();
        return true;
      }
      else
        break;
    }

    case kMouseUpMessage:
      if (hasCapture()) {
        releaseMouse();
        jmouse_set_cursor(kArrowCursor);

        if (clickedWindowPos != NULL) {
          delete clickedWindowPos;
          clickedWindowPos = NULL;
        }

        m_hitTest = HitTestNowhere;
        return true;
      }
      break;

    case kMouseMoveMessage:
      if (!m_isMoveable)
        break;

      // Does it have the mouse captured?
      if (hasCapture()) {
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();

        // Reposition/resize
        if (m_hitTest == HitTestCaption) {
          int x = clickedWindowPos->x + (mousePos.x - clickedMousePos.x);
          int y = clickedWindowPos->y + (mousePos.y - clickedMousePos.y);
          moveWindow(gfx::Rect(x, y,
                               getBounds().w,
                               getBounds().h), true);
        }
        else {
          int x, y, w, h;

          w = clickedWindowPos->w;
          h = clickedWindowPos->h;

          bool hitLeft = (m_hitTest == HitTestBorderNW ||
                          m_hitTest == HitTestBorderW ||
                          m_hitTest == HitTestBorderSW);
          bool hitTop = (m_hitTest == HitTestBorderNW ||
                         m_hitTest == HitTestBorderN ||
                         m_hitTest == HitTestBorderNE);
          bool hitRight = (m_hitTest == HitTestBorderNE ||
                           m_hitTest == HitTestBorderE ||
                           m_hitTest == HitTestBorderSE);
          bool hitBottom = (m_hitTest == HitTestBorderSW ||
                            m_hitTest == HitTestBorderS ||
                            m_hitTest == HitTestBorderSE);

          if (hitLeft) {
            w += clickedMousePos.x - mousePos.x;
          }
          else if (hitRight) {
            w += mousePos.x - clickedMousePos.x;
          }

          if (hitTop) {
            h += (clickedMousePos.y - mousePos.y);
          }
          else if (hitBottom) {
            h += (mousePos.y - clickedMousePos.y);
          }

          limitSize(&w, &h);

          if ((getBounds().w != w) ||
              (getBounds().h != h)) {
            if (hitLeft)
              x = clickedWindowPos->x - (w - clickedWindowPos->w);
            else
              x = getBounds().x;

            if (hitTop)
              y = clickedWindowPos->y - (h - clickedWindowPos->h);
            else
              y = getBounds().y;

            moveWindow(gfx::Rect(x, y, w, h), false);
            invalidate();
          }
        }
      }
      break;

    case kSetCursorMessage:
      if (m_isMoveable) {
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
        HitTest ht = hitTest(mousePos);
        CursorType cursor = kArrowCursor;

        switch (ht) {

          case HitTestCaption:
            cursor = kArrowCursor;
            break;

          case HitTestBorderNW:
            cursor = kSizeTLCursor;
            break;

          case HitTestBorderW:
            cursor = kSizeLCursor;
            break;

          case HitTestBorderSW:
            cursor = kSizeBLCursor;
            break;

          case HitTestBorderNE:
            cursor = kSizeTRCursor;
            break;

          case HitTestBorderE:
            cursor = kSizeRCursor;
            break;

          case HitTestBorderSE:
            cursor = kSizeBRCursor;
            break;

          case HitTestBorderN:
            cursor = kSizeTCursor;
            break;

          case HitTestBorderS:
            cursor = kSizeBCursor;
            break;

        }

        jmouse_set_cursor(cursor);
        return true;
      }
      break;

  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 19
0
bool Entry::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kTimerMessage:
      if (hasFocus() && static_cast<TimerMessage*>(msg)->timer() == &m_timer) {
        // Blinking caret
        m_state = m_state ? false: true;
        invalidate();
      }
      break;

    case kFocusEnterMessage:
      if (shouldStartTimer(true))
        m_timer.start();

      m_state = true;
      invalidate();

      if (m_lock_selection) {
        m_lock_selection = false;
      }
      else {
        selectAllText();
        m_recent_focused = true;
      }

      // Start processing dead keys
      if (m_translate_dead_keys)
        os::instance()->setTranslateDeadKeys(true);
      break;

    case kFocusLeaveMessage:
      invalidate();

      m_timer.stop();

      if (!m_lock_selection)
        deselectText();

      m_recent_focused = false;

      // Stop processing dead keys
      if (m_translate_dead_keys)
        os::instance()->setTranslateDeadKeys(false);
      break;

    case kKeyDownMessage:
      if (hasFocus() && !isReadOnly()) {
        // Command to execute
        EntryCmd cmd = EntryCmd::NoOp;
        KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
        KeyScancode scancode = keymsg->scancode();

        switch (scancode) {

          case kKeyLeft:
            if (msg->ctrlPressed() || msg->altPressed())
              cmd = EntryCmd::BackwardWord;
            else if (msg->cmdPressed())
              cmd = EntryCmd::BeginningOfLine;
            else
              cmd = EntryCmd::BackwardChar;
            break;

          case kKeyRight:
            if (msg->ctrlPressed() || msg->altPressed())
              cmd = EntryCmd::ForwardWord;
            else if (msg->cmdPressed())
              cmd = EntryCmd::EndOfLine;
            else
              cmd = EntryCmd::ForwardChar;
            break;

          case kKeyHome:
            cmd = EntryCmd::BeginningOfLine;
            break;

          case kKeyEnd:
            cmd = EntryCmd::EndOfLine;
            break;

          case kKeyDel:
            if (msg->shiftPressed())
              cmd = EntryCmd::Cut;
            else if (msg->ctrlPressed())
              cmd = EntryCmd::DeleteForwardToEndOfLine;
            else
              cmd = EntryCmd::DeleteForward;
            break;

          case kKeyInsert:
            if (msg->shiftPressed())
              cmd = EntryCmd::Paste;
            else if (msg->ctrlPressed())
              cmd = EntryCmd::Copy;
            break;

          case kKeyBackspace:
            if (msg->ctrlPressed())
              cmd = EntryCmd::DeleteBackwardWord;
            else
              cmd = EntryCmd::DeleteBackward;
            break;

          default:
            // Map common macOS/Windows shortcuts for Cut/Copy/Paste/Select all
#if defined __APPLE__
            if (msg->onlyCmdPressed())
#else
            if (msg->onlyCtrlPressed())
#endif
            {
              switch (scancode) {
                case kKeyX: cmd = EntryCmd::Cut; break;
                case kKeyC: cmd = EntryCmd::Copy; break;
                case kKeyV: cmd = EntryCmd::Paste; break;
                case kKeyA: cmd = EntryCmd::SelectAll; break;
              }
            }
            break;
        }

        if (cmd == EntryCmd::NoOp) {
          if (keymsg->unicodeChar() >= 32) {
            executeCmd(EntryCmd::InsertChar, keymsg->unicodeChar(),
                       (msg->shiftPressed()) ? true: false);

            // Select dead-key
            if (keymsg->isDeadKey()) {
              if (lastCaretPos() < m_maxsize)
                selectText(m_caret-1, m_caret);
            }
            return true;
          }
          // Consume all key down of modifiers only, e.g. so the user
          // can press first "Ctrl" key, and then "Ctrl+C"
          // combination.
          else if (keymsg->scancode() >= kKeyFirstModifierScancode) {
            return true;
          }
          else {
            break;              // Propagate to manager
          }
        }

        executeCmd(cmd, keymsg->unicodeChar(),
                   (msg->shiftPressed()) ? true: false);
        return true;
      }
      break;

    case kMouseDownMessage:
      captureMouse();

    case kMouseMoveMessage:
      if (hasCapture()) {
        bool is_dirty = false;
        int c = getCaretFromMouse(static_cast<MouseMessage*>(msg));

        if (static_cast<MouseMessage*>(msg)->left() || !isPosInSelection(c)) {
          // Move caret
          if (m_caret != c) {
            setCaretPos(c);
            is_dirty = true;
            invalidate();
          }

          // Move selection
          if (m_recent_focused) {
            m_recent_focused = false;
            m_select = m_caret;
          }
          else if (msg->type() == kMouseDownMessage)
            m_select = m_caret;
        }

        // Show the caret
        if (is_dirty) {
          if (shouldStartTimer(true))
            m_timer.start();
          m_state = true;
        }

        return true;
      }
      break;

    case kMouseUpMessage:
      if (hasCapture()) {
        releaseMouse();

        MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
        if (mouseMsg->right()) {
          // This flag is disabled in kFocusEnterMessage message handler.
          m_lock_selection = true;

          showEditPopupMenu(mouseMsg->position());
          requestFocus();
        }
      }
      return true;

    case kDoubleClickMessage:
      forwardWord();
      m_select = m_caret;
      backwardWord();
      invalidate();
      return true;

    case kMouseEnterMessage:
    case kMouseLeaveMessage:
      // TODO theme stuff
      if (isEnabled())
        invalidate();
      break;
  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 20
0
bool ButtonBase::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kFocusEnterMessage:
    case kFocusLeaveMessage:
      if (isEnabled()) {
        if (m_behaviorType == kButtonWidget) {
          // Deselect the widget (maybe the user press the key, but
          // before release it, changes the focus).
          if (isSelected())
            setSelected(false);
        }

        // TODO theme specific stuff
        invalidate();
      }
      break;

    case kKeyDownMessage: {
      KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
      KeyScancode scancode = keymsg->scancode();

      // If the button is enabled.
      if (isEnabled()) {
        bool mnemonicPressed =
          ((msg->altPressed() || msg->cmdPressed()) &&
           isMnemonicPressed(keymsg));

        // For kButtonWidget
        if (m_behaviorType == kButtonWidget) {
          // Has focus and press enter/space
          if (hasFocus()) {
            if ((scancode == kKeyEnter) ||
                (scancode == kKeyEnterPad) ||
                (scancode == kKeySpace)) {
              setSelected(true);
              return true;
            }
          }

          // Check if the user pressed mnemonic.
          if (mnemonicPressed) {
            setSelected(true);
            return true;
          }
          // Magnetic widget catches ENTERs
          else if (isFocusMagnet() &&
                   ((scancode == kKeyEnter) ||
                    (scancode == kKeyEnterPad))) {
            manager()->setFocus(this);

            // Dispatch focus movement messages (because the buttons
            // process them)
            manager()->dispatchMessages();

            setSelected(true);
            return true;
          }
        }
        // For kCheckWidget or kRadioWidget
        else {
          /* if the widget has the focus and the user press space or
             if the user press Alt+the underscored letter of the button */
          if ((hasFocus() && (scancode == kKeySpace)) || mnemonicPressed) {
            if (m_behaviorType == kCheckWidget) {
              // Swap the select status
              setSelected(!isSelected());
              invalidate();
            }
            else if (m_behaviorType == kRadioWidget) {
              if (!isSelected()) {
                setSelected(true);
              }
            }
            return true;
          }
        }
      }
      break;
    }

    case kKeyUpMessage:
      if (isEnabled()) {
        if (m_behaviorType == kButtonWidget) {
          if (isSelected()) {
            generateButtonSelectSignal();
            return true;
          }
        }
      }
      break;

    case kMouseDownMessage:
      switch (m_behaviorType) {

        case kButtonWidget:
          if (isEnabled()) {
            setSelected(true);

            m_pressedStatus = isSelected();
            captureMouse();
          }
          return true;

        case kCheckWidget:
          if (isEnabled()) {
            setSelected(!isSelected());

            m_pressedStatus = isSelected();
            captureMouse();
          }
          return true;

        case kRadioWidget:
          if (isEnabled()) {
            if (!isSelected()) {
              m_handleSelect = false;
              setSelected(true);
              m_handleSelect = true;

              m_pressedStatus = isSelected();
              captureMouse();
            }
          }
          return true;
      }
      break;

    case kMouseUpMessage:
      if (hasCapture()) {
        releaseMouse();

        if (hasMouseOver()) {
          switch (m_behaviorType) {

            case kButtonWidget:
              generateButtonSelectSignal();
              break;

            case kCheckWidget:
              {
                // Fire onClick() event
                Event ev(this);
                onClick(ev);

                invalidate();
              }
              break;

            case kRadioWidget:
              {
                setSelected(false);
                setSelected(true);

                // Fire onClick() event
                Event ev(this);
                onClick(ev);
              }
              break;
          }
        }
        return true;
      }
      break;

    case kMouseMoveMessage:
      if (isEnabled() && hasCapture()) {
        bool hasMouse = hasMouseOver();

        m_handleSelect = false;

        // Switch state when the mouse go out
        if ((hasMouse && isSelected() != m_pressedStatus) ||
            (!hasMouse && isSelected() == m_pressedStatus)) {
          if (hasMouse)
            setSelected(m_pressedStatus);
          else
            setSelected(!m_pressedStatus);
        }

        m_handleSelect = true;
      }
      break;

    case kMouseEnterMessage:
    case kMouseLeaveMessage:
      // TODO theme stuff
      if (isEnabled())
        invalidate();
      break;
  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 21
0
void GameView::onGui()
{
	PROFILE_FUNCTION();
	if (!m_pipeline->isReady()) return;

	auto& io = ImGui::GetIO();

	bool is_foreground_win = PlatformInterface::isWindowActive();
	if (m_is_mouse_captured && (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] ||
								   !m_editor->isGameMode() || !is_foreground_win))
	{
		captureMouse(false);
	}

	const char* window_name = "Game View###game_view";
	if (m_is_mouse_captured) window_name = "Game View (mouse captured)###game_view";
	if (ImGui::BeginDock(window_name, &m_is_opened))
	{
		m_is_mouse_hovering_window = ImGui::IsMouseHoveringWindow();

		auto content_min = ImGui::GetCursorScreenPos();
		auto size = ImGui::GetContentRegionAvail();
		size.y -= ImGui::GetTextLineHeightWithSpacing();
		ImVec2 content_max(content_min.x + size.x, content_min.y + size.y);
		if (size.x > 0 && size.y > 0)
		{
			auto pos = ImGui::GetWindowPos();
			auto cp = ImGui::GetCursorPos();
			m_pipeline->setViewport(0, 0, int(size.x), int(size.y));

			auto* fb = m_pipeline->getFramebuffer("default");
			m_texture_handle = fb->getRenderbufferHandle(0);
			ImGui::Image(&m_texture_handle, size);
			if (ImGui::Checkbox("Pause", &m_paused))
			{
				m_editor->getEngine().pause(m_paused);
			}
			if (m_paused)
			{
				ImGui::SameLine();
				if (ImGui::Button("Next frame"))
				{
					m_editor->getEngine().nextFrame();
				}
			}
			ImGui::SameLine();
			if (ImGui::DragFloat("m_time_multiplier", &m_time_multiplier, 0.01f, 0.01f, 30.0f))
			{
				m_editor->getEngine().setTimeMultiplier(m_time_multiplier);
			}
			m_pipeline->render();
		}

		if (m_is_mouse_captured)
		{
			PlatformInterface::clipCursor(
				content_min.x, content_min.y, content_max.x, content_max.y);

			if (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] || !m_editor->isGameMode())
			{
				captureMouse(false);
			}
		}

		if (ImGui::IsMouseHoveringRect(content_min, content_max) && m_is_mouse_hovering_window &&
			ImGui::IsMouseClicked(0) && m_editor->isGameMode())
		{
			captureMouse(true);
		}
	}
	ImGui::EndDock();
}
Esempio n. 22
0
void SceneView::onGUI()
{
	PROFILE_FUNCTION();
	m_is_opened = false;
	ImVec2 view_pos;
	const char* title = "Scene View###Scene View";
	if (m_log_ui && m_log_ui->getUnreadErrorCount() > 0)
	{
		title = "Scene View | errors in log###Scene View";
	}

	if (ImGui::BeginDock(title, nullptr, ImGuiWindowFlags_NoScrollWithMouse))
	{
		m_is_opened = true;
		auto size = ImGui::GetContentRegionAvail();
		size.y -= ImGui::GetTextLineHeightWithSpacing();
		auto* fb = m_pipeline->getFramebuffer("default");
		if (size.x > 0 && size.y > 0 && fb)
		{
			auto pos = ImGui::GetWindowPos();
			m_pipeline->setViewport(0, 0, int(size.x), int(size.y));
			m_texture_handle = fb->getRenderbufferHandle(0);
			auto cursor_pos = ImGui::GetCursorScreenPos();
			m_screen_x = int(cursor_pos.x);
			m_screen_y = int(cursor_pos.y);
			m_width = int(size.x);
			m_height = int(size.y);
			auto content_min = ImGui::GetCursorScreenPos();
			ImVec2 content_max(content_min.x + size.x, content_min.y + size.y);
			if (m_is_opengl)
			{
				ImGui::Image(&m_texture_handle, size, ImVec2(0, 1), ImVec2(1, 0));
			}
			else
			{
				ImGui::Image(&m_texture_handle, size);
			}
			view_pos = content_min;
			auto rel_mp = ImGui::GetMousePos();
			rel_mp.x -= m_screen_x;
			rel_mp.y -= m_screen_y;
			if (ImGui::IsItemHovered())
			{
				m_editor->getGizmo().enableStep(m_toggle_gizmo_step_action->isActive());
				for (int i = 0; i < 3; ++i)
				{
					if (ImGui::IsMouseClicked(i))
					{
						ImGui::ResetActiveID();
						if(i == 1) captureMouse(true);
						m_editor->onMouseDown((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
						break;
					}
				}
			}
			if (m_is_mouse_captured || ImGui::IsItemHovered())
			{
				auto& input = m_editor->getEngine().getInputSystem();
				auto delta = Lumix::Vec2(input.getMouseXMove(), input.getMouseYMove());
				if (delta.x != 0 || delta.y != 0)
				{
					m_editor->onMouseMove((int)rel_mp.x, (int)rel_mp.y, (int)delta.x, (int)delta.y);
				}
			}
			for (int i = 0; i < 3; ++i)
			{
				auto rel_mp = ImGui::GetMousePos();
				rel_mp.x -= m_screen_x;
				rel_mp.y -= m_screen_y;
				if (ImGui::IsMouseReleased(i))
				{
					if (i == 1) captureMouse(false);
					m_editor->onMouseUp((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
				}
			}
			m_pipeline->render();
		}

		ImGui::PushItemWidth(60);
		ImGui::DragFloat("Camera speed", &m_camera_speed, 0.1f, 0.01f, 999.0f, "%.2f");
		ImGui::SameLine();
		if (m_editor->isMeasureToolActive())
		{
			ImGui::Text("| Measured distance: %f", m_editor->getMeasuredDistance());
		}

		ImGui::SameLine();
		int step = m_editor->getGizmo().getStep();
		if (ImGui::DragInt("Gizmo step", &step, 1.0f, 0, 200))
		{
			m_editor->getGizmo().setStep(step);
		}

		ImGui::SameLine();
		ImGui::Checkbox("Stats", &m_show_stats);

		m_pipeline->callLuaFunction("onGUI");
	}

	ImGui::EndDock();

	if(m_show_stats)
	{
		view_pos.x += ImGui::GetStyle().FramePadding.x;
		view_pos.y += ImGui::GetStyle().FramePadding.y;
		ImGui::SetNextWindowPos(view_pos);
		auto col = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
		col.w = 0.3f;
		ImGui::PushStyleColor(ImGuiCol_WindowBg, col);
		if (ImGui::Begin("###stats_overlay",
				nullptr,
				ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize |
					ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings |
					ImGuiWindowFlags_ShowBorders))
		{
			const auto& stats = m_pipeline->getStats();
			ImGui::LabelText("Draw calls", "%d", stats.draw_call_count);
			ImGui::LabelText("Instances", "%d", stats.instance_count);
			char buf[30];
			Lumix::toCStringPretty(stats.triangle_count, buf, Lumix::lengthOf(buf));
			ImGui::LabelText("Triangles", "%s", buf);
			ImGui::LabelText("Resolution", "%dx%d", m_pipeline->getWidth(), m_pipeline->getHeight());
			ImGui::LabelText("FPS", "%.2f", m_editor->getEngine().getFPS());
			ImGui::LabelText("CPU time", "%.2f", m_pipeline->getCPUTime() * 1000.0f);
			ImGui::LabelText("GPU time", "%.2f", m_pipeline->getGPUTime() * 1000.0f);
			ImGui::LabelText("Waiting for submit", "%.2f", m_pipeline->getWaitSubmitTime() * 1000.0f);
			ImGui::LabelText("Waiting for render thread", "%.2f", m_pipeline->getGPUTime() * 1000.0f);
		}
		ImGui::End();
		ImGui::PopStyleColor();
	}
}
Esempio n. 23
0
bool ListBox::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kOpenMessage:
      centerScroll();
      break;

    case kMouseDownMessage:
      captureMouse();

    case kMouseMoveMessage:
      if (hasCapture()) {
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
        int select = getSelectedIndex();
        View* view = View::getView(this);
        bool pick_item = true;

        if (view) {
          gfx::Rect vp = view->getViewportBounds();

          if (mousePos.y < vp.y) {
            int num = MAX(1, (vp.y - mousePos.y) / 8);
            selectIndex(select-num);
            pick_item = false;
          }
          else if (mousePos.y >= vp.y + vp.h) {
            int num = MAX(1, (mousePos.y - (vp.y+vp.h-1)) / 8);
            selectIndex(select+num);
            pick_item = false;
          }
        }

        if (pick_item) {
          Widget* picked;

          if (view) {
            picked = view->getViewport()->pick(mousePos);
          }
          else {
            picked = pick(mousePos);
          }

          /* if the picked widget is a child of the list, select it */
          if (picked && hasChild(picked)) {
            if (ListItem* pickedItem = dynamic_cast<ListItem*>(picked))
              selectChild(pickedItem);
          }
        }

        return true;
      }
      break;

    case kMouseUpMessage:
      releaseMouse();
      break;

    case kMouseWheelMessage: {
      View* view = View::getView(this);
      if (view) {
        gfx::Point scroll = view->getViewScroll();
        scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * getTextHeight()*3;
        view->setViewScroll(scroll);
      }
      break;
    }

    case kKeyDownMessage:
      if (hasFocus() && !getChildren().empty()) {
        int select = getSelectedIndex();
        View* view = View::getView(this);
        int bottom = MAX(0, getChildren().size()-1);
        KeyMessage* keymsg = static_cast<KeyMessage*>(msg);

        switch (keymsg->scancode()) {
          case kKeyUp:
            // Select previous element.
            if (select >= 0)
              select--;
            // Or select the bottom of the list if there is no
            // selected item.
            else
              select = bottom;
            break;
          case kKeyDown:
            select++;
            break;
          case kKeyHome:
            select = 0;
            break;
          case kKeyEnd:
            select = bottom;
            break;
          case kKeyPageUp:
            if (view) {
              gfx::Rect vp = view->getViewportBounds();
              select -= vp.h / getTextHeight();
            }
            else
              select = 0;
            break;
          case kKeyPageDown:
            if (view) {
              gfx::Rect vp = view->getViewportBounds();
              select += vp.h / getTextHeight();
            }
            else
              select = bottom;
            break;
          case kKeyLeft:
          case kKeyRight:
            if (view) {
              gfx::Rect vp = view->getViewportBounds();
              gfx::Point scroll = view->getViewScroll();
              int sgn = (keymsg->scancode() == kKeyLeft) ? -1: 1;

              scroll.x += vp.w/2*sgn;

              view->setViewScroll(scroll);
            }
            break;
          default:
            return Widget::onProcessMessage(msg);
        }

        selectIndex(MID(0, select, bottom));
        return true;
      }
      break;

    case kDoubleClickMessage:
      onDoubleClickItem();
      return true;
  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 24
0
bool OpenGLApp::initAPI(){
	screen = DefaultScreen(display);

	int nModes;
    XF86VidModeGetAllModeLines(display, screen, &nModes, &dmodes);

	Array <DispRes> modes;

	char str[64];
	int foundMode = -1;
	for (int i = 0; i < nModes; i++){
		if (dmodes[i]->hdisplay >= 640 && dmodes[i]->vdisplay >= 480){
			modes.add(newRes(dmodes[i]->hdisplay, dmodes[i]->vdisplay, i));

			if (dmodes[i]->hdisplay == fullscreenWidth && dmodes[i]->vdisplay == fullscreenHeight){
				foundMode = i;
			}
		}
	}

	resolution->clear();
	modes.sort(dComp);
	for (uint i = 0; i < modes.getCount(); i++){
		sprintf(str, "%dx%d", modes[i].w, modes[i].h);
		int index = resolution->addItemUnique(str);
		if (modes[i].index == foundMode) resolution->selectItem(index);
	}


	if (fullscreen){
		if (foundMode >= 0 && XF86VidModeSwitchToMode(display, screen, dmodes[foundMode])){
			XF86VidModeSetViewPort(display, screen, 0, 0);
		} else {
			char str[128];
			sprintf(str, "Couldn't set fullscreen at %dx%d.", fullscreenWidth, fullscreenHeight);
			ErrorMsg(str);
			fullscreen = false;
		}
	}

	XVisualInfo *vi;
	while (true){
		int attribs[] = {
			GLX_RGBA,
			GLX_DOUBLEBUFFER,
			GLX_RED_SIZE,      8,
			GLX_GREEN_SIZE,    8,
			GLX_BLUE_SIZE,     8,
			GLX_ALPHA_SIZE,    (colorBits > 24)? 8 : 0,
			GLX_DEPTH_SIZE,    depthBits,
			GLX_STENCIL_SIZE,  stencilBits,
			GLX_SAMPLE_BUFFERS_ARB, (antiAliasSamples > 0),
			GLX_SAMPLES_ARB,         antiAliasSamples,
			None,
		};

		vi = glXChooseVisual(display, screen, attribs);
		if (vi != NULL) break;

		antiAliasSamples -= 2;
		if (antiAliasSamples < 0){
			char str[256];
			sprintf(str, "No Visual matching colorBits=%d, depthBits=%d and stencilBits=%d", colorBits, depthBits, stencilBits);
			ErrorMsg(str);
			return false;
		}
	}


	//printf("Selected visual = 0x%x\n",(unsigned int) (vi->visualid));
	glContext = glXCreateContext(display, vi, None, True);


	XSetWindowAttributes attr;
	attr.colormap = XCreateColormap(display, RootWindow(display, screen), vi->visual, AllocNone);

	attr.border_pixel = 0;
	attr.override_redirect = fullscreen;
    attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
		PointerMotionMask | StructureNotifyMask;

	window = XCreateWindow(display, RootWindow(display, vi->screen),
			0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
			CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &attr);

	if (!fullscreen){
	    Atom wmDelete;
        wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(display, window, &wmDelete, 1);
		char *title = "OpenGL";
        XSetStandardProperties(display, window, title, title, None, NULL, 0, NULL);
	}
    XMapRaised(display, window);

	// Create a blank cursor for cursor hiding
	XColor dummy;
	char data = 0;
	Pixmap blank = XCreateBitmapFromData(display, window, &data, 1, 1);
	blankCursor = XCreatePixmapCursor(display, blank, blank, &dummy, &dummy, 0, 0);
	XFreePixmap(display, blank);


	XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);


	glXMakeCurrent(display, window, glContext);

	initExtensions(display);

	if (antiAliasSamples > 0){
		glEnable(GL_MULTISAMPLE_ARB);
	}

	if (fullscreen) captureMouse(!configDialog->isVisible());

	renderer = new OpenGLRenderer(window, glContext, display, screen);
	renderer->setViewport(width, height);

	antiAlias->selectItem(antiAliasSamples / 2);

	linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP);
	defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp);
	blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
	noDepthTest  = renderer->addDepthState(false, false);
	noDepthWrite = renderer->addDepthState(true,  false);
	cullNone  = renderer->addRasterizerState(CULL_NONE);
	cullBack  = renderer->addRasterizerState(CULL_BACK);
	cullFront = renderer->addRasterizerState(CULL_FRONT);

	return true;
}
Esempio n. 25
0
bool TextBox::onProcessMessage(Message* msg)
{
  switch (msg->type()) {

    case kKeyDownMessage:
      if (hasFocus()) {
        View* view = View::getView(this);
        if (view) {
          gfx::Rect vp = view->getViewportBounds();
          gfx::Point scroll = view->getViewScroll();
          int textheight = getTextHeight();

          switch (static_cast<KeyMessage*>(msg)->scancode()) {

            case kKeyLeft:
              scroll.x -= vp.w/2;
              view->setViewScroll(scroll);
              break;

            case kKeyRight:
              scroll.x += vp.w/2;
              view->setViewScroll(scroll);
              break;

            case kKeyUp:
              scroll.y -= vp.h/2;
              view->setViewScroll(scroll);
              break;

            case kKeyDown:
              scroll.y += vp.h/2;
              view->setViewScroll(scroll);
              break;

            case kKeyPageUp:
              scroll.y -= (vp.h-textheight);
              view->setViewScroll(scroll);
              break;

            case kKeyPageDown:
              scroll.y += (vp.h-textheight);
              view->setViewScroll(scroll);
              break;

            case kKeyHome:
              scroll.y = 0;
              view->setViewScroll(scroll);
              break;

            case kKeyEnd:
              scroll.y = getBounds().h - vp.h;
              view->setViewScroll(scroll);
              break;

            default:
              return Widget::onProcessMessage(msg);
          }
        }
        return true;
      }
      break;

    case kMouseDownMessage: {
      View* view = View::getView(this);
      if (view) {
        captureMouse();
        m_oldPos = static_cast<MouseMessage*>(msg)->position();
        set_mouse_cursor(kScrollCursor);
        return true;
      }
      break;
    }

    case kMouseMoveMessage: {
      View* view = View::getView(this);
      if (view && hasCapture()) {
        gfx::Point scroll = view->getViewScroll();
        gfx::Point newPos = static_cast<MouseMessage*>(msg)->position();

        scroll += m_oldPos - newPos;
        view->setViewScroll(scroll);

        m_oldPos = newPos;
      }
      break;
    }

    case kMouseUpMessage: {
      View* view = View::getView(this);
      if (view && hasCapture()) {
        releaseMouse();
        set_mouse_cursor(kArrowCursor);
        return true;
      }
      break;
    }

    case kMouseWheelMessage: {
      View* view = View::getView(this);
      if (view) {
        gfx::Point scroll = view->getViewScroll();

        scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * getTextHeight()*3;

        view->setViewScroll(scroll);
      }
      break;
    }
  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 26
0
bool OpenGLApp::initAPI(){
	initialMode = CGDisplayCurrentMode(kCGDirectMainDisplay);

	dmodes = CGDisplayAvailableModes(kCGDirectMainDisplay);
	int count = CFArrayGetCount(dmodes);

	Array <DispRes> modes;
	int foundMode = -1;
	for (int i = 0; i < count; i++){
		CFDictionaryRef mode = (CFDictionaryRef) CFArrayGetValueAtIndex(dmodes, i);

		long bitsPerPixel = GetDictionaryLong(mode, kCGDisplayBitsPerPixel);
		Boolean safeForHardware = GetDictionaryBoolean(mode, kCGDisplayModeIsSafeForHardware);
		Boolean stretched = GetDictionaryBoolean(mode, kCGDisplayModeIsStretched);

		if (bitsPerPixel < colorBits || !safeForHardware || stretched) continue;

		long width  = GetDictionaryLong(mode, kCGDisplayWidth);
		long height = GetDictionaryLong(mode, kCGDisplayHeight);
		long refreshRate = GetDictionaryLong(mode, kCGDisplayRefreshRate);

//		printf("Mode: %dx%dx%d @ %d\n", width, height, bitsPerPixel, refreshRate);

		if (width >= 640 && height >= 480){
			modes.add(newRes(width, height, i));

			if (width == fullscreenWidth && height == fullscreenHeight){
				foundMode = i;
			}
		}
	}

	resolution->clear();
	modes.sort(dComp);
	char str[64];
	for (uint i = 0; i < modes.getCount(); i++){
		sprintf(str, "%dx%d", modes[i].w, modes[i].h);
		int index = resolution->addItemUnique(str);
		if (modes[i].index == foundMode) resolution->selectItem(index);
	}

	if (fullscreen){
		if (foundMode < 0 || CGDisplaySwitchToMode(kCGDirectMainDisplay, (CFDictionaryRef) CFArrayGetValueAtIndex(dmodes, foundMode)) != kCGErrorSuccess){
			sprintf(str, "Couldn't set fullscreen to %dx%d.", fullscreenWidth, fullscreenHeight);
			ErrorMsg(str);
			fullscreen = false;
		}
	}


	Rect rect;
	if (fullscreen){
		rect.left = 0;
		rect.top  = 0;
	} else {
		long w = GetDictionaryLong(initialMode, kCGDisplayWidth);
		long h = GetDictionaryLong(initialMode, kCGDisplayHeight);

		rect.left = (w - width) / 2;
		rect.top  = (h - height) / 2;
	}
	rect.right = rect.left + width;
	rect.bottom = rect.top + height;

	WindowAttributes attributes = fullscreen? (kWindowNoTitleBarAttribute | kWindowNoShadowAttribute) : (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute);

	OSStatus error = CreateNewWindow(kDocumentWindowClass, attributes, &rect, &window);
	if (error != noErr || window == NULL){
		ErrorMsg("Couldn't create window");
		return false;
	}

    GDHandle screen = GetGWorldDevice(GetWindowPort(window));
    if (screen == NULL){
        ErrorMsg("Couldn't get device");
        ReleaseWindow(window);
        return false;
    }

	AGLPixelFormat pixelFormat;
	while (true){
		GLint attributes[] = {
			fullscreen? AGL_FULLSCREEN : AGL_WINDOW,
			AGL_RGBA,
			AGL_DOUBLEBUFFER,
			AGL_RED_SIZE,            8,
			AGL_GREEN_SIZE,          8,
			AGL_BLUE_SIZE,           8,
			AGL_ALPHA_SIZE,         (colorBits > 24)? 8 : 0,
			AGL_DEPTH_SIZE,          depthBits,
			AGL_STENCIL_SIZE,        stencilBits,
			AGL_SAMPLE_BUFFERS_ARB, (antiAliasSamples > 0),
			AGL_SAMPLES_ARB,         antiAliasSamples,
			AGL_NONE
		};

		pixelFormat = aglChoosePixelFormat(&screen, 1, attributes);
		if (pixelFormat != NULL) break;

		antiAliasSamples -= 2;
		if (antiAliasSamples < 0){
			ErrorMsg("No suitable pixel format");
			ReleaseWindow(window);
			return false;
		}
	}

	glContext = aglCreateContext(pixelFormat, NULL);
    aglDestroyPixelFormat(pixelFormat);

	if (glContext == NULL){
		ErrorMsg("Couldn't create context");
		ReleaseWindow(window);
		return false;
	}

	if (fullscreen){
		CGCaptureAllDisplays();
		aglSetFullScreen(glContext, 0, 0, 0, 0);
	} else {
		if (!aglSetDrawable(glContext, GetWindowPort(window))){
			ErrorMsg("Couldn't set drawable");
			aglDestroyContext(glContext);
			ReleaseWindow(window);
			return false;
		}
	}

	if (!aglSetCurrentContext(glContext)){
		ErrorMsg("Couldn't make context current");
		aglDestroyContext(glContext);
		ReleaseWindow(window);
		return false;
	}

	setWindowTitle(getTitle());
    ShowWindow(window);

	initExtensions();

	if (antiAliasSamples > 0){
		glEnable(GL_MULTISAMPLE_ARB);
	}

	if (fullscreen) captureMouse(!configDialog->isVisible());

	renderer = new OpenGLRenderer(glContext);
	renderer->setViewport(width, height);

	antiAlias->selectItem(antiAliasSamples / 2);

	linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP);
	defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp);
	blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
	noDepthTest  = renderer->addDepthState(false, false);
	noDepthWrite = renderer->addDepthState(true,  false);
	cullNone  = renderer->addRasterizerState(CULL_NONE);
	cullBack  = renderer->addRasterizerState(CULL_BACK);
	cullFront = renderer->addRasterizerState(CULL_FRONT);

	return true;
}
Esempio n. 27
0
bool TextBox::onProcessMessage(Message* msg)
{
  switch (msg->type) {

    case JM_DRAW:
      getTheme()->draw_textbox(this, &msg->draw.rect);
      return true;

    case JM_SIGNAL:
      if (msg->signal.num == JI_SIGNAL_SET_TEXT) {
        View* view = View::getView(this);
        if (view)
          view->updateView();
      }
      break;

    case JM_KEYPRESSED:
      if (hasFocus()) {
        View* view = View::getView(this);
        if (view) {
          gfx::Rect vp = view->getViewportBounds();
          gfx::Point scroll = view->getViewScroll();
          int textheight = jwidget_get_text_height(this);

          switch (msg->key.scancode) {

            case KEY_LEFT:
              scroll.x -= vp.w/2;
              view->setViewScroll(scroll);
              break;

            case KEY_RIGHT:
              scroll.x += vp.w/2;
              view->setViewScroll(scroll);
              break;

            case KEY_UP:
              scroll.y -= vp.h/2;
              view->setViewScroll(scroll);
              break;

            case KEY_DOWN:
              scroll.y += vp.h/2;
              view->setViewScroll(scroll);
              break;

            case KEY_PGUP:
              scroll.y -= (vp.h-textheight);
              view->setViewScroll(scroll);
              break;

            case KEY_PGDN:
              scroll.y += (vp.h-textheight);
              view->setViewScroll(scroll);
              break;

            case KEY_HOME:
              scroll.y = 0;
              view->setViewScroll(scroll);
              break;

            case KEY_END:
              scroll.y = jrect_h(this->rc) - vp.h;
              view->setViewScroll(scroll);
              break;

            default:
              return false;
          }
        }
        return true;
      }
      break;

    case JM_BUTTONPRESSED: {
      View* view = View::getView(this);
      if (view) {
        captureMouse();
        jmouse_set_cursor(JI_CURSOR_SCROLL);
        return true;
      }
      break;
    }

    case JM_MOTION: {
      View* view = View::getView(this);
      if (view && hasCapture()) {
        gfx::Rect vp = view->getViewportBounds();
        gfx::Point scroll = view->getViewScroll();

        scroll.x += jmouse_x(1) - jmouse_x(0);
        scroll.y += jmouse_y(1) - jmouse_y(0);

        view->setViewScroll(scroll);

        jmouse_control_infinite_scroll(vp);
      }
      break;
    }

    case JM_BUTTONRELEASED: {
      View* view = View::getView(this);
      if (view && hasCapture()) {
        releaseMouse();
        jmouse_set_cursor(JI_CURSOR_NORMAL);
        return true;
      }
      break;
    }

    case JM_WHEEL: {
      View* view = View::getView(this);
      if (view) {
        gfx::Point scroll = view->getViewScroll();

        scroll.y += (jmouse_z(1) - jmouse_z(0)) * jwidget_get_text_height(this)*3;

        view->setViewScroll(scroll);
      }
      break;
    }
  }

  return Widget::onProcessMessage(msg);
}
Esempio n. 28
0
bool OpenGLApp::initAPI(){
	if (screen >= GetSystemMetrics(SM_CMONITORS)) screen = 0;

	int monitorCounter = screen;
	EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM) &monitorCounter);

  // TODO: Use this when saving out position?
  // HMONITOR hMonitor = MonitorFromWindow(m_handle->hWnd, MONITOR_DEFAULTTOPRIMARY);

	DWORD flags = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
	int x, y;


	x = monInfo.rcMonitor.left;
	y = monInfo.rcMonitor.top;

	device.cb = sizeof(device);
	//TODO: Monitor count is not equal to device count?
	EnumDisplayDevices(NULL, 0/*screen*/, &device, 0);

	DEVMODE dm, tdm;
	memset(&dm, 0, sizeof(dm));
	dm.dmSize = sizeof(dm);
	dm.dmBitsPerPel = colorBits;
	dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
	dm.dmPelsWidth  = fullscreenWidth;
	dm.dmPelsHeight = fullscreenHeight;
	dm.dmDisplayFrequency = 60;

	// Find a suitable fullscreen format
	int i = 0;
	int targetHz = 85;
	char str[128];

	resolution->clear();
	while (EnumDisplaySettings((const char *) device.DeviceName, i, &tdm)){
		if (int(tdm.dmBitsPerPel) == colorBits && tdm.dmPelsWidth >= 640 && tdm.dmPelsHeight >= 480){
			sprintf(str, "%dx%d", tdm.dmPelsWidth, tdm.dmPelsHeight);
			int index = resolution->addItemUnique(str);

			if (int(tdm.dmPelsWidth) == fullscreenWidth && int(tdm.dmPelsHeight) == fullscreenHeight){
				if (abs(int(tdm.dmDisplayFrequency) - targetHz) < abs(int(dm.dmDisplayFrequency) - targetHz)){
					dm = tdm;
				}
				resolution->selectItem(index);
			}
		}
		i++;
	}


	if (fullscreen){
    //TODO: Select correct monitor?
    //dm.dmFields |= DM_POSITION ;
    //dm.dmPosition.x = x;
    //dm.dmPosition.y = y;

		if (ChangeDisplaySettingsEx((const char *) device.DeviceName, &dm, NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL){
			flags |= WS_POPUP;
			captureMouse(!configDialog->isVisible());
		} else {
			ErrorMsg("Couldn't set fullscreen mode");
			fullscreen = false;
		}
	}

	sprintf(str, "%s (%dx%d)", getTitle(), width, height);
	if (!fullscreen){
		flags |= WS_OVERLAPPEDWINDOW;

		RECT wRect;
		wRect.left = 0;
		wRect.right = width;
		wRect.top = 0;
		wRect.bottom = height;
		AdjustWindowRect(&wRect, flags, FALSE);

		width  = min(wRect.right  - wRect.left, monInfo.rcWork.right  - monInfo.rcWork.left);
		height = min(wRect.bottom - wRect.top,  monInfo.rcWork.bottom - monInfo.rcWork.top);

		x = (monInfo.rcWork.left + monInfo.rcWork.right  - width ) / 2;
		y = (monInfo.rcWork.top  + monInfo.rcWork.bottom - height) / 2;
	}


	hwnd = CreateWindow("Humus", str, flags, x, y, width, height, HWND_DESKTOP, NULL, hInstance, NULL);
  
	PIXELFORMATDESCRIPTOR pfd = {
        sizeof (PIXELFORMATDESCRIPTOR), 1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA, colorBits,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		depthBits, stencilBits,
		0, PFD_MAIN_PLANE, 0, 0, 0, 0
    };

	hdc = GetDC(hwnd);

	int iAttribs[] = {
		WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
		WGL_ACCELERATION_ARB,   WGL_FULL_ACCELERATION_ARB,
		WGL_DOUBLE_BUFFER_ARB,  GL_TRUE,
		WGL_RED_BITS_ARB,       8,
		WGL_GREEN_BITS_ARB,     8,
		WGL_BLUE_BITS_ARB,      8,
		WGL_ALPHA_BITS_ARB,     (colorBits > 24)? 8 : 0,
		WGL_DEPTH_BITS_ARB,     depthBits,
		WGL_STENCIL_BITS_ARB,   stencilBits,
		0
	};

	int pixelFormats[256];
	int bestFormat = 0;
	int bestSamples = 0;
	uint nPFormats;
	if (wgl_ext_ARB_pixel_format && wglChoosePixelFormatARB(hdc, iAttribs, NULL, elementsOf(pixelFormats), pixelFormats, &nPFormats) && nPFormats > 0){
		int minDiff = 0x7FFFFFFF;
		int attrib = WGL_SAMPLES_ARB;
		int samples;

		// Find a multisample format as close as possible to the requested
		for (uint i = 0; i < nPFormats; i++){
			wglGetPixelFormatAttribivARB(hdc, pixelFormats[i], 0, 1, &attrib, &samples);
			int diff = abs(antiAliasSamples - samples);
			if (diff < minDiff){
				minDiff = diff;
				bestFormat = i;
				bestSamples = samples;
			}
		}
	} else {
		pixelFormats[0] = ChoosePixelFormat(hdc, &pfd);
	}
	antiAliasSamples = bestSamples;

	SetPixelFormat(hdc, pixelFormats[bestFormat], &pfd);

  if(wgl_ext_ARB_create_context)
  {
    glContext = wglCreateContextAttribsARB(hdc, 0, 0);
  }
  else
  {
    glContext = wglCreateContext(hdc);
  }
	wglMakeCurrent(hdc, glContext);

  ogl_LoadFunctions();
	wgl_LoadFunctions(hdc);

	if (wgl_ext_ARB_multisample && antiAliasSamples > 0){
		glEnable(GL_MULTISAMPLE);
	}

	if (fullscreen) captureMouse(!configDialog->isVisible());

	renderer = new OpenGLRenderer(hdc, glContext);
	renderer->setViewport(width, height);

	antiAlias->selectItem(antiAliasSamples / 2);

	linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP);
	defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp);
	blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
	noDepthTest  = renderer->addDepthState(false, false);
	noDepthWrite = renderer->addDepthState(true,  false);
	cullNone  = renderer->addRasterizerState(CULL_NONE);
	cullBack  = renderer->addRasterizerState(CULL_BACK);
	cullFront = renderer->addRasterizerState(CULL_FRONT);

	return true;
}
Esempio n. 29
0
bool D3D11App::initAPI(const API_Revision api_revision, const DXGI_FORMAT backBufferFmt, const DXGI_FORMAT depthBufferFmt, const int samples, const uint flags)
{
	backBufferFormat = backBufferFmt;
	depthBufferFormat = depthBufferFmt;
	msaaSamples = samples;

	const bool sampleBackBuffer = (flags & SAMPLE_BACKBUFFER) != 0;

//	if (screen >= GetSystemMetrics(SM_CMONITORS)) screen = 0;

	IDXGIFactory1 *dxgiFactory;
	if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **) &dxgiFactory)))
	{
		ErrorMsg("Couldn't create DXGIFactory");
		return false;
	}

	IDXGIAdapter1 *dxgiAdapter;
	if (dxgiFactory->EnumAdapters1(0, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND)
	{
		ErrorMsg("No adapters found");
		return false;
	}

//	DXGI_ADAPTER_DESC1 adapterDesc;
//	dxgiAdapter->GetDesc1(&adapterDesc);

	IDXGIOutput *dxgiOutput;
	if (dxgiAdapter->EnumOutputs(0, &dxgiOutput) == DXGI_ERROR_NOT_FOUND)
	{
		ErrorMsg("No outputs found");
		return false;
	}

	DXGI_OUTPUT_DESC oDesc;
	dxgiOutput->GetDesc(&oDesc);


	// Find a suitable fullscreen format
	int targetHz = 85;
	DXGI_RATIONAL fullScreenRefresh;
	int fsRefresh = 60;
	fullScreenRefresh.Numerator = fsRefresh;
	fullScreenRefresh.Denominator = 1;
	char str[128];

	uint nModes = 0;
	dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, NULL);
	DXGI_MODE_DESC *modes = new DXGI_MODE_DESC[nModes];
	dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, modes);

	resolution->clear();
	for (uint i = 0; i < nModes; i++)
	{
		if (modes[i].Width >= 640 && modes[i].Height >= 480)
		{
			sprintf(str, "%dx%d", modes[i].Width, modes[i].Height);
			int index = resolution->addItemUnique(str);

			if (int(modes[i].Width) == fullscreenWidth && int(modes[i].Height) == fullscreenHeight)
			{
				int refresh = modes[i].RefreshRate.Numerator / modes[i].RefreshRate.Denominator;
				if (abs(refresh - targetHz) < abs(fsRefresh - targetHz))
				{
					fsRefresh = refresh;
					fullScreenRefresh = modes[i].RefreshRate;
				}
				resolution->selectItem(index);
			}
		}
	}
	delete [] modes;

	sprintf(str, "%s (%dx%d)", getTitle(), width, height);

	DWORD wndFlags = 0;
	int x, y, w, h;
	if (fullscreen)
	{
		wndFlags |= WS_POPUP;
		x = y = 0;
		w = width;
		h = height;
	}
	else
	{
		wndFlags |= WS_OVERLAPPEDWINDOW;

		RECT wRect;
		wRect.left = 0;
		wRect.right = width;
		wRect.top = 0;
		wRect.bottom = height;
		AdjustWindowRect(&wRect, wndFlags, FALSE);

		MONITORINFO monInfo;
		monInfo.cbSize = sizeof(monInfo);
		GetMonitorInfo(oDesc.Monitor, &monInfo);

		w = min(wRect.right  - wRect.left, monInfo.rcWork.right  - monInfo.rcWork.left);
		h = min(wRect.bottom - wRect.top,  monInfo.rcWork.bottom - monInfo.rcWork.top);
		x = (monInfo.rcWork.left + monInfo.rcWork.right  - w) / 2;
		y = (monInfo.rcWork.top  + monInfo.rcWork.bottom - h) / 2;
	}


	hwnd = CreateWindow("Game", str, wndFlags, x, y, w, h, HWND_DESKTOP, NULL, hInstance, NULL);

	RECT rect;
	GetClientRect(hwnd, &rect);

	// Create device and swap chain
	DWORD deviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED;
#ifdef _DEBUG
    deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_FEATURE_LEVEL requested_feature_level = (api_revision == D3D11)? D3D_FEATURE_LEVEL_11_0 : (api_revision == D3D11_1)? D3D_FEATURE_LEVEL_10_1 : D3D_FEATURE_LEVEL_10_0;
	D3D_FEATURE_LEVEL feature_level;
	if (FAILED(D3D11CreateDevice(dxgiAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, deviceFlags, &requested_feature_level, 1, D3D11_SDK_VERSION, &device, &feature_level, &context)))
	{
		ErrorMsg("Couldn't create D3D11 device");
		return false;
	}

	while (msaaSamples > 0)
	{
		UINT nQuality;
		if (SUCCEEDED(device->CheckMultisampleQualityLevels(backBufferFormat, msaaSamples, &nQuality)) && nQuality > 0)
		{
			if ((flags & NO_SETTING_CHANGE) == 0) antiAliasSamples = msaaSamples;
			break;
		}
		else
		{
			msaaSamples -= 2;
		}
	}
	DXGI_SWAP_CHAIN_DESC sd;
	memset(&sd, 0, sizeof(sd));
	sd.BufferDesc.Width  = rect.right;
	sd.BufferDesc.Height = rect.bottom;
	sd.BufferDesc.Format = backBufferFormat;
	sd.BufferDesc.RefreshRate = fullScreenRefresh;
	sd.BufferUsage = /*DXGI_USAGE_BACK_BUFFER | */DXGI_USAGE_RENDER_TARGET_OUTPUT | (sampleBackBuffer? DXGI_USAGE_SHADER_INPUT : 0);
	sd.BufferCount = 1;
	sd.OutputWindow = hwnd;
	sd.Windowed = (BOOL) (!fullscreen);
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	sd.SampleDesc.Count = msaaSamples;
	sd.SampleDesc.Quality = 0;

	if (FAILED(dxgiFactory->CreateSwapChain(device, &sd, &swapChain)))
	{
		ErrorMsg("Couldn't create swapchain");
		return false;
	}

	// We'll handle Alt-Enter ourselves thank you very much ...
	dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);

	dxgiOutput->Release();
	dxgiAdapter->Release();
	dxgiFactory->Release();

	if (fullscreen)
	{
		captureMouse(!configDialog->isVisible());
	}

	renderer = new Direct3D11Renderer(device, context);

	if (!createBuffers(sampleBackBuffer))
	{
		delete renderer;
		return false;
	}
	antiAlias->selectItem(antiAliasSamples / 2);

	linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP);
	defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp);
	blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
	noDepthTest  = renderer->addDepthState(false, false);
	noDepthWrite = renderer->addDepthState(true,  false);
	cullNone  = renderer->addRasterizerState(CULL_NONE);
	cullBack  = renderer->addRasterizerState(CULL_BACK);
	cullFront = renderer->addRasterizerState(CULL_FRONT);

	return true;
}
Esempio n. 30
0
bool PaletteView::onProcessMessage(Message* msg)
{
  switch (msg->type) {

    case JM_REQSIZE:
      request_size(&msg->reqsize.w, &msg->reqsize.h);
      return true;

    case JM_DRAW: {
      div_t d = div(Palette::MaxColors, m_columns);
      int cols = m_columns;
      int rows = d.quot + ((d.rem)? 1: 0);
      int x, y, u, v;
      int c, color;
      BITMAP *bmp;
      Palette* palette = get_current_palette();
      int bordercolor = makecol(255, 255, 255);

      bmp = create_bitmap(jrect_w(this->rc), jrect_h(this->rc));
      clear_to_color(bmp, makecol(0 , 0, 0));

      y = this->border_width.t;
      c = 0;

      for (v=0; v<rows; v++) {
        x = this->border_width.l;

        for (u=0; u<cols; u++) {
          if (c >= palette->size())
            break;

          if (bitmap_color_depth(ji_screen) == 8)
            color = c;
          else
            color = makecol_depth
              (bitmap_color_depth(ji_screen),
               _rgba_getr(palette->getEntry(c)),
               _rgba_getg(palette->getEntry(c)),
               _rgba_getb(palette->getEntry(c)));

          rectfill(bmp, x, y, x+m_boxsize-1, y+m_boxsize-1, color);

          if (m_selectedEntries[c]) {
            const int max = Palette::MaxColors;
            bool top    = (c >= m_columns            && c-m_columns >= 0  ? m_selectedEntries[c-m_columns]: false);
            bool bottom = (c < max-m_columns         && c+m_columns < max ? m_selectedEntries[c+m_columns]: false);
            bool left   = ((c%m_columns)>0           && c-1         >= 0  ? m_selectedEntries[c-1]: false);
            bool right  = ((c%m_columns)<m_columns-1 && c+1         < max ? m_selectedEntries[c+1]: false);

            if (!top) hline(bmp, x-1, y-1, x+m_boxsize, bordercolor);
            if (!bottom) hline(bmp, x-1, y+m_boxsize, x+m_boxsize, bordercolor);
            if (!left) vline(bmp, x-1, y-1, y+m_boxsize, bordercolor);
            if (!right) vline(bmp, x+m_boxsize, y-1, y+m_boxsize, bordercolor);
          }

          x += m_boxsize+this->child_spacing;
          c++;
        }

        y += m_boxsize+this->child_spacing;
      }

      blit(bmp, ji_screen,
           0, 0, this->rc->x1, this->rc->y1, bmp->w, bmp->h);
      destroy_bitmap(bmp);
      return true;
    }

    case JM_BUTTONPRESSED:
      captureMouse();
      /* continue... */

    case JM_MOTION: {
      JRect cpos = jwidget_get_child_rect(this);

      int req_w, req_h;
      request_size(&req_w, &req_h);

      int mouse_x = MID(cpos->x1, msg->mouse.x, cpos->x1+req_w-this->border_width.r-1);
      int mouse_y = MID(cpos->y1, msg->mouse.y, cpos->y1+req_h-this->border_width.b-1);

      jrect_free(cpos);

      Color color = getColorByPosition(mouse_x, mouse_y);
      if (color.getType() == Color::IndexType) {
        int idx = color.getIndex();

        app_get_statusbar()->showColor(0, "", color, 255);

        if (hasCapture() && idx != m_currentEntry) {
          if (!(msg->any.shifts & KB_CTRL_FLAG))
            clearSelection();

          if (msg->any.shifts & KB_SHIFT_FLAG)
            selectRange(m_rangeAnchor, idx);
          else
            selectColor(idx);

          // Emit signals
          jwidget_emit_signal(this, SIGNAL_PALETTE_EDITOR_CHANGE);
          IndexChange(idx);
        }
      }

      if (hasCapture())
        return true;

      break;
    }

    case JM_BUTTONRELEASED:
      releaseMouse();
      return true;

    case JM_WHEEL: {
      View* view = View::getView(this);
      if (view) {
        gfx::Point scroll = view->getViewScroll();
        scroll.y += (jmouse_z(1)-jmouse_z(0)) * 3 * m_boxsize;
        view->setViewScroll(scroll);
      }
      break;
    }

    case JM_MOUSELEAVE:
      app_get_statusbar()->clearText();
      break;

  }

  return Widget::onProcessMessage(msg);
}