⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appuifwmodule.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
* ====================================================================
*  appuifwmodule.cpp
*
*  Python API to Series 60 application UI framework facilities
*
*  Implements currently (16.03.05) following Python types and functions:
*
*  Application (an implicit instance "app" always present)
*    unicode full_name()
*    set_tabs(list<unicode>, callable)
*    activate_tab(int)
*    set_exit()
*    callable exit_key_handler
*    list<tuple<unicode, callable>> menu
*    ui_control body
*    unicode title
*    mode screen
*    callable(focus) focus
*    layout(int)
*
*  Listbox
*    Listbox(list<unicode OR tuple<unicode, unicode>>, callable)
*    int current()
*    set_list(list<unicode OR tuple<unicode, unicode>>, [int])
*    bind(event_code, callable)
*
*  Form
*    Form(list<tuple<unicode, string, unicode>>, int)
*    execute()
*    add_menu_item()
*    insert(), pop(), sequence methods: length, item, assignment
*
*  Text
*    unicode get()
*    set(unicode)
*    add(unicode)
*    int len()
*    clear()
*    set_pos(int)
*    int get_pos()
*    bind(event_code, callable)
*    bool focus
*  attributes:
*    focus
*    style
*    color
*    highlight_color
*    font
*
*  Canvas
*    line((x1,y1),(x2,y2),(r,g,b))
*     - draw line from (x1,y1) to (x2,y2) with color (r,g,b)
*    rectfill((x1,y1),(x2,y2),(r,g,b))
*     - fill rectangle with corners at (x1,y1) and (x2,y2) with color (r,g,b)
*    clear([(r,g,b)])
*     - clear entire canvas to white or to given color
*    text((x,y),unicode,(r,g,b))
*     - draw text to (x,y) with given color
*    bind(event_code, callable)
*    CObject _ccoecontrol()
*     - return the pointer to the canvas CCoeControl as CObject
*  attributes:
*    draw (read/write)
*     - called when refreshing the display is needed with parameters:
*       (Canvas,((x1,y1),(x2,y2)))
*    resize (read/write)
*     - called when the canvas is resized with Canvas as parameter
*     
*  Content_handler
*    Content_handler([callable])
*    open(unicode OR string) 
*    open_standalone(unicode OR string)
*
*  int selection_list(list<unicode> [, int])
*
*  tuple<int> multi_selection_list(list<unicode> [, string, int])
*
*  <query_result_type> query(unicode, string [,<initial_value>])
*
*  note(unicode, string)           
*
*  (unicode, unicode)
*  multi_query(unicode, unicode)
*
*  int popup_menu(list<unicode OR tuple<unicode, unicode>>, [unicode])
*
*  list<unicode> available_fonts()
*
*
* Copyright (c) 2005-2007 Nokia Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/

#include "appuifwmodule.h"
#include "appuifw_callbacks.h"
#include "colorspec.cpp"
// Yuck. This is ugly but will do for now until a better solution is implemented 
// for shared functionality between appuifw and graphics modules. Perhaps they
// should just be merged?
#include "../../ext/graphics/fontspec.cpp"

#if SERIES60_VERSION>=28
#include "akniconutils.h"
#include "GULICON.H"
#define SCALABLE_UI
#endif /* SERIES60_VERSION */

#define UICONTROLAPI_NAME "_uicontrolapi"

struct Application_data {
  Application_data(CAmarettoAppUi* aAppUi, Application_object* aOp):
    appui(aAppUi), ob_exit_key_cb(aOp,aAppUi), ob_event_cb(aOp,aAppUi),
    ob_command_cb(aOp,aAppUi), ob_menu_cb(aOp,aAppUi),
    ob_tab_cb(aOp,aAppUi), ob_focus_cb(aOp,aAppUi)
  {
    rsc_offset = (-1);
    appui->SetMenuDynInitFunc(&(ob_menu_cb));
    appui->SetMenuCommandFunc(&(ob_command_cb));
  }
  ~Application_data() {
    if (rsc_offset != (-1))
      (CEikonEnv::Static())->DeleteResourceFile(rsc_offset);
    appui->SetMenuDynInitFunc(NULL);
    appui->SetMenuCommandFunc(NULL);
    appui->SetExitFunc(NULL);
    appui->SetHostedControl(NULL, NULL);
    appui->SetFocusFunc(NULL);
  }

  CAmarettoAppUi* appui;
  TInt rsc_offset;
  CAppuifwExitKeyCallback ob_exit_key_cb;
  CAppuifwEventCallback ob_event_cb;
  CAppuifwCommandCallback ob_command_cb;
  CAppuifwMenuCallback ob_menu_cb;
  CAppuifwTabCallback ob_tab_cb;
  CAppuifwFocusCallback ob_focus_cb;
};

