اطلاعیه

Collapse
No announcement yet.

ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    #16
    پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

    oop نوعی روش برنامه نویسی هستش که البته در C++ قابل استفاده هستش ولی در C نیست

    دیدگاه


      #17
      پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

      نوشته اصلی توسط gbg
      oop نوعی روش برنامه نویسی هستش که البته در C++ قابل استفاده هستش ولی در C نیست
      آهان فهمیدم منظورشون Object-oriented programming یا همون برنامه نویسی شی گرا هست.
      بله اگه ویندوزها و بقیه اجزا به صورت شی گرا باشن مدیریتشون خیلی راحت تر میشه.نمیدونم اصلا چرا این نوع برنامه نویسی با اینکه کارو راحت میکنه و keil هم از ازش پشتیبانی میکنه ولی استفاده تو پروژه های دانشجویی نمیشه .شایدم استفاده میشه ما ندیدیم.
      مثلا پورت سریال میکرو به صورت یه شیء تعریف بشه و بشه براحتی مثلا با دستورهای زیر باهاش کار کرد :

      کد:
      UART0.baudrate = 9600
      UART0.puts("Hello C++)

      دیدگاه


        #18
        پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

        نوعی روش برنامه نویسی هستش که البته در C++ قابل استفاده هستش ولی در C نیست
        در حد سورس کد ممکنه ولی در حد پیاده سازی با هر زبانی میشه. من جمله اسمبلی.

        دیدگاه


          #19
          پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

          بیس اصلی برنامه و کلاس Alert و List رو تا یه حدی کار کردم ولی الان چندتا مشکل دارم.
          مراحل کارو میگم ولی چون سورسه هنوز خیلی ناقصه نمیذارمش.
          - اول یه Namespace به اسم GUI درست کردم.
          - یه کلاس به اسم Alert توش تعریف کردم که عنوان و متن اصلی و آدرس تصویر Alert و نوع Alert رو تو خودش نگه میداره و شامل چند تا متد برای ایجاد Alert با ورودهای مختلف هست.
          - یه کلاس هم عین Alert برای List تعریف کردم با این تفاوت که این یکی عکسی نداره و به جای متن یه آرایه از لیست هست.
          -یه کلاس هم با اسم Display درست کردم.وظیفه این کلاس نمایش عناصر گرافیکی مثل Alert روی LCD هست.یعنی این کلاس تعیین میکنه که نحوه چینش عناصر گرافیکی باید چطور باشه.این کلاس شامل چندتا متد Overload شده (فارسیش چیه ؟) به اسم Show هست که با گرفتن عنصر گرافیکی اونو نمایش میده.همچنین بسته به نوع عنصر گرافیکی کامندهایی درست میکنه که برای تشخیص لمس شدن دکمه ها و اعضای لیست استفاده میشن.
          - یه کلاس کامند هم تعریف کردم که اسم مختصات و طول کلیدها و بقیه عناصری که نیاز هست لمس اونها تشخیص داده بشه رو نگه داری میکنه.
          - داخل کلاس Display یه متد به اسم cheak درست کردم که باید در بازه های زمانی کوتاه فراخوانی بشه.با این کار تاچ چک میشه و اگه کلیدی چیزی فشرده شده باشه اسم اون کلید رو برمیگردونه.

          تو برنامه مثال اول یه Alert و دو تا List تعریف شده و بعد Alert نشون میده و اگه کلید Yes فشرده بشه لیست 2 و در غیر این صورت لیست 1 رو نشون میده.

          کد:
           Display disp;
          Alert alert("Alert","Are you Sure ?",image,Alert::YESNO);
           	char *lst1[]={"Choise 1","Choise 2","Choise 3","Choise 4"};
          	char *lst2[]={"Choise 5","Choise 6","Choise 7","Choise 8"};
           	List list1("List1",lst1,List::Exclusive);
          	List list2("List2",lst1,List::Exclusive);
          	char *cmdtxt;
          	
          	disp.Show(alert);
          	while ((cmdtxt = disp.cheak())==0) {
          		os_dly_wait(10);
          	}
          	if (strcmp(cmdtxt,"NO")==0) disp.Show(list1);
          	else if (strcmp(cmdtxt,"YES")==0) disp.Show(list2);


          حالا مشکل اینه که برنامه باید منتظر فشرده شدن کلید باشه.چطوری میتونم کاری بکنم که اگه کلیدی فشرده بشه توسط کلاس Display این اتفاق به برنامه اصلی منتقل بشه.مثلا یه تایع از برنامه اصلی فراخونی بشه.

          دیدگاه


            #20
            پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

            من اون موردی که کار کردم بر اساس ساختارهایی شبیه Windows بود. برای انجام عملیات روی اون ساختارها شما به اولین چیزی که احتیاج دارین مدیریت رویداد ها هست. یعنی مثلا یک تسک داشته باشین که مرتبا کی پد و یا تاچ رو مانیتور کنه و تغییرات محل فشار دادن یا تایمر ها و غیره رو از طریق یک سری پیغام داخل یک صف به برنامه اصلی انتقال بده. حتی میشه عملیات گرافیکی رو هم توی همین تسک انجام داد یا بهتر اینه که توی یک تسک با اولویت پایین عملیات رسم انجام بشه و در یک تسک با اولویت بالا سرویس دهی به تایمر ها و تاچ و غیره صورت بگیره.

            اما صرف نظر از اینا کاری که میشه کرد اینه که (تیپ ویندوزی) برنامه ای که داره این متد رو برای نمایش Alert فراخوانی میکنه باید کد بازگشتی از نمایش Alert برگرده. و صدا زننده بر اون اساس کارشو ادامه بده. این اصول کلی!

            اما ایجاد یک محیط همچینی بیشتر به این درد میخوره که علاوه بر انجام عملیات گرافیکی (که بر خلاف انتظار شما اصلا کار مهمی هم نیست) اصل عملیات منطقی انجام بشه. بنا براین استفاده از یه چیزی مثل os_dly_wait کار درستی نیست.

            دیدگاه


              #21
              پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD


              منم دقیقا یه تسک لازم دارم که تاچ رو مانیتور کنه و تغییراتشو مونیتور کنه و اگه رویدادی رخ داده باشه اونو به برنامه اصلی منتقل کنه.حالا مساله اینجاست که این انتقال رویداد داخل یه پیغام به برنامه اصلی چطوری انجام بشه؟اگه کد بازگشتی متد نمایش Alert این پیغام باشه که برنامه باید تو همین متد نمایش منتظر فشرده شدن صفحه لمسی بشه.
              مثالی که گذاشتم یه تسک با اولویت پایین هست که به نمایش گرافیکی اختصاص داره.چون منم میخوام نمایش گرافیکی از برنامه اصلی جدا بشه ولی قسمت نمایش گرافیکی باید به صورت رویدادی کار کنه نه ترتیبی.منظورم اینه که مثل مثالی که نوشتم نباشه که اول یه چیزو نشون بده و بعد تو یه حلقه while منتظر اتفاق باشه و بعد ادامه بده.طوره باشه که این تسک اگه یه رویداد مربوط به گرافیک افتاد فراخوانی بشه و بعد نمایش تغییرات مشخص شده تموم بشه.

              دیدگاه


                #22
                پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

                شما میتونی از ساختاری مثل message queue استفاده کنی. همیشه یک پنجره در حالت active داریم که رویداد های مربوط به تاچ به اون ارسال میشه. ضمنا رویداد هایی مثل enter و leave هم داریم که برای تمام window ها ارسال میشه و در تابع داخلی مربوطه پردازش میشه. در Gdi در ویندوز تمام عملیات گرافیکی به صورت فرمانهایی برای تسک رفرش کننده ارسال میشه تا در اونجا پردازش بشه. این ارتباط هم میتونه از طریق message queue انجام بشه.
                اما تمام اینها بستگی داره به نوع و تعداد سخت افزارهای ورودی و مشخصات کاری برنامه. چه بسا ممکنه اگه روالهای ترسیم از طریق این تسک انجام نشه سریعتر باشه و نیاز کمتری به حجم حافظه داشته باشه.

                دیدگاه


                  #23
                  پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

                  با سلام

                  خدمت دوستان عزیز کتابخانه کامل رابط گرافیکی توسط شرکت میکرو چیپ با نام AN1136 رادانلود کنید یک فایل نصبی تمام کتابخانه ها شامل موار زیر امده وقابل استفاده است

                  1. Button
                  2. Slider
                  3. Window
                  4. Check Box
                  5. Radio Button
                  6. Edit Box
                  7. List Box
                  8. Group Box
                  9. Horizontal/Vertical Scroll Bars
                  10. Progress Bar
                  11. Static Text
                  12. Picture
                  13. Dial
                  14. Meter
                  Please refer to the “Microchip Graphics Library API”
                  documentation for a description of each Object.

                  بر اساس سورس فایل اصلی میتوان برای تمام میکرو ها تغیر داد
                  در زیر رابط باتوم butom l کد ببینید



                  [tt]************************************************** ***************************
                  * Module for Microchip Graphics Library
                  * GOL Layer
                  * Button
                  ************************************************** ***************************
                  * FileName: Button.c
                  * Dependencies: Button.h
                  * Processor: PIC24, PIC32
                  * Compiler: MPLAB C30 Version 3.00, C32
                  * Linker: MPLAB LINK30, LINK32
                  * Company: Microchip Technology Incorporated
                  *
                  * Software License Agreement
                  *
                  * Copyright © 2007 Microchip Technology Inc. All rights reserved.
                  * Microchip licenses to you the right to use, modify, copy and distribute
                  * Software only when embedded on a Microchip microcontroller or digital
                  * signal controller, which is integrated into your product or third party
                  * product (pursuant to the sublicense terms in the accompanying license
                  * agreement).
                  *
                  * You should refer to the license agreement accompanying this Software
                  * for additional information regarding your rights and obligations.
                  *
                  * SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
                  * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
                  * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
                  * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
                  * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
                  * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
                  * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
                  * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
                  * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
                  * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
                  * OR OTHER SIMILAR COSTS.
                  *
                  * Author Date Comment
                  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  * Paolo A. Tamayo 11/12/07 Version 1.0 release
                  ************************************************** ***************************/

                  #include "Graphics\Graphics.h"

                  #ifdef USE_BUTTON

                  /************************************************** *******************
                  * Function: BUTTON *BtnCreate(WORD ID, SHORT left, SHORT top, SHORT right,
                  * SHORT bottom, SHORT radius, void *pBitmap, XCHAR *pText,
                  * GOL_SCHEME *pScheme)
                  *
                  *
                  * Notes: Creates a BUTTON object and adds it to the current active list.
                  * If the creation is successful, the pointer to the created Object
                  * is returned. If not successful, NULL is returned.
                  *
                  ************************************************** ******************/
                  BUTTON *BtnCreate( WORD ID, SHORT left, SHORT top, SHORT right, SHORT bottom, SHORT radius,
                  WORD state, void *pBitmap, XCHAR *pText, GOL_SCHEME *pScheme)
                  {
                  BUTTON *pB = NULL;

                  pB = malloc(sizeof(BUTTON));
                  if (pB == NULL)
                  return NULL;

                  pB->ID = ID; // unique id assigned for referencing
                  pB->pNxtObj = NULL; // initialize pointer to NULL
                  pB->type = OBJ_BUTTON; // set object type
                  pB->left = left; // left position
                  pB->top = top; // top position
                  pB->right = right; // right position
                  pB->bottom = bottom; // bottom position
                  pB->radius = radius; // radius
                  pB->pBitmap = pBitmap; // location of bitmap
                  pB->pText = pText; // location of the text
                  pB->state = state; // state

                  // Set the color scheme to be used
                  if (pScheme == NULL)
                  pB->pGolScheme = _pDefaultGolScheme;
                  else
                  pB->pGolScheme = (GOL_SCHEME *)pScheme;

                  pB->textWidth = 0;
                  pB->textHeight = 0;
                  if (pB->pText != NULL) {
                  // Calculate the text width & height
                  pB->textWidth = GetTextWidth(pText, pB->pGolScheme->pFont);
                  pB->textHeight = GetTextHeight(pB->pGolScheme->pFont);
                  }
                  GOLAddObject((OBJ_HEADER*) pB);

                  #ifdef USE_FOCUS
                  if(GetState(pB,BTN_FOCUSED))
                  GOLSetFocus((OBJ_HEADER*)pB);
                  #endif

                  return pB;
                  }

                  /************************************************** *******************
                  * Function: BtnSetText(BUTTON *pB, XCHAR *pText)
                  *
                  *
                  * Notes: Sets the text used in the button.
                  *
                  ************************************************** ******************/
                  void BtnSetText(BUTTON *pB, XCHAR *pText)
                  {
                  pB->pText = pText;
                  pB->textWidth = GetTextWidth(pText, pB->pGolScheme->pFont);
                  pB->textHeight = GetTextHeight(pB->pGolScheme->pFont);
                  }

                  /************************************************** *******************
                  * Function: BtnMsgDefault(WORD translatedMsg, BUTTON *pB, GOL_MSG* pMsg)
                  *
                  *
                  * Notes: This the default operation to change the state of the button.
                  * Called inside GOLMsg() when GOLMsgCallback() returns a 1.
                  *
                  ************************************************** ******************/
                  void BtnMsgDefault(WORD translatedMsg, BUTTON *pB, GOL_MSG* pMsg){

                  #ifdef USE_FOCUS
                  #ifdef USE_TOUCHSCREEN
                  if(pMsg->type == TYPE_TOUCHSCREEN){
                  if(!GetState(pB,BTN_FOCUSED)){
                  GOLSetFocus((OBJ_HEADER*)pB);
                  }
                  }
                  #endif
                  #endif

                  switch(translatedMsg){

                  case BTN_MSG_PRESSED:
                  SetState(pB, BTN_PRESSED|BTN_DRAW); // set pressed and redraw
                  break;

                  case BTN_MSG_RELEASED:
                  ClrState(pB, BTN_PRESSED); // reset pressed
                  SetState(pB, BTN_DRAW); // redraw
                  break;

                  }

                  }

                  /************************************************** *******************
                  * Function: WORD BtnTranslateMsg(BUTTON *pB, GOL_MSG *pMsg)
                  *
                  *
                  * Notes: Evaluates the message if the object will be affected by the
                  * message or not.
                  *
                  ************************************************** ******************/
                  WORD BtnTranslateMsg(BUTTON *pB, GOL_MSG *pMsg)
                  {
                  // Evaluate if the message is for the button
                  // Check if disabled first
                  if (GetState(pB,BTN_DISABLED))
                  return OBJ_MSG_INVALID;

                  #ifdef USE_TOUCHSCREEN

                  if(pMsg->type == TYPE_TOUCHSCREEN){
                  // Check if it falls in the button's face
                  if( (pB->left < pMsg->param1) &&
                  (pB->right > pMsg->param1) &&
                  (pB->top < pMsg->param2) &&
                  (pB->bottom > pMsg->param2) ){

                  if(GetState(pB, BTN_TOGGLE)) {
                  if(pMsg->uiEvent == EVENT_RELEASE) {
                  if(GetState(pB, BTN_PRESSED))
                  return BTN_MSG_RELEASED;
                  else
                  return BTN_MSG_PRESSED;
                  }
                  }
                  else {
                  if(pMsg->uiEvent == EVENT_RELEASE)
                  return BTN_MSG_RELEASED;
                  if(!GetState(pB,BTN_PRESSED))
                  return BTN_MSG_PRESSED;
                  }

                  }else{
                  if(!GetState(pB, BTN_TOGGLE)) {
                  if(GetState(pB,BTN_PRESSED))
                  return BTN_MSG_RELEASED;
                  }
                  }

                  return OBJ_MSG_INVALID;
                  }

                  #endif


                  #ifdef USE_KEYBOARD

                  if(pMsg->type == TYPE_KEYBOARD){
                  if(pMsg->param1 == pB->ID){
                  if(pMsg->uiEvent == EVENT_KEYSCAN){
                  if((pMsg->param2 == SCAN_SPACE_PRESSED)||
                  (pMsg->param2 == SCAN_CR_PRESSED) ){
                  return BTN_MSG_PRESSED;
                  }
                  if((pMsg->param2 == SCAN_SPACE_RELEASED)||
                  (pMsg->param2 == SCAN_CR_RELEASED) ){
                  return BTN_MSG_RELEASED;
                  }
                  }
                  }
                  return OBJ_MSG_INVALID;
                  }

                  #endif

                  return OBJ_MSG_INVALID;
                  }

                  /************************************************** *******************
                  * Function: WORD BtnDraw(BUTTON *pB)
                  *
                  *
                  * Notes: This is the state machine to draw the button.
                  *
                  ************************************************** ******************/
                  WORD BtnDraw(BUTTON *pB)
                  {
                  typedef enum {
                  REMOVE,
                  BEVEL_DRAW,
                  RNDBUTTON_DRAW,
                  TEXT_DRAW,
                  TEXT_DRAW_RUN,
                  FOCUS_DRAW,
                  } BTN_DRAW_STATES;

                  static BTN_DRAW_STATES state = REMOVE;
                  static SHORT width, height, radius;

                  WORD faceClr, embossLtClr, embossDkClr, xText, yText;

                  if(IsDeviceBusy())
                  return 0;

                  switch(state){

                  case REMOVE:

                  if(IsDeviceBusy())
                  return 0;

                  if (GetState(pB,BTN_HIDE)) { // Hide the button (remove from screen)
                  SetColor(pB->pGolScheme->CommonBkColor);
                  Bar(pB->left, pB->top, pB->right, pB->bottom);
                  return 1;
                  }
                  /* Note: that width and height adjustment considers the following assumptions:
                  1. if circular width = height = radius*2
                  2. if vertical capsule width = radius*2
                  3. if horizontal capsule height = radius*2
                  4. radius must be less than or equal to width if height is greater than width
                  5. radius must be less than or equal to height if width is greater than height
                  6. if button is cornered, radius must be zero
                  */
                  radius = pB->radius; // get radius
                  width = (pB->right - pB->left) - (radius*2); // get width
                  height = (pB->bottom - pB->top) - (radius*2); // get height
                  state = BEVEL_DRAW;

                  case BEVEL_DRAW:
                  if(!GetState(pB,BTN_DISABLED)){
                  if(GetState(pB,BTN_PRESSED)){
                  embossDkClr = pB->pGolScheme->EmbossLtColor;
                  embossLtClr = pB->pGolScheme->EmbossDkColor;
                  faceClr = pB->pGolScheme->Color1;
                  } else {
                  embossLtClr = pB->pGolScheme->EmbossLtColor;
                  embossDkClr = pB->pGolScheme->EmbossDkColor;
                  faceClr = pB->pGolScheme->Color0;
                  }
                  }else{
                  embossLtClr = pB->pGolScheme->EmbossLtColor;
                  embossDkClr = pB->pGolScheme->EmbossDkColor;
                  faceClr = pB->pGolScheme->ColorDisabled;
                  }
                  GOLPanelDraw(pB->left+radius, pB->top+radius, pB->right-radius,
                  pB->bottom-radius, radius, faceClr, embossLtClr, embossDkClr,
                  pB->pBitmap, GOL_EMBOSS_SIZE);
                  state = RNDBUTTON_DRAW;

                  case RNDBUTTON_DRAW:

                  if(!GOLPanelDrawTsk()){
                  return 0;
                  }
                  state = TEXT_DRAW;

                  case TEXT_DRAW:
                  if (pB->pText != NULL){
                  if (!GetState(pB,BTN_DISABLED)){
                  if (GetState(pB,BTN_PRESSED)){
                  SetColor(pB->pGolScheme->TextColor1);
                  }else{
                  SetColor(pB->pGolScheme->TextColor0);
                  }
                  }
                  else{
                  SetColor(pB->pGolScheme->TextColorDisabled);
                  }
                  SetFont(pB->pGolScheme->pFont);
                  // check text alignment
                  if (GetState(pB, BTN_TEXTRIGHT))
                  xText = pB->right-(pB->textWidth+GOL_EMBOSS_SIZE+2);
                  else if (GetState(pB, BTN_TEXTLEFT))
                  xText = pB->left+GOL_EMBOSS_SIZE+2;
                  else
                  xText = (pB->left+pB->right-pB->textWidth)>>1;

                  if (GetState(pB, BTN_TEXTTOP))
                  yText = pB->top+GOL_EMBOSS_SIZE+2;
                  else if (GetState(pB, BTN_TEXTBOTTOM))
                  yText = pB->bottom-(pB->textHeight+GOL_EMBOSS_SIZE+2);
                  else
                  yText = (pB->bottom+pB->top-pB->textHeight)>>1;

                  MoveTo(xText, yText);
                  state = TEXT_DRAW_RUN;
                  }else {
                  state = FOCUS_DRAW;
                  goto rnd_button_draw_focus;
                  }

                  case TEXT_DRAW_RUN:
                  if(!OutText(pB->pText))
                  return 0;
                  state = FOCUS_DRAW;

                  case FOCUS_DRAW:
                  rnd_button_draw_focus:
                  if(IsDeviceBusy())
                  return 0;

                  if(GetState(pB,BTN_FOCUSED)){
                  SetLineType(FOCUS_LINE);
                  if(GetState(pB,BTN_PRESSED)) {
                  SetColor(pB->pGolScheme->TextColor1);
                  } else {
                  SetColor(pB->pGolScheme->TextColor0);
                  }
                  // check if the object has rounded corners or not
                  if (!pB->radius) {
                  Rectangle( pB->left+GOL_EMBOSS_SIZE+2 , pB->top+GOL_EMBOSS_SIZE+2,
                  pB->right-GOL_EMBOSS_SIZE-2, pB->bottom-GOL_EMBOSS_SIZE-2);
                  }
                  else {
                  // original center is still the same, but radius is reduced
                  Bevel( pB->left+radius, pB->top+radius, \
                  pB->right-radius, pB->bottom-radius, \
                  radius - 2 - GOL_EMBOSS_SIZE);
                  }
                  SetLineType(SOLID_LINE);
                  }

                  state = REMOVE;
                  return 1;
                  }
                  return 1;
                  }

                  #endif // USE_BUTTON
                  [/tt]

                  دیدگاه


                    #24
                    پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

                    البته این applib فقط gui نداره. کلی آت و آشغال قشنگ دیگه هم همراهش هست. فکر میکنم کلی بدرد میخوره. حتما دانلودش کنین.
                    اینم آدرس فایل اصلیش. منتهی از اون طرف ف ی ل ت ر ه.
                    http://ww1.microchip.com/downloads/en/DeviceDoc/MCHP_App_Lib_v2010_10_19_Installer.zip

                    دیدگاه


                      #25
                      پاسخ : ایجاد رابط کاربری گرافیکی (GUI) برای N96 LCD

                      با سلام
                      دوستان گرامیومن خیلی خیلی دوست دارم در این زمینه کار کنم.اما هیچ اطلاعاتی در این زمینه ندارم.لذا اگه ممکنه یه روند واسه یادگیری و کار در این موضوع بهم بگین.
                      چون خودم یه پروژه داشتم که میخواستم همچین کاری نیز بکنمواما نمیدونستم باید چیکار کنم و الان که دیدم بیشتر علاقه مند شدم.

                      دیدگاه

                      لطفا صبر کنید...
                      X