Пример #1
0
void KrEventManager::HandleEvent( const SDL_Event& event, KrEngine* engine )
{
    if ( event.type == SDL_KEYDOWN && keyFocus >= 0) //maks
    {
        //	- the tab key changes key focus.
        //	- accelerators are checked
        //	- keys passed through to the handler.

#ifdef DEBUG
        GLOUTPUT( "KeyDown mod=%d sym=%d, unicode=%d, name=%s\n", event.key.keysym.mod, event.key.keysym.sym, event.key.keysym.unicode, SDL_GetKeyName(event.key.keysym.sym)); //maks
#endif

        if (    event.key.keysym.sym == SDLK_TAB
                && keyListeners.Count() > 1 )
        {
            if ( event.key.keysym.mod & KMOD_SHIFT )
                ChangeKeyFocus( keyFocus + keyListeners.Count() - 1 );
            else
                ChangeKeyFocus( keyFocus + 1 );
            return;
        }

        for( int i=0; i<accelListeners.Count(); ++i )
        {
            int sym = accelListeners[i].keysym;
            int mod = accelListeners[i].keymod;

            if (    event.key.keysym.sym == sym &&
                    event.key.keysym.mod & mod &&
                    keyListeners.Count() &&
                    accelListeners[i].target == keyListeners[ keyFocus ]) //maks: send accelerators for key focus owners
            {
                accelListeners[i].target->Accelerate( true, mod, sym ); //maks
                return;
            }
        }

        if ( keyListeners.Count() > 0 )
        {
            keyFocus = GlClamp( keyFocus, 0, int( keyListeners.Count()-1 ) );
            KrWidget* widget = keyListeners[ keyFocus ];

            // Go up the chain until handled.
            while( widget && !widget->KeyEvent( event ) )
            {
                widget = widget->ParentWidget();
            }
        }
    }
    else if ( event.type == SDL_KEYUP )
    {
        // - only accelerates key up
        for( int i=0; i<accelListeners.Count(); ++i )
        {
            if (    event.key.keysym.sym == accelListeners[i].keysym &&
                    event.key.keysym.mod & accelListeners[i].keymod &&
                    keyFocus >= 0 &&
                    keyListeners.Count() &&
                    accelListeners[i].target == keyListeners[ keyFocus ]) //maks
            {
                accelListeners[i].target->Accelerate( false, event.key.keysym.mod, event.key.keysym.sym ); //maks
                return;
            }
        }

        //Send shift key up
        if ( keyListeners.Count() > 0 && (event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT))
        {
            keyFocus = GlClamp( keyFocus, 0, int( keyListeners.Count()-1 ) );
            KrWidget* widget = keyListeners[ keyFocus ];

            // Go up the chain until handled.
            while( widget && !widget->KeyEvent( event ) )
            {
                widget = widget->ParentWidget();
            }
        }
    }
    else if ( event.type == SDL_MOUSEMOTION )
    {
        GlDynArray<KrImage*> hitArray;
        KrWidget* hit = 0;
        //int window = engine->GetWindowFromPoint( event.motion.x, event.motion.y );

        KrVector2T< GlFixed > object;

#ifndef _WIN32_WCE
        if(mouseDown && mouseFocus) //maks
        {
            //Don't change the focus if mouse button is down
            //Don't works on Pocket PC. In input.ged don't close the SIP keyboard (only send keyFocus = true)

            hit = mouseFocus;
            hit->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );
        }
        else
#endif
        {
            engine->Tree()->HitTest( event.motion.x, event.motion.y,
                                     KrImageTree::ALWAYS_INSIDE_BOX, //| GET_ALL_HITS,
                                     &hitArray/*,
				&window*/ );


            for( int i=0; i<hitArray.Count(); ++i )
            {
                KrImNode* parent = hitArray[i]->Parent();
                while( parent )
                {
                    if ( parent->ToWidget() )
                    {
                        hit = parent->ToWidget();
                        hit->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );
                        break;
                    }
                    parent = parent->Parent();
                }
            }
        }

        // 1) Something has the focus. Nothing had it before.
        // 2) Something has the focus, something else had it before.
        // 3) Something loses the focus.
        // 5) The thing with focus gets a move.
        if ( hit && !mouseFocus )
        {
            mouseFocus = hit;
            mouseFocus->MouseIn( mouseDown, true );
            mouseFocus->MouseMove( mouseDown, object.x.ToIntRound(), object.y.ToIntRound() );
        }
        else if ( hit && mouseFocus && mouseFocus != hit )
        {
            mouseFocus->MouseIn( mouseDown, false );
            mouseFocus = hit;
            mouseFocus->MouseIn( mouseDown, true );
            mouseFocus->MouseMove( mouseDown, object.x.ToIntRound(), object.y.ToIntRound() );
        }
        else if ( !hit && mouseFocus )
        {
            mouseFocus->MouseIn( mouseDown, false );
            mouseFocus = hit;
        }
        else if ( hit && hit == mouseFocus )
        {
            GLASSERT( hit == mouseFocus );
            mouseFocus->MouseMove( mouseDown, object.x.ToIntRound(), object.y.ToIntRound() );
        }
        else if ( !hit && !mouseFocus )
        {
            // nothing to do
        }
        else
        {
            GLASSERT( 0 );
        }

    }
    else if ( event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP )
    {
        if ( event.button.button == SDL_BUTTON_LEFT )
        {
            bool down = event.button.state != 0;	// & SDL_BUTTON_LMASK;
            if ( down != mouseDown )
            {
                mouseDown = down;
                if ( mouseFocus )
                {
                    int window = engine->GetWindowFromPoint( event.motion.x, event.motion.y );
                    KrVector2T< GlFixed > object;
                    mouseFocus->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );

                    mouseFocus->MouseClick( mouseDown ? KrWidget::LEFT_DOWN : KrWidget::LEFT_UP,
                                            object.x.ToIntRound(),
                                            object.y.ToIntRound() );
                }
                else //maks
                {
                    if(
                        keyFocus >= 0 && keyFocus < keyListeners.Count() &&
                        !newListnerFocus //maks: Only remove the focus if the widget don't has changed the focus in this cycle (solve focus bug in Math for Kids.ged)
                    )
                    {
                        keyListeners[ keyFocus ]->KeyFocus( false );
                        keyFocus = -1;
                        FocusState(false);
                    }
                }
            }
        }
        else if ( event.button.button == SDL_BUTTON_RIGHT ) //maks
        {
            bool down = event.button.state != 0;
            if ( down != mouseDown )
            {
                mouseDown = down;
                if ( mouseFocus )
                {
                    int window = engine->GetWindowFromPoint( event.motion.x, event.motion.y );
                    KrVector2T< GlFixed > object;
                    mouseFocus->ScreenToObject( event.motion.x, event.motion.y, &object/*, window*/ );

                    mouseFocus->MouseClick( mouseDown ? KrWidget::RIGHT_DOWN : KrWidget::RIGHT_UP,
                                            object.x.ToIntRound(),
                                            object.y.ToIntRound() );
                }
            }
        }
    }

    newListnerFocus = false; //maks
}
Пример #2
0
void KrEncoder::CreateIsoTile(	KrPaintInfo* info, 
								KrConsole* console,
								int x, int y,
								int width, int height,
								KrRle* rle,
								int isoWidth,
								int rotation )
{
	if ( isoWidth % 4 )
	{
		console->Print( "ERROR: Isometric tile created with non-multiplo of 4 width (%d).\n", isoWidth );
		return;
	}

	int isoHeight = isoWidth / 2;
	KrPainter painter( info );
	KrRGBA rgba;

	// Create a memory buffer to hold the tile:
	KrRGBA* isoMemory = new KrRGBA[ isoWidth * isoHeight ];
	memset( isoMemory, 0, isoWidth * isoHeight * sizeof( KrRGBA ) );

	for( int iy = 0; iy < isoHeight; ++iy )
	{
		int rowwidth = 0;
		if ( iy < isoHeight / 2 )
			rowwidth = 2 + 4 * iy;
		else
			rowwidth = 2 + 4 * ( isoHeight - iy - 1 );

		const int QUALITY = 4;		// 2, 4
		const int QUALITYAREA = 16;	// 4, 16
		const int QUALITYBIAS = 7;	// 1, 7
		const GlFixed increment = GlFixed( 1  ) / GlFixed( QUALITY );

		for( int ix =  isoWidth / 2 - rowwidth / 2;
		         ix <  isoWidth / 2 + rowwidth / 2;
				 ++ix )
		{
			int red = 0, green = 0, blue = 0, alpha = 0;

			for ( int i=0; i<QUALITY; ++i )
			{
				for ( int j=0; j<QUALITY; ++j )
				{
					GlFixed fsx, fsy;
					int sx, sy;

					IsoToSource( ix + increment*i,   
								 iy - isoHeight / 2 + increment*j,   
								 isoWidth, width, height, &fsx, &fsy,
								 rotation, increment );
					
					//sx = fsx.ToInt();
					//sy = fsy.ToInt();

					sx = GlClamp( fsx.ToIntRound(), 0, width - 1 );
					sy = GlClamp( fsy.ToIntRound(), 0, height - 1 );					

					painter.BreakPixel( sx + x, sy + y, &rgba );
					
					red   += rgba.c.red;
					green += rgba.c.green;
					blue  += rgba.c.blue;
					alpha += rgba.c.alpha;
				}
			}

			// Whew! all that for one pixel.
			// Use rounding on the colors, to gamma-correct
			rgba.Set(	( red + QUALITYBIAS ) / QUALITYAREA, 
						( green + QUALITYBIAS ) / QUALITYAREA, 
						( blue + QUALITYBIAS ) / QUALITYAREA, 
						( alpha + QUALITYBIAS ) / QUALITYAREA );
			GLASSERT( iy >= 0 && iy < isoHeight );
			GLASSERT( ix >= 0 && ix < isoWidth );
			isoMemory[ iy * isoWidth + ix ] = rgba;
		}
	}
	KrPaintInfo isoInfo( isoMemory, isoWidth, isoHeight );
	rle->Create( &isoInfo, 0, 0, 
				 isoWidth, isoHeight, 
				 ( isoWidth - 1 ) / 2, ( isoHeight - 1 ) / 2, 
				 isoWidth, isoHeight );
	delete [] isoMemory;
}