/*
 * An utility for obtaining the Application object
 */

static Application_object* get_app()
{
  PyInterpreterState *interp = PyThreadState_Get()->interp;
  PyObject* m = PyDict_GetItemString(interp->modules, "_appuifw");
  
  return (Application_object*)PyDict_GetItemString(PyModule_GetDict(m),
                                                   "app");
}

/* A function that is used with CAsyncCallBack.
 * It is called to destroy the object after
 * UI processing is done.
 */

TInt decrefObject(TAny* aObj)
{
  PyEval_RestoreThread(PYTHON_TLS->thread_state);
  Py_DECREF((PyObject*)aObj);
  PyEval_SaveThread();
  return 1;
}

/*
 * A helper function for the implementation of callbacks
 * from C/C++ code to Python callables
 */

TInt app_callback_handler(TAny* func)
{
  // Strictly speaking this violates the Python/C API spec.
  // We should pass an empty tuple instead of NULL.
  return app_callback_handler(func, NULL);
}

TInt app_callback_handler(TAny* func, TAny* arg)
{
  TInt error = KErrNone;
  
  PyObject* rval = PyEval_CallObject((PyObject*)func, (PyObject*)arg);
  
  if (!rval) {
    error = KErrPython;
    if (PyErr_Occurred() == PyExc_OSError) {
      PyObject *type, *value, *traceback;
      // Note that PyErr_Fetch gives us ownership of these objects, so
      // we must remember to DECREF them.
      PyErr_Fetch(&type, &value, &traceback); 
      if (PyInt_Check(value))
        error = PyInt_AS_LONG(value);
      Py_XDECREF(type);
      Py_XDECREF(value);
      Py_XDECREF(traceback);
    } else {
      PyErr_Print();
    }
  }
  else
    Py_DECREF(rval);

  return error;
}

TInt 
AppuifwControl_Check(PyObject *obj) 
{
  return (AppuifwControl_AsControl(obj))?1:0;
}

struct _control_object *
AppuifwControl_AsControl(PyObject *obj)
{
  PyObject *controlapi_cobject=NULL;
  if (!(controlapi_cobject=PyObject_GetAttrString(obj, UICONTROLAPI_NAME)) ||
      !(PyCObject_Check(controlapi_cobject))) {
    Py_XDECREF(controlapi_cobject);
    return NULL;
  }
  struct _control_object *control_object=
    (struct _control_object *)PyCObject_AsVoidPtr(controlapi_cobject);
  Py_DECREF(controlapi_cobject);
  return control_object;
}

static void _uicontrolapi_decref(void *control_obj)
{
  Py_DECREF((PyObject *)control_obj);
}


/*
 * Implementation of appuifw.Application (an implicit instance
 * of this type with name "app" comes with this module, new
 * instances can not be created from Python)
 */

extern "C" {static void application_dealloc(Application_object *op);}

/* 
 * SPy_S60app_New() -- C API only! 
 */

extern "C" PyObject *
SPy_S60app_New()          
{
  Application_object *op = PyObject_New(Application_object,
                                        &Application_type);
  if (op == NULL)
    return PyErr_NoMemory();

  op->ob_dict_attr = NULL;
  op->ob_menu = NULL;
  op->ob_body = Py_None;
  Py_INCREF(Py_None);
  op->ob_title = NULL;
  op->ob_screen = Py_BuildValue("s", "normal");
  op->ob_data = NULL;

#ifdef EKA2
  op->ob_orientation = Py_BuildValue("s", "automatic");
#endif
  CEikonEnv* env = CEikonEnv::Static();
  CAmarettoAppUi* appui = STATIC_CAST(CAmarettoAppUi*, env->EikAppUi());

  TInt error;
  const TDesC* title;
  TRAP(error,
       (title =
        ((CAknTitlePane*)
         ((env->AppUiFactory()->StatusPane())->
          ControlL(TUid::Uid(EEikStatusPaneUidTitle))))->Text())
       );

  if (error != KErrNone) {
    application_dealloc(op);
    return SPyErr_SetFromSymbianOSErr(error);
  }

  if (!(op->ob_title =
        PyUnicode_FromUnicode(title->Ptr(), title->Length())) ||
      (!(op->ob_data = new Application_data(appui, op))) ||
      (!(op->ob_menu = PyList_New(0)))) {
    application_dealloc(op);
    return NULL;
  }
  
  TParse f;
  TFileName fn = op->ob_data->appui->Application()->AppFullName();
  f.Set(KAppuiFwRscFile, &fn, NULL);
  TRAP(error,
       (op->ob_data->rsc_offset = env->AddResourceFileL(f.FullName())));

  if (error != KErrNone) {
    application_dealloc(op);
    return SPyErr_SetFromSymbianOSErr(error);
  }
  
  return (PyObject *) op;
}

