Index: exposurses.c ================================================================== --- exposurses.c +++ exposurses.c @@ -1,499 +1,499 @@ -/* This file based on menu_scroll.c from: -http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/intro.html */ -#include -#include -#include -#include - -/* Learning notes - This is a macro that is expanded (text substitution) before compiling */ -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -char *exposure_array[] = { - "-6", - "-5", - "-4", - "-3", - "-2", - "-1", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - NULL -}; - -char *iso_array[] = { - "50", - "100", - "200", - "400", - "800", - "1600", - "3200", - NULL -}; - -char *shutter_array[] = { - "OVER", - "1/1000", - "1/500", - "1/250", - "1/125", - "1/60", - "1/30", - "1/15", - "1/8", - "1/4", - "1/2", - "1", - "UNDER", - NULL -}; - -char *aperture_array[] = { - "UNDER", - "f/1.4", - "f/2", - "f/2.8", - "f/4", - "f/5.6", - "f/8", - "f/11", - "f/16", - "OVER", - NULL -}; - -ITEM **exposure_items; -ITEM **iso_items; -ITEM **shutter_items; -ITEM **aperture_items; -MENU *exposure_menu; -MENU *iso_menu; -MENU *shutter_menu; -MENU *aperture_menu; -WINDOW *exposure_win; -WINDOW *iso_win; -WINDOW *shutter_win; -WINDOW *aperture_win; - -void selection(char *name); -void remove_menu(ITEM **items, MENU *men, int n); -void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color); -MENU *add_menu(ITEM **items); -WINDOW *add_window(int xpos, char *title); -ITEM **add_item(char **array, int n); -int exposure(int iso); -double shutter(int exposure, double aperture); -double aperture(int exposure, double shutter); -int nearest_match(double x, int menu, int n_array); -double fraction_to_double(char *fraction); -/* No one will ever need more than 9 bytes! */ -char exposure_sel[9] = ""; -char iso_sel[9] = ""; -char shutter_sel[9] = ""; -char aperture_sel[9] = ""; -int selection_counter = 1; -int menu_counter = 1; - -int main() { - int c; - MENU **menu; - WINDOW **win; - int i; - int n_exposure; - int n_iso; - int n_shutter; - int n_aperture; - - /* Initialize curses */ - initscr(); - start_color(); - cbreak(); - noecho(); - keypad(stdscr, TRUE); - init_pair(1, COLOR_RED, COLOR_BLACK); - init_pair(2, COLOR_CYAN, COLOR_BLACK); - - /* Create items */ - /* Can't really avoid finding array sizes here */ - n_exposure = ARRAY_SIZE(exposure_array); - n_iso = ARRAY_SIZE(iso_array); - n_shutter = ARRAY_SIZE(shutter_array); - n_aperture = ARRAY_SIZE(aperture_array); - exposure_items = add_item(exposure_array, n_exposure); - iso_items = add_item(iso_array, n_iso); - aperture_items = add_item(aperture_array, n_aperture); - shutter_items = add_item(shutter_array, n_shutter); - exposure_menu = add_menu(exposure_items); - iso_menu = add_menu(iso_items); - shutter_menu = add_menu(shutter_items); - aperture_menu = add_menu(aperture_items); - exposure_win = add_window(4, "EV"); - iso_win = add_window(45, "ISO"); - shutter_win = add_window(86, "Shutter"); - aperture_win = add_window(127, "Aperture"); - /* Don't know how to avoid the repition below */ - set_menu_win(exposure_menu, exposure_win); - set_menu_win(iso_menu, iso_win); - set_menu_win(shutter_menu, shutter_win); - set_menu_win(aperture_menu, aperture_win); - set_menu_sub(exposure_menu, derwin(exposure_win, 6, 38, 3, 1)); - set_menu_sub(iso_menu, derwin(iso_win, 6, 38, 3, 1)); - set_menu_sub(shutter_menu, derwin(shutter_win, 6, 38, 3, 1)); - set_menu_sub(aperture_menu, derwin(aperture_win, 6, 38, 3, 1)); - post_menu(exposure_menu); - post_menu(iso_menu); - post_menu(shutter_menu); - post_menu(aperture_menu); - wrefresh(exposure_win); - wrefresh(iso_win); - wrefresh(shutter_win); - wrefresh(aperture_win); - attron(COLOR_PAIR(2)); - mvprintw(LINES - 2, 0, "Select EV"); - mvprintw(LINES - 1, 0, "Arrow keys to navigate, Enter to select, Q to exit"); - attroff(COLOR_PAIR(2)); - refresh(); - - /* Set default menu */ - menu = &exposure_menu; - win = &exposure_win; - - while((c = getch()) != 81) { /* 81 is Q */ - switch(c) { - case KEY_LEFT: - if (selection_counter > 2) { - menu_counter = 3; - menu = &shutter_menu; - win = &shutter_win; - } - break; - case KEY_RIGHT: - if (selection_counter > 2) { - menu_counter = 4; - menu = &aperture_menu; - win = &aperture_win; - } - break; - case KEY_DOWN: - menu_driver(*menu, REQ_DOWN_ITEM); - break; - case KEY_UP: - menu_driver(*menu, REQ_UP_ITEM); - break; - case 10: { /* ENTER */ - ITEM *cur; - void (*p)(char *); - - cur = current_item(*menu); - p = item_userptr(cur); - /* Learning notes - Don't understand this bit. Is this a function pointer? */ - p((char *)item_name(cur)); - /* Need to igore over/under if selected, probably easier than try to prevent selection */ - if (!((strcmp("OVER", shutter_sel) == 0) - || (strcmp("UNDER", shutter_sel) == 0) - || (strcmp("OVER", aperture_sel) == 0) - || (strcmp("UNDER", aperture_sel) == 0))) { - switch (selection_counter) { - case 1: { /* Exposure selected */ - selection_counter += 1; - menu_counter += 1; - move(LINES - 2, 0); - clrtoeol(); - mvprintw(LINES - 2, 0, "Select ISO"); - refresh(); - menu = &iso_menu; - win = &iso_win; - } - break; - case 2: { /* ISO Selected */ - selection_counter += 1; - menu_counter += 1; - move(LINES - 2, 0); - clrtoeol(); - mvprintw(LINES - 2, 0, "Select Shutter or Aperture"); - refresh(); - menu = &shutter_menu; - win = &shutter_win; - } - break; - case 3: { /* Shutter or Aperture selected */ - if (strcmp("", shutter_sel) == 0) { - char aperture_sel_[4] = ""; - strncpy(aperture_sel_, aperture_sel+2, 3); - /* Using menu_driver to go up/down to force refresh and correct highlighting */ - menu_driver(shutter_menu, REQ_SCR_UPAGE); - menu_driver(shutter_menu, REQ_SCR_DPAGE); - /* There is probably a nicer way to format the below */ - set_menu_pattern( - shutter_menu, - shutter_array[nearest_match( - shutter(exposure(atoi(iso_sel)), strtod(aperture_sel_, NULL)), - 3, - n_shutter - )] - ); - menu_driver(shutter_menu, REQ_DOWN_ITEM); - menu_driver(shutter_menu, REQ_UP_ITEM); - wrefresh(shutter_win); - } - if (strcmp("", aperture_sel) == 0) { - menu_driver(aperture_menu, REQ_SCR_UPAGE); - menu_driver(aperture_menu, REQ_SCR_DPAGE); - set_menu_pattern( - aperture_menu, - aperture_array[nearest_match( - aperture(exposure(atoi(iso_sel)), fraction_to_double(shutter_sel)), - 4, - n_aperture - )] - ); - menu_driver(aperture_menu, REQ_DOWN_ITEM); - menu_driver(aperture_menu, REQ_UP_ITEM); - wrefresh(aperture_win); - } - /* Clear the selections for next time */ - strcpy(iso_sel, ""); - strcpy(shutter_sel, ""); - strcpy(aperture_sel, ""); - /* And set defaults back to start */ - selection_counter = 1; - menu_counter = 1; - menu = &exposure_menu; - win = &exposure_win; - move(LINES - 2, 0); - clrtoeol(); - mvprintw(LINES - 2, 0, "Select EV"); - refresh(); - } - break; - } - } - /* If over/under need to clear selection so know which is blank when a proper selection is made */ - if ((strcmp("OVER", shutter_sel) == 0) || (strcmp("UNDER", shutter_sel) == 0)) { - strcpy(shutter_sel, ""); - } - if ((strcmp("OVER", aperture_sel) == 0) || (strcmp("UNDER", aperture_sel) == 0)) { - strcpy(aperture_sel, ""); - } - } - break; - } - wrefresh(*win); - } - /* Unpost and free all the memory taken up */ - remove_menu(exposure_items, exposure_menu, n_exposure); - remove_menu(iso_items, iso_menu, n_iso); - remove_menu(shutter_items, shutter_menu, n_shutter); - remove_menu(aperture_items, aperture_menu, n_aperture); - endwin(); -} - -/* Below pointer configuration figured out from: - * https://github.com/Yurickh/Psycho-Tetris/blob/master/src/menu.c#L9 */ -ITEM **add_item(char **array, int n) { - int i; - ITEM **local_items; - - local_items = (ITEM **)calloc(n, sizeof(ITEM *)); - for(i = 0; i= fraction_to_double(shutter_array[1])/2) { - /* diff is greater than diff of next one down minus max/min */ - diff_idx = 0; - } - } - if (diff_idx == n_array-3) { - if (diff >= fraction_to_double(shutter_array[n_array-3])*2) { - diff_idx = n_array-2; - } - } - break; - case 4: - for ( n = 2; n < n_array-2; ++n ) { - strncpy(array_value_str, aperture_array[n]+2, 4); - array_value_db = strtod(array_value_str, NULL); - if (fabs(array_value_db - x) < diff) { - diff_idx = n; - diff = fabs(array_value_db - x); - } - } - /* Apertures similarly. Although progression is fiddlier.*/ - if (diff_idx == 1) { - strncpy(array_value_str, aperture_array[1]+2, 4); - array_value_db = strtod(array_value_str, NULL); - if (diff >= array_value_db/sqrt(2.0)) { - /* diff is greater than diff of next one down minus max/min */ - diff_idx = 0; - } - } - if (diff_idx == n_array-3) { - strncpy(array_value_str, aperture_array[n_array-3]+2, 4); - array_value_db = strtod(array_value_str, NULL); - if (diff >= array_value_db*sqrt(2.0)) { - diff_idx = n_array-2; - } - } - - break; - } - return diff_idx; -} - -double fraction_to_double(char *fraction) { - double fraction_as_db; - char denominator[9]; - char *ptr = strstr(fraction, "/"); - - if (ptr) { - /*then split*/ - strncpy(denominator, fraction+2, 5); - fraction_as_db = 1 / strtod(denominator, NULL); - } - else { - fraction_as_db = strtod(fraction, NULL); - } - return fraction_as_db; -} - -/* Debug lines - * sprintf(temp, "%f", x); - * mvprintw(LINES - 4, 0, temp); - * refresh();*/ +/* This file based on menu_scroll.c from: +http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/intro.html */ +#include +#include +#include +#include + +/* Learning notes - This is a macro that is expanded (text substitution) before compiling */ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +char *exposure_array[] = { + "-6", + "-5", + "-4", + "-3", + "-2", + "-1", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + NULL +}; + +char *iso_array[] = { + "50", + "100", + "200", + "400", + "800", + "1600", + "3200", + NULL +}; + +char *shutter_array[] = { + "OVER", + "1/1000", + "1/500", + "1/250", + "1/125", + "1/60", + "1/30", + "1/15", + "1/8", + "1/4", + "1/2", + "1", + "UNDER", + NULL +}; + +char *aperture_array[] = { + "UNDER", + "f/1.4", + "f/2", + "f/2.8", + "f/4", + "f/5.6", + "f/8", + "f/11", + "f/16", + "OVER", + NULL +}; + +ITEM **exposure_items; +ITEM **iso_items; +ITEM **shutter_items; +ITEM **aperture_items; +MENU *exposure_menu; +MENU *iso_menu; +MENU *shutter_menu; +MENU *aperture_menu; +WINDOW *exposure_win; +WINDOW *iso_win; +WINDOW *shutter_win; +WINDOW *aperture_win; + +void selection(char *name); +void remove_menu(ITEM **items, MENU *men, int n); +void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color); +MENU *add_menu(ITEM **items); +WINDOW *add_window(int xpos, char *title); +ITEM **add_item(char **array, int n); +int exposure(int iso); +double shutter(int exposure, double aperture); +double aperture(int exposure, double shutter); +int nearest_match(double x, int menu, int n_array); +double fraction_to_double(char *fraction); +/* No one will ever need more than 9 bytes! */ +char exposure_sel[9] = ""; +char iso_sel[9] = ""; +char shutter_sel[9] = ""; +char aperture_sel[9] = ""; +int selection_counter = 1; +int menu_counter = 1; + +int main() { + int c; + MENU **menu; + WINDOW **win; + int i; + int n_exposure; + int n_iso; + int n_shutter; + int n_aperture; + + /* Initialize curses */ + initscr(); + start_color(); + cbreak(); + noecho(); + keypad(stdscr, TRUE); + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_CYAN, COLOR_BLACK); + + /* Create items */ + /* Can't really avoid finding array sizes here */ + n_exposure = ARRAY_SIZE(exposure_array); + n_iso = ARRAY_SIZE(iso_array); + n_shutter = ARRAY_SIZE(shutter_array); + n_aperture = ARRAY_SIZE(aperture_array); + exposure_items = add_item(exposure_array, n_exposure); + iso_items = add_item(iso_array, n_iso); + aperture_items = add_item(aperture_array, n_aperture); + shutter_items = add_item(shutter_array, n_shutter); + exposure_menu = add_menu(exposure_items); + iso_menu = add_menu(iso_items); + shutter_menu = add_menu(shutter_items); + aperture_menu = add_menu(aperture_items); + exposure_win = add_window(4, "EV"); + iso_win = add_window(45, "ISO"); + shutter_win = add_window(86, "Shutter"); + aperture_win = add_window(127, "Aperture"); + /* Don't know how to avoid the repition below */ + set_menu_win(exposure_menu, exposure_win); + set_menu_win(iso_menu, iso_win); + set_menu_win(shutter_menu, shutter_win); + set_menu_win(aperture_menu, aperture_win); + set_menu_sub(exposure_menu, derwin(exposure_win, 6, 38, 3, 1)); + set_menu_sub(iso_menu, derwin(iso_win, 6, 38, 3, 1)); + set_menu_sub(shutter_menu, derwin(shutter_win, 6, 38, 3, 1)); + set_menu_sub(aperture_menu, derwin(aperture_win, 6, 38, 3, 1)); + post_menu(exposure_menu); + post_menu(iso_menu); + post_menu(shutter_menu); + post_menu(aperture_menu); + wrefresh(exposure_win); + wrefresh(iso_win); + wrefresh(shutter_win); + wrefresh(aperture_win); + attron(COLOR_PAIR(2)); + mvprintw(LINES - 2, 0, "Select EV"); + mvprintw(LINES - 1, 0, "Arrow keys to navigate, Enter to select, Q to exit"); + attroff(COLOR_PAIR(2)); + refresh(); + + /* Set default menu */ + menu = &exposure_menu; + win = &exposure_win; + + while((c = getch()) != 81) { /* 81 is Q */ + switch(c) { + case KEY_LEFT: + if (selection_counter > 2) { + menu_counter = 3; + menu = &shutter_menu; + win = &shutter_win; + } + break; + case KEY_RIGHT: + if (selection_counter > 2) { + menu_counter = 4; + menu = &aperture_menu; + win = &aperture_win; + } + break; + case KEY_DOWN: + menu_driver(*menu, REQ_DOWN_ITEM); + break; + case KEY_UP: + menu_driver(*menu, REQ_UP_ITEM); + break; + case 10: { /* ENTER */ + ITEM *cur; + void (*p)(char *); + + cur = current_item(*menu); + p = item_userptr(cur); + /* Learning notes - Don't understand this bit. Is this a function pointer? */ + p((char *)item_name(cur)); + /* Need to igore over/under if selected, probably easier than try to prevent selection */ + if (!((strcmp("OVER", shutter_sel) == 0) + || (strcmp("UNDER", shutter_sel) == 0) + || (strcmp("OVER", aperture_sel) == 0) + || (strcmp("UNDER", aperture_sel) == 0))) { + switch (selection_counter) { + case 1: { /* Exposure selected */ + selection_counter += 1; + menu_counter += 1; + move(LINES - 2, 0); + clrtoeol(); + mvprintw(LINES - 2, 0, "Select ISO"); + refresh(); + menu = &iso_menu; + win = &iso_win; + } + break; + case 2: { /* ISO Selected */ + selection_counter += 1; + menu_counter += 1; + move(LINES - 2, 0); + clrtoeol(); + mvprintw(LINES - 2, 0, "Select Shutter or Aperture"); + refresh(); + menu = &shutter_menu; + win = &shutter_win; + } + break; + case 3: { /* Shutter or Aperture selected */ + if (strcmp("", shutter_sel) == 0) { + char aperture_sel_[4] = ""; + strncpy(aperture_sel_, aperture_sel+2, 3); + /* Using menu_driver to go up/down to force refresh and correct highlighting */ + menu_driver(shutter_menu, REQ_SCR_UPAGE); + menu_driver(shutter_menu, REQ_SCR_DPAGE); + /* There is probably a nicer way to format the below */ + set_menu_pattern( + shutter_menu, + shutter_array[nearest_match( + shutter(exposure(atoi(iso_sel)), strtod(aperture_sel_, NULL)), + 3, + n_shutter + )] + ); + menu_driver(shutter_menu, REQ_DOWN_ITEM); + menu_driver(shutter_menu, REQ_UP_ITEM); + wrefresh(shutter_win); + } + if (strcmp("", aperture_sel) == 0) { + menu_driver(aperture_menu, REQ_SCR_UPAGE); + menu_driver(aperture_menu, REQ_SCR_DPAGE); + set_menu_pattern( + aperture_menu, + aperture_array[nearest_match( + aperture(exposure(atoi(iso_sel)), fraction_to_double(shutter_sel)), + 4, + n_aperture + )] + ); + menu_driver(aperture_menu, REQ_DOWN_ITEM); + menu_driver(aperture_menu, REQ_UP_ITEM); + wrefresh(aperture_win); + } + /* Clear the selections for next time */ + strcpy(iso_sel, ""); + strcpy(shutter_sel, ""); + strcpy(aperture_sel, ""); + /* And set defaults back to start */ + selection_counter = 1; + menu_counter = 1; + menu = &exposure_menu; + win = &exposure_win; + move(LINES - 2, 0); + clrtoeol(); + mvprintw(LINES - 2, 0, "Select EV"); + refresh(); + } + break; + } + } + /* If over/under need to clear selection so know which is blank when a proper selection is made */ + if ((strcmp("OVER", shutter_sel) == 0) || (strcmp("UNDER", shutter_sel) == 0)) { + strcpy(shutter_sel, ""); + } + if ((strcmp("OVER", aperture_sel) == 0) || (strcmp("UNDER", aperture_sel) == 0)) { + strcpy(aperture_sel, ""); + } + } + break; + } + wrefresh(*win); + } + /* Unpost and free all the memory taken up */ + remove_menu(exposure_items, exposure_menu, n_exposure); + remove_menu(iso_items, iso_menu, n_iso); + remove_menu(shutter_items, shutter_menu, n_shutter); + remove_menu(aperture_items, aperture_menu, n_aperture); + endwin(); +} + +/* Below pointer configuration figured out from: + * https://github.com/Yurickh/Psycho-Tetris/blob/master/src/menu.c#L9 */ +ITEM **add_item(char **array, int n) { + int i; + ITEM **local_items; + + local_items = (ITEM **)calloc(n, sizeof(ITEM *)); + for(i = 0; i= fraction_to_double(shutter_array[1])/2) { + /* diff is greater than diff of next one down minus max/min */ + diff_idx = 0; + } + } + if (diff_idx == n_array-3) { + if (diff >= fraction_to_double(shutter_array[n_array-3])*2) { + diff_idx = n_array-2; + } + } + break; + case 4: + for ( n = 2; n < n_array-2; ++n ) { + strncpy(array_value_str, aperture_array[n]+2, 4); + array_value_db = strtod(array_value_str, NULL); + if (fabs(array_value_db - x) < diff) { + diff_idx = n; + diff = fabs(array_value_db - x); + } + } + /* Apertures similarly. Although progression is fiddlier.*/ + if (diff_idx == 1) { + strncpy(array_value_str, aperture_array[1]+2, 4); + array_value_db = strtod(array_value_str, NULL); + if (diff >= array_value_db/sqrt(2.0)) { + /* diff is greater than diff of next one down minus max/min */ + diff_idx = 0; + } + } + if (diff_idx == n_array-3) { + strncpy(array_value_str, aperture_array[n_array-3]+2, 4); + array_value_db = strtod(array_value_str, NULL); + if (diff >= array_value_db*sqrt(2.0)) { + diff_idx = n_array-2; + } + } + + break; + } + return diff_idx; +} + +double fraction_to_double(char *fraction) { + double fraction_as_db; + char denominator[9]; + char *ptr = strstr(fraction, "/"); + + if (ptr) { + /*then split*/ + strncpy(denominator, fraction+2, 5); + fraction_as_db = 1 / strtod(denominator, NULL); + } + else { + fraction_as_db = strtod(fraction, NULL); + } + return fraction_as_db; +} + +/* Debug lines + * sprintf(temp, "%f", x); + * mvprintw(LINES - 4, 0, temp); + * refresh();*/