Files
libgphoto2/camlibs/CONFIG_DIALOG

360 lines
10 KiB
Plaintext

/* Widget Data Structures
--------------------------------------------------------------- */
typedef enum {
WIDGET_WINDOW,
WIDGET_PAGE,
WIDGET_TEXT,
WIDGET_RANGE,
WIDGET_TOGGLE,
WIDGET_RADIO,
WIDGET_MENU,
WIDGET_BUTTON,
WIDGET_NONE
} CameraWidgetType;
#define CameraWidgetCallback(_a) int (*_a) (CameraWidget *widget)
typedef struct {
/* Publicly accessible
------------------------------ */
WidgetType type;
char label[32];
/* Current value of the widget */
char value_string[32];
float value_number;
/* For Radio and Menu */
char choice[32];
/* For Range */
float min;
float max;
float step
/* Function Callback */
CameraWidgetCallback(callback);
/* Private (don't access)
------------------------------ */
CameraWidget *children;
int children_count;
} CameraWidget;
/* Widget API
--------------------------------------------------------------- */
CameraWidget* gp_widget_new(CameraWidgetType type, char *label);
/* Create a new widget */
int gp_widget_append(CameraWidget *parent, CameraWidget *child);
int gp_widget_prepend(CameraWidget *parent, CameraWidget *child);
/* Add a child widget to the parent widget */
int gp_widget_child_count(CameraWidget *parent);
/* Retrieve the number of children a parent has */
CameraWidget* gp_widget_child(CameraWidget *parent, int child_number);
/* Retrieve a pointer to a child #child_number of the parent */
int gp_widget_free(CameraWidget *widget);
/* Frees a widget, as well as all the children */
Then, you can build an interface in the library, and set the initial values and pass that
back to the front-end.
now, the library can make decisions as to what widgets to show depending on the camera
model. BUT, (the big but), it adds to the complexity in the libraries. we've always been
trying to find the trade-off between complexity of the camera library API and the ease of
creating a camera library.
The camera_config_get() function would be passed in a CameraWidget pointer tho the
top-level window.
here is an example config_get function:
int camera_config_get (CameraWidget *window) {
CameraWidget *t, *page;
int num;
char buf[1024];
/* set the window label to something more specific */
strcpy(window->label, "Fujitsu Camera Settings");
/* Create a new page for "Quality" */
page = gp_widget_new(WIDGET_PAGE, "Quality");
/* Add the page to the window */
gp_widget_add(window, page);
/* Get the current camera resolution setting */
num = fujitstu_setting_int(FUJITSU_RESOLUTION);
/* returns 0,1, or 2 */
/* Add the Resolution setting radio buttons */
t = gp_widget_new(WIDGET_RADIO, "Resolution");
strcpy(t->choice, "Standard");
if (num == 0) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_RADIO, "Resolution");
strcpy(t->choice, "High");
if (num == 1) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_RADIO, "Resolution");
strcpy(t->choice, "Best");
if (num == 2) {t->value_number = 1;}
gp_widget_append(page, t);
/* Don't show the compression settings if current model
is D220-L because it doesn't support it */
if (strcmp(current_camera, "olympus D220-L")!=0) {
/* Get the current camera compression setting */
num = fujitstu_setting_int(FUJITSU_COMPRESSION);
/* returns 0,1, or 2 */
/* Add the Compression setting radio buttons */
t = gp_widget_new(WIDGET_RADIO, "Compression");
strcpy(t->choice, "None");
if (num == 0) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_RADIO, "Compression");
strcpy(t->choice, "Low");
if (num == 1) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_RADIO, "Compression");
strcpy(t->choice, "High");
if (num == 2) {t->value_number = 1;}
gp_widget_append(page, t);
}
/* Create a new page for "Flash/Lens" */
page = gp_widget_new(WIDGET_PAGE, "Flash/Lens");
/* Add the page to the window */
gp_widget_add(window, page);
/* Get the current camera flash setting */
num = fujitstu_setting_int(FUJITSU_FLASH);
/* returns 0,1,2, or 3 */
t = gp_widget_new(WIDGET_MENU, "Flash Setting");
strcpy(t->choice, "Auto");
if (num == 0) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_MENU, "Flash Setting");
strcpy(t->choice, "Red-eye");
if (num == 1) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_MENU, "Flash Setting");
strcpy(t->choice, "Force");
if (num == 2) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_MENU, "Flash Setting");
strcpy(t->choice, "None");
if (num == 3) {t->value_number = 1;}
gp_widget_append(page, t);
/* Get the current camera lens setting */
num = fujitstu_setting_int(FUJITSU_LENS);
/* returns 0, or 1 */
t = gp_widget_new(WIDGET_RADIO, "Lens Mode");
strcpy(t->choice, "Normal");
if (num == 0) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_RADIO, "Lens Mode");
strcpy(t->choice, "Macro");
if (num == 1) {t->value_number = 1;}
gp_widget_append(page, t);
t = gp_widget_new(WIDGET_RANGE, "Zoom");
t->min = 28.0;
t->max = 135.0;
t->step = 1.0;
t->value_number = (float)fujitsu_setting_int(FUJITSU_ZOOM);
gp_widget_append(page, t);
return (GP_OK);
}
--------=-=-=-=------------------ - - - - - ------------------------
don't reference below here. this was only a spec. :P
--------=-=-=-=------------------ - - - - - ------------------------
Old Specification
-----------------
This is simply a draft for the configuration dialog spec for the camera
libraries. Please ask questions if something doesn't jive or sucks.
-Scott <scottf@unr.edu>
Configuration dialog widgets
============================================================================
Notebook page:
label: (string) Descriptive label displayed on notebook tab
default="Page #"
example:
<page label="General Settings">
<... other widgets ...>
</page>
Text input:
label: (string) Descriptive label displayed beside widget
example:
<text label="Camera ID"/>
Range input:
label: (string) Descriptive label displayed beside widget
min: (int) Minimum range value
max: (int) Maximum range value
example:
<range label="Timeout" min="0" max="255"/>
Toggle input:
label: (string) Descriptive label displayed beside widget
example:
<toggle label="Enable Flash"/>
Radio buttons:
label: (string) Descriptive label displayed beside widget (used to group buttons)
choice: (string) The individual choices in the radio button array
example:
<radio label="Image Quality" choice="High"/>
<radio label="Image Quality" choice="Medium"/>
<radio label="Image Quality" choice="Low"/>
Drop-down menu:
label: (string) Descriptive label displayed beside widget (used to group entries)
choice: (string) The individual choices in the radio button array
example:
<menu label="Port" choice="Serial Port 1"/>
<menu label="Port" choice="Serial Port 2"/>
<menu label="Port" choice="Serial Port 3"/>
<menu label="Port" choice="Serial Port 4"/>
Button input:
label: (string) Descriptive label displayed on button
callback: (string) Name of a function in library to call when pressed.
Function prototype is: int function();
Returns GP_OK or GP_ERROR.
example:
<button label="Take Picture" callback="camera_take_picture"/>
Control statements
============================================================================
The "if" statement (maybe):
logic: (string) Either "and", "or", or "not"
default = "and"
Available variables:
camera
port
? any others needed
* implicit AND with listed
* preceed variables with a ! to signal NOT
* no nesting of logic operators or <if> statements.
* maybe regular expressions?
<if logic="and" camera="Olympus D-220L" port="usb">
<... put D-220L-specific widgets here ...>
</if>
<if camera="!Nikon 990">
<... put widgets that shouldn't be displayed with Nikon 990 ...>
</if>
Example
============================================================================
<page label="Quality">
<radio label="Resolution" choice="Standard"/>
<radio label="Resolution" choice="High"/>
<radio label="Resolution" choice="Best"/>
<radio label="Compression" choice="None"/>
<radio label="Compression" choice="Low"/>
<radio label="Compression" choice="High"/>
</page>
<page label="Focus/Lens">
<menu label="Flash type" choice="Auto"/>
<menu label="Flash type" choice="Red-eye"/>
<menu label="Flash type" choice="Force"/>
<menu label="Flash type" choice="None"/>
<radio label="Lens Mode" choice="Normal"/>
<radio label="Lens Mode" choice="Macro"/>
</page>
<page label="Power Saving">
<range label="Docked" min="0" max="600"/>
<range label="Undocked" min="0" max="180"/>
</page>
<page label="Miscellaneous">
<text label="Camera ID"/>
<range label="LCD Brightness" min="0" max="7"/>
</page>
NOTES
============================================================================
* The files are read as streams. so, a tag can be multi-lined, like:
<if logic="or"
camera="Olympus D-220L"
camera="Olympus D-360L"
camera="Olympus D-620L"
camera="Olympus C-2500L">
<... widgets for any of the cameras ...>
</if>
makes it a little easier to read and/or follow.
* The front-end will query the camera library about what the values should be
using camera_config_query(). In the example above, to ask which radio button should
be chosen for "Resolution", the front-end will call (psuedo-code):
gp_config_query("Resolution", value);
if value == "Standard"
select "Standard" button
if value == "High"
select "High" button
... and so on
this requires a clever interface builder. easiest way is to keep track of each toolkit widget
created for the configuration dialog, and attach the 'label' name to it. then, when its
time to set the configuration dialog to reflect the current camera settings, find that
toolkit widget and make a call to 'click' that widget.
When all is done, display the configuration dialog. Or, bring up the dialog and put a button in
it saying "get camera settings" or something.
* Interfaces should wait to close the configuration dialog until gp_config_set returns.
If GP_OK is returned, close the window.
If GP_ERROR is returned, it is expected that the camera libraries have already notified
the user of an error by using gp_message(). Leave the window open so they can make the necessary
changes.