extern "C" PyObject *
app_full_name(Application_object *self)
{
  TFileName n = ((self->ob_data)->appui)->Application()->AppFullName();

  return Py_BuildValue("u#", n.Ptr(), n.Length());
}

extern "C" PyObject *
app_uid(Application_object *self)
{
  TUid uid = ((self->ob_data)->appui)->Application()->AppDllUid();
  TBuf<KMaxUidName> uidName(uid.Name());

  uidName.Delete(KMaxUidName-1,1);
  uidName.Delete(0,1);
  
  return Py_BuildValue("u#", uidName.Ptr(), uidName.Length());
}

extern "C" PyObject *
app_set_tabs(Application_object *self, PyObject *args)
{
  TInt error = KErrNone;
  PyObject* list;
  PyObject* cb;

  if (!PyArg_ParseTuple(args, "O!O", &PyList_Type, &list, &cb))
    return NULL;

  int sz = PyList_Size(list);

  if ((sz > 1) && !PyCallable_Check(cb)) {
    PyErr_SetString(PyExc_TypeError, "callable expected");
    return NULL;
  }

  CDesCArray *tab_text_list = NULL;
  if (sz > 1) {
    if (!(tab_text_list = new CDesCArrayFlat(sz)))
      return PyErr_NoMemory();
    
    for (int i = 0; i < sz; i++) {
      PyObject* s = PyList_GetItem(list, i);
      if (!PyUnicode_Check(s))
        error = KErrArgument;
      else {
        TPtr buf(PyUnicode_AsUnicode(s), PyUnicode_GetSize(s),
                 PyUnicode_GetSize(s));
        TRAP(error, tab_text_list->AppendL(buf));
      }
      if (error != KErrNone)
        break;
    }
  }
  else
    cb = Py_None;

  if (error == KErrNone) {
    self->ob_data->ob_tab_cb.Set(cb);
    Py_BEGIN_ALLOW_THREADS
    error = self->ob_data->appui->EnableTabs(tab_text_list,
                                             &self->ob_data->ob_tab_cb);
    Py_END_ALLOW_THREADS
  }

  delete tab_text_list;

  RETURN_ERROR_OR_PYNONE(error);
}

extern "C" PyObject *
app_activate_tab(Application_object *self, PyObject *args)
{
  TInt index;
  
  if (!PyArg_ParseTuple(args, "i", &index))
    return NULL;
  
  Py_BEGIN_ALLOW_THREADS
  self->ob_data->appui->SetActiveTab(index);
  Py_END_ALLOW_THREADS

  Py_INCREF(Py_None);
  return Py_None;
}

#if SERIES60_VERSION>=28
extern "C" PyObject *
app_layout(Application_object *self, PyObject *args)
{
  TInt layout = 0;
  TRect rect; 
  TBool available = EFalse;
  
  if (!PyArg_ParseTuple(args, "i", &layout))
    return NULL;
  
  available = AknLayoutUtils::LayoutMetricsRect((AknLayoutUtils::TAknLayoutMetrics)layout, rect);
  
  if(available) {
    // size, position:
    return Py_BuildValue("((ii),(ii))", rect.Width(), 
                                        rect.Height(),
                                        rect.iTl.iX,
                                        rect.iTl.iY
                                        );
  } else {
    PyErr_SetString(PyExc_ValueError, "unknown layout");
    return NULL;
  }
}
#endif /* SERIES60_VERSION */

extern "C" PyObject *
app_set_exit(Application_object *self, PyObject* /*args*/)
{
  self->ob_data->appui->SetExitFlag();

  Py_INCREF(Py_None);
  return Py_None;
}

extern "C" {

  static void
  application_dealloc(Application_object *op)
  {
    delete op->ob_data;
    op->ob_data = NULL;
    Py_XDECREF(op->ob_dict_attr);
    Py_XDECREF(op->ob_menu);
    Py_XDECREF(op->ob_body);
    Py_XDECREF(op->ob_title);
    Py_XDECREF(op->ob_screen);
#ifdef EKA2
    Py_XDECREF(op->ob_orientation);
#endif
    PyObject_Del(op);
  }

  static const PyMethodDef application_methods[] = {
    {"set_exit", (PyCFunction)app_set_exit, METH_NOARGS},
    {"full_name", (PyCFunction)app_full_name, METH_NOARGS},
    {"uid", (PyCFunction)app_uid, METH_NOARGS},
    {"set_tabs", (PyCFunction)app_set_tabs, METH_VARARGS},
    {"activate_tab", (PyCFunction)app_activate_tab, METH_VARARGS},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -