Subversion Repositories Kolibri OS

Rev

Rev 6561 | Rev 6612 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     KolibriGUI demobox
  3.     -Picture Button
  4.     -StaticText
  5.     -File Open/Save Dialog
  6.     -Filebrowser
  7.     -Controlling minimal window size
  8.  
  9.     Free for all
  10.  
  11.     Initially written by Siemargl, 2016
  12.  
  13.  
  14.     ToDo
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <assert.h>
  21. #include "kos32sys.h"
  22. #include "kolibri_gui.h"
  23. #include "kolibri_opendialog.h"
  24. #include "kolibri_libimg.h"
  25.  
  26. char temp_path[4096];
  27. char** sys_path = (char**)0x20; // hack - get path from KOS header. analog argv[0]
  28.  
  29. char*   load_file_inmem(char* fname, int32_t* read_sz); // see below
  30. void* read_folderdata(char* name);
  31. void control_minimal_window_size(int wmin, int hmin);
  32.  
  33. int main(int argc, char **argv)
  34. {
  35.     /* Load all libraries, initialize global tables like system color table and
  36.     operations table. kolibri_gui_init() will EXIT with mcall -1 if it fails
  37.     to do it's job. This is all you need to call and all libraries and GUI
  38.     elements can be used after a successful call to this function
  39.     */
  40.     kolibri_gui_init();
  41.     kolibri_proclib_init();  // opensave && color dialogs
  42.     kolibri_libimg_init();  // png handling
  43.  
  44.     int gui_event = KOLIBRI_EVENT_REDRAW;
  45.     uint32_t pressed_button = 0;
  46. //    uint32_t mouse_button;
  47. //    pos_t   mouse_pos;
  48.     oskey_t keypress;
  49.  
  50.     // load image for buttons
  51.     const int icon_rgb_size = 16*16*3; // every icons 16x16 24bpp
  52.     char *image_data_rgb,
  53.          *image_data,
  54.          *filedata;
  55.     // make full path + argv
  56.     strcpy(temp_path, *sys_path);
  57.     char *pc = strrchr(temp_path, '/');  // this fails if has params with '/' within. use argv[0] instead
  58.     if (pc) pc[1] = 0;
  59.     strcat(temp_path, "reload_16x16_8b.png");
  60. //    debug_board_write_str(temp_path);
  61.  
  62.     int32_t read_bytes;
  63.     filedata = load_file_inmem(temp_path, &read_bytes);
  64.     image_data_rgb = malloc(icon_rgb_size * 3);  // we know size
  65.     // îïðåäåëÿåì âèä èçîáðàæåíèÿ è ïåðåâîäèì åãî âî âðåìåííûé áóôåð image_data
  66.     image_data = (*img_decode)(filedata, read_bytes, 0);
  67.     // ïðåîáðàçóåì èçîáðàæåíèå ê ôîðìàòó rgb
  68.     (*img_to_rgb2)(image_data, image_data_rgb);
  69.     // óäàëÿåì âðåìåííûé áóôåð image_data
  70.     (*img_destroy)(image_data);
  71.     free(filedata);
  72.  
  73.     // creating GUI using library functions
  74.     kolibri_window *main_window = kolibri_new_window(50, 40, 430, 500, "PictureButton and File dialog demo");
  75.  
  76.     pict_button tbar[3];
  77.     gui_add_pict_button(main_window, kolibri_pict_button(&tbar[0], X_Y(10, 16), X_Y(10, 16), image_data_rgb, image_data_rgb + icon_rgb_size, image_data_rgb + icon_rgb_size * 2, 24, NULL, 0));
  78.     gui_add_pict_button(main_window, kolibri_pict_button(&tbar[1], X_Y(35, 16), X_Y(10, 16), image_data_rgb, image_data_rgb + icon_rgb_size, image_data_rgb + icon_rgb_size * 2, 24, NULL, 0));
  79.     gui_add_pict_button(main_window, kolibri_pict_button(&tbar[2], X_Y(60, 16), X_Y(10, 16), image_data_rgb, image_data_rgb + icon_rgb_size, image_data_rgb + icon_rgb_size * 2, 24, NULL, 0));
  80.  
  81.     statictext labels[3];  //  tips
  82.     gui_add_statictext(main_window, kolibri_statictext_def(&labels[0], X_Y(5, 28), "Open"));
  83.     gui_add_statictext(main_window, kolibri_statictext_def(&labels[1], X_Y(35, 28), "Save"));
  84.     gui_add_statictext(main_window, kolibri_statictext_def(&labels[2], X_Y(65, 28), "Select Dir & browse"));
  85.  
  86.     open_dialog *dlg_opensave = kolibri_new_open_dialog(OPEN, 10, 10, 420, 320);
  87.     (*OpenDialog_init)(dlg_opensave);
  88.  
  89.     pathview pview;
  90.     gui_add_pathview(main_window, kolibri_pathview(&pview, X_Y(10, 50), 330, 1, 0, dlg_opensave->openfile_path, temp_path, 0, 0)); // black font, no background, font 1
  91.  
  92.     filebrowser brows;
  93.     filedata = load_file_inmem("/rd/1/File managers/z_icons.png", &read_bytes);
  94.     image_data_rgb = malloc(icon_rgb_size * 20);  // we know size
  95.     // îïðåäåëÿåì âèä èçîáðàæåíèÿ è ïåðåâîäèì åãî âî âðåìåííûé áóôåð image_data
  96.     image_data = (*img_decode)(filedata, read_bytes, 0);
  97.     // ïðåîáðàçóåì èçîáðàæåíèå ê ôîðìàòó rgb
  98.     (*img_to_rgb2)(image_data, image_data_rgb);
  99.     // óäàëÿåì âðåìåííûé áóôåð image_data
  100.     (*img_destroy)(image_data);
  101.     free(filedata);
  102.  
  103.     filedata = load_file_inmem("/rd/1/File managers/icons.ini", &read_bytes);
  104.     gui_add_filebrowser(main_window, kolibri_filebrowser(&brows, X_Y(10, 400), X_Y(80, 300), X_Y(6, 9), X_Y(16, 16), image_data_rgb, NULL, 24,
  105.                                          filedata, filedata + read_bytes,
  106.                                          0x00FF00, 0xbbddff, 0x000000, 0xFFFFFF, 0xFF0000));
  107.  
  108.     // try devices "/" - good
  109.     brows.folder_data = read_folderdata("/rd/1");
  110.     brows.select_panel_counter = 1;  // if want to show selection
  111.  
  112.     int extended_key = 0, act = 0;
  113.     do  /* Start of main activity loop */
  114.     {
  115.         switch(gui_event)
  116.         {
  117.         case KOLIBRI_EVENT_REDRAW:
  118.             control_minimal_window_size(430, 500);
  119.             brows.all_redraw = 1;
  120.             kolibri_handle_event_redraw(main_window);
  121.             brows.all_redraw = 0;
  122.             break;
  123.         case KOLIBRI_EVENT_NONE:
  124.                         break;
  125.         case KOLIBRI_EVENT_KEY:
  126.             keypress = get_key();
  127.             if(keypress.state) break;
  128.             if (keypress.code == 0xE0){ extended_key = 1; break; }
  129.  
  130.             act = 0;
  131.             switch(keypress.ctrl_key)  // ascii scancode
  132.             {
  133.             case 80: // arrow down
  134.                 act = 1; break;
  135.             case 72: // arrow up
  136.                 act = 2; break;
  137.             case 81: // PageDown
  138.                 act = 3; break;
  139.             case 73: // PageUp
  140.                 act = 4; break;
  141.             case 71: // Home
  142.                 act = 5; break;
  143.             case 79: // End
  144.                 act = 6; break;
  145.             case 28: // Enter
  146.                 act = 7; break;
  147.             case 82: // Insert
  148.                 act = 8; break;
  149.             case 78: // NumPad+   select all
  150.                 act = 9; break;
  151.             case 74: // NumPad-   deselct
  152.                 act = 10; break;
  153.             case 55: // NumPad*  invert selection
  154.                 act = 11; break;
  155.             default:
  156.                 act = 12; // search by letter
  157.             }
  158.             brows.key_action = act;
  159.             brows.key_action_num = keypress.ctrl_key;
  160.  
  161.             debug_board_printf("key pressed [%X] %d, action %d, ext_flag = %d\n", keypress.val, brows.key_action_num, act, extended_key);
  162.  
  163.             if (extended_key) extended_key = 0;
  164.             (*filebrowse_key)(&brows);
  165.             //kolibri_handle_event_key(main_window);
  166.                         break;
  167.         case KOLIBRI_EVENT_BUTTON:
  168.             pressed_button = get_os_button();
  169.             switch (pressed_button)
  170.             {
  171.               case BTN_QUIT:
  172.                 return 0;
  173.                 break;
  174.             }
  175.             break;
  176.         case KOLIBRI_EVENT_MOUSE:
  177. //            mouse_pos = get_mouse_pos(POS_WINDOW); // window relative
  178. //            mouse_button = get_mouse_eventstate();
  179.             brows.select_flag = 0;
  180.             kolibri_handle_event_mouse(main_window);
  181.  
  182.  
  183.             if (brows.mouse_keys_delta == 3)  // double clicked in browser
  184.             {
  185.                 debug_board_printf("mouse_keys_delta == 3, name %s\n", brows.selected_BDVK_adress->fname);
  186.                 brows.mouse_keys_delta = 0;
  187.             }
  188.  
  189.             if(tbar[0].click)  // open
  190.             {
  191.                 tbar[0].click = 0;
  192.                 dlg_opensave->mode = OPEN;
  193.                 (*OpenDialog_start)(dlg_opensave);
  194.                 //debug_board_printf("status == %d, buf = %s\n", dlg_opensave->status, dlg_opensave->openfile_path);
  195.                 if (dlg_opensave->status != 2 && dlg_opensave->status != 0) // fail or cancel
  196.                 {
  197.                     (*path_show_prepare)(&pview);
  198.                     (*path_show_draw)(&pview);
  199.                 }
  200.             }
  201.             if(tbar[1].click)  // save
  202.             {
  203.                 tbar[1].click = 0;
  204.                 dlg_opensave->mode = SAVE;
  205.                 (*OpenDialog_start)(dlg_opensave);
  206.                 if (dlg_opensave->status != 2 && dlg_opensave->status != 0) // fail or cancel
  207.                     (*path_show_prepare)(&pview);
  208.  
  209.                 // just calling line below draws incomplete
  210.                 // kolibri_handle_event_redraw(main_window);
  211.             }
  212.             if(tbar[2].click)  // select
  213.             {
  214.                 tbar[2].click = 0;
  215.                 dlg_opensave->mode = SELECT;
  216.                 (*OpenDialog_start)(dlg_opensave);
  217.                 if (dlg_opensave->status != 2 && dlg_opensave->status != 0) // fail or cancel
  218.                 {
  219.                     (*path_show_prepare)(&pview);
  220.                     free(brows.folder_data);
  221.                     brows.folder_data = read_folderdata(dlg_opensave->openfile_path);
  222.                     brows.start_draw_line = brows.start_draw_cursor_line = 0;
  223.                 }
  224.                 // we may redraw here, or just wait next redraw event
  225.                 brows.all_redraw = 1;
  226.                 kolibri_handle_event_redraw(main_window);
  227.                 brows.all_redraw = 0;
  228.             }
  229.  
  230.             break;
  231.         }
  232.  
  233.         gui_event = get_os_event();
  234.     } while(1) ; /* End of main activity loop */
  235.  
  236.   return 0;
  237. }
  238.  
  239.  
  240. char*   load_file_inmem(char* fname, int32_t* read_sz)
  241. {
  242.     FILE *f = fopen(fname, "rb");
  243.     if (!f) {
  244.         debug_board_printf("Can't open file: %s", fname);
  245.         exit(1);
  246.     }
  247.     if (fseek(f, 0, SEEK_END)) {
  248.         debug_board_printf("Can't SEEK_END file: %s", fname);
  249.         exit(1);
  250.     }
  251.     int filesize = ftell(f);
  252.     rewind(f);
  253.     char* fdata = malloc(filesize);
  254.     if(!fdata) {
  255.         debug_board_printf("No memory for file %s", fname);
  256.         exit(1);
  257.     }
  258.     *read_sz = fread(fdata, 1, filesize, f);
  259.     if (ferror(f)) {
  260.         debug_board_printf("Error reading file %s", fname);
  261.         exit(1);
  262.     }
  263.     fclose(f);
  264.  
  265.     return fdata;
  266. }
  267.  
  268. void* read_folderdata(char* name)
  269. {
  270.     struct fs_dirinfo di;
  271.     struct fs_dirheader dhead;
  272.     assert(sizeof di == 25);
  273.  
  274.     memset(&di, 0, sizeof di);
  275.     di.ppath = name;
  276.     di.retval = (uint32_t)&dhead;
  277.     int rc = sf_file(1, &di);  // read dir size
  278.     if(rc) {
  279.         debug_board_printf("Error reading dir size %s", name);
  280.         exit(1);
  281.     }
  282.     di.size = dhead.totl_blocks;
  283.  
  284.     char *retdir = malloc(sizeof dhead + dhead.totl_blocks * sizeof(struct fsBDFE));
  285.     if(!retdir) {
  286.         debug_board_printf("No memory for dir %s", name);
  287.         exit(1);
  288.     }
  289.     di.retval = (uint32_t)retdir;
  290.     rc = sf_file(1, &di);  // read dir size
  291.     if(rc) {
  292.         debug_board_printf("Error 2 reading dir size %s", name);
  293.         exit(1);
  294.     }
  295.  
  296.     // manual clear mark flag (random junk in fname free space)
  297.     int i;
  298.     for (i = 0; i < dhead.totl_blocks; i++)
  299.         ((struct fsBDFE*)(retdir+32))[i].fname[259] = 0;
  300.  
  301.     debug_board_printf("Loaded dir [%s] etnries %d,\n first file [%s]\n", name, ((struct fs_dirheader*)(retdir))->curn_blocks, ((struct fsBDFE*)(retdir+32))->fname);
  302.  
  303.     return retdir;
  304. }
  305.  
  306.  
  307.  
  308. void control_minimal_window_size(int wmin, int hmin)
  309. {
  310.     char pinfo[1024];
  311.     get_proc_info(pinfo);
  312.  
  313.     int win_hight = *(int*)(pinfo + 46),
  314.         win_width = *(int*)(pinfo + 42);
  315.     char win_status = pinfo[70];
  316.  
  317.     if (win_status & 7) return;  // maximized, minimized or titlebar mode
  318.  
  319.     if (win_width < wmin)
  320.         __asm__ __volatile__("int $0x40" ::"a"(67), "b"(-1), "c"(-1), "d"(wmin), "S"(-1));  // SF_CHANGE_WINDOW x,y,w,h
  321.     if (win_hight < hmin)
  322.         __asm__ __volatile__("int $0x40" ::"a"(67), "b"(-1), "c"(-1), "d"(-1), "S"(hmin));  // x,y,w,h
  323.  
  324. }
  325.  
  326.  
  327.