git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@611 67ed7778-7388-44ab-90cf-0a291f65f57c
360 lines
10 KiB
Plaintext
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.
|