ホーム > デベロッパ > BREW プログラミング入門 > イベント処理って何だ? > - 2 / 2 -

イベント処理って何だ? - 2 / 2 -

//
//      Nico.c
//

#include "AEEModGen.h"      // モジュール インターフェイスの宣言
#include "AEEAppGen.h"      // アプレット インターフェイスの宣言
#include "AEEShell.h"       // シェル インターフェイスの宣言
#include "AEEGraphics.h"    // グラフィック インターフェイスの宣言

#include "Nico.bid"


// ニコチャン アプレット構造体
typedef struct
{
    AEEApplet   a;          // アプレット構造体の先頭メンバは必ず AEEApplet 型にすること
    IGraphics*  graphics;   // IGraphics オブジェクト
    boolean     pressed;    // キーが押された状態か
} NicoApplet;


// 前方宣言
static boolean Nico_HandleEvent(NicoApplet * app, AEEEvent eCode, 
                                uint16 wParam, uint32 dwParam);

static boolean Nico_OnAppStart(NicoApplet* app);
static boolean Nico_OnAppStop(NicoApplet* app);
static boolean Nico_OnAppSuspend(NicoApplet* app);
static boolean Nico_OnAppResume(NicoApplet* app);
static boolean Nico_OnKey(NicoApplet* app, uint16 key);
static boolean Nico_OnKeyPress(NicoApplet* app, uint16 key);
static boolean Nico_OnKeyRelease(NicoApplet* app, uint16 key);
static void Nico_DrawFace(NicoApplet* app);


//
//  アプレットを作成するときに呼び出されます。
//
int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po,void ** ppObj)
{
    *ppObj = NULL;
    
    if (ClsId == AEECLSID_NICO){
        if (AEEApplet_New(sizeof(NicoApplet), ClsId, pIShell, po, (IApplet**)ppObj,
            (AEEHANDLER)Nico_HandleEvent, NULL) == TRUE) 
        {
            // アプレット構造体を初期化する
            NicoApplet* app = (NicoApplet*)(*ppObj);
            app->pressed = FALSE;

            return AEE_SUCCESS;
        }
    }
    return (EFAILED);
}


//
//  イベント ハンドラ
//
static boolean Nico_HandleEvent(
    NicoApplet* app, AEEEvent eCode, uint16 wParam, uint32 dwParam)
{  
    switch (eCode) 
    {
    case EVT_APP_START:
        return Nico_OnAppStart(app);

    case EVT_APP_STOP:
        return Nico_OnAppStop(app);

    case EVT_APP_SUSPEND:
        return Nico_OnAppSuspend(app);

    case EVT_APP_RESUME:
        return Nico_OnAppResume(app);

    case EVT_KEY:
        return Nico_OnKey(app, wParam);

    case EVT_KEY_PRESS:
        return Nico_OnKeyPress(app, wParam);

    case EVT_KEY_RELEASE:
        return Nico_OnKeyRelease(app, wParam);
            
    default:
        break;
    }
    return FALSE;
}


//
//  アプレットが開始したときに呼び出される
//
static boolean Nico_OnAppStart(NicoApplet* app)
{
    IShell* shell = app->a.m_pIShell;

    // IGraphics オブジェクトを取得する
    ISHELL_CreateInstance(shell, AEECLSID_GRAPHICS, &app->graphics);
    if (app->graphics == NULL) 
        return FALSE;

    // 画面描画
    Nico_DrawFace(app);

    return TRUE;
}


//
//  アプレットが終了したときに呼び出される
//
static boolean Nico_OnAppStop(NicoApplet* app)
{
    // IGraphics オブジェクトを解放する
    IGRAPHICS_Release(app->graphics);

    return TRUE; 
}


//
//  アプレットが中断したときに呼び出される
//
static boolean Nico_OnAppSuspend(NicoApplet* app)
{
    // サスペンドする前にキー押下状態を解除する
    app->pressed = FALSE;

    return TRUE;
}


//
//  アプレットが再開したときに呼び出される
//
static boolean Nico_OnAppResume(NicoApplet* app)
{
    // 画面描画
    Nico_DrawFace(app);

    return TRUE;
}


//
//  キーが押されたときに呼び出される。
//
static boolean Nico_OnKey(NicoApplet* app, uint16 key)
{
    if (key == AVK_SOFT2) {
        ISHELL_CloseApplet(app->a.m_pIShell, TRUE);
        return TRUE;
    }
    if (key == AVK_SOFT1) {
        ISHELL_StartApplet(app->a.m_pIShell, 0x1234);
    }

    return FALSE;
}


//
//  キーが押下されたときに呼び出される
//
static boolean Nico_OnKeyPress(NicoApplet* app, uint16 key)
{
    if (key == AVK_SELECT) {
        app->pressed = TRUE;
        Nico_DrawFace(app);
        return TRUE;
    }
    return FALSE;
}


//
//  キーが押下状態から離されたときに呼び出される
//
static boolean Nico_OnKeyRelease(NicoApplet* app, uint16 key)
{
    if (key == AVK_SELECT) {
        app->pressed = FALSE;
        Nico_DrawFace(app);
        return TRUE;
    }
    return FALSE;
}



//
//  ニコチャンを描画する関数
//
//  NicoApplet.pressed が FALSE ならば笑った顔、
//  TRUE ならば怒った顔を表示する。
//
static void Nico_DrawFace(NicoApplet* app)
{
    IGraphics* g = app->graphics;
    AEECircle c;
    AEELine* lines;

    AEELine nico_lines[] = { // 笑った顔の線テーブル
        { 45, 40, 45, 48 },
        { 55, 40, 55, 48 },
        { 40, 55, 50, 60 },
        { 60, 55, 50, 60 },
        { -1, -1, -1, -1 }
    };

    AEELine pun_lines[] = {  // 怒った顔の線テーブル
        { 35, 35, 45, 45 },
        { 65, 35, 55, 45 },
        { 35, 60, 65, 60 },
        { -1, -1, -1, -1 }
    };

    // 線の描画色を黒に設定
    IGRAPHICS_SetColor(g, 0, 0, 0, 0);

    // 塗りつぶしモードに設定
    IGRAPHICS_SetFillMode(g, TRUE);

    // 画面全体を白でクリア
    IGRAPHICS_SetBackground(g, 255, 255, 255);
    IGRAPHICS_ClearViewport(g);


    // 顔の色を設定
    if (app->pressed) {
        IGRAPHICS_SetFillColor(g, 255, 0, 0, 0);
    }
    else {
        IGRAPHICS_SetFillColor(g, 255, 255, 0, 0);
    }

    // 顔の円を描画
    c.cx = 50;
    c.cy = 50;
    c.r  = 20 + (app->pressed ? 10 : 0);
    IGRAPHICS_DrawCircle(g, &c);


    // 顔の目と口を描画
    lines = (app->pressed) ? pun_lines : nico_lines;
    while ((*lines).sx != -1) {
        IGRAPHICS_DrawLine(g, lines);
        lines++;
    }

    // 実際に画面に表示する
    IGRAPHICS_Update(g);

}