Subversion Repositories Kolibri OS

Rev

Rev 6559 | Rev 6589 | 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.  
  45.     int gui_event = KOLIBRI_EVENT_REDRAW;
  46.     uint32_t pressed_button = 0;
  47. //    uint32_t mouse_button;
  48. //    pos_t   mouse_pos;
  49.     oskey_t keypress;
  50.  
  51.     // load image for buttons
  52.     const int icon_rgb_size = 16*16*3; // every icons 16x16 24bpp
  53.     char *image_data_rgb,
  54.          *image_data,
  55.          *filedata;
  56.     // make full path + argv
  57.     strcpy(temp_path, *sys_path);
  58.     char *pc = strrchr(temp_path, '/');  // this fails if has params with '/' within. use argv[0] instead
  59.     if (pc) pc[1] = 0;
  60.     strcat(temp_path, "reload_16x16_8b.png");
  61. //    debug_board_write_str(temp_path);
  62.  
  63.     int32_t read_bytes;
  64.     filedata = load_file_inmem(temp_path, &read_bytes);
  65.     image_data_rgb = malloc(icon_rgb_size * 3);  // we know size
  66.     // юяЁхфхы хь тшф шчюсЁрцхэш  ш яхЁхтюфшь хую тю тЁхьхээ√щ сєЇхЁ image_data
  67.     image_data = (*img_decode)(filedata, read_bytes, 0);
  68.     // яЁхюсЁрчєхь шчюсЁрцхэшх ъ ЇюЁьрЄє rgb
  69.     (*img_to_rgb2)(image_data, image_data_rgb);
  70.     // єфры хь тЁхьхээ√щ сєЇхЁ image_data
  71.     (*img_destroy)(image_data);
  72.     free(filedata);
  73.  
  74.     // creating GUI using library functions
  75.     kolibri_window *main_window = kolibri_new_window(50, 40, 430, 500, "PictureButton and File dialog demo");
  76.  
  77.     pict_button tbar[3];
  78.     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));
  79.     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));
  80.     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));
  81.  
  82.     statictext labels[3];  //  tips
  83.     gui_add_statictext(main_window, kolibri_statictext_def(&labels[0], X_Y(5, 28), "Open"));
  84.     gui_add_statictext(main_window, kolibri_statictext_def(&labels[1], X_Y(35, 28), "Save"));
  85.     gui_add_statictext(main_window, kolibri_statictext_def(&labels[2], X_Y(65, 28), "Select Dir & browse"));
  86.  
  87.     open_dialog *dlg_opensave = kolibri_new_open_dialog(OPEN, 10, 10, 420, 320);
  88.     (*OpenDialog_init)(dlg_opensave);
  89.  
  90.     pathview pview;
  91.     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
  92.  
  93.     filebrowser brows;
  94.     filedata = load_file_inmem("/rd/1/File managers/z_icons.png", &read_bytes);
  95.     image_data_rgb = malloc(icon_rgb_size * 20);  // we know size
  96.     // юяЁхфхы хь тшф шчюсЁрцхэш  ш яхЁхтюфшь хую тю тЁхьхээ√щ сєЇхЁ image_data
  97.     image_data = (*img_decode)(filedata, read_bytes, 0);
  98.     // яЁхюсЁрчєхь шчюсЁрцхэшх ъ ЇюЁьрЄє rgb
  99.     (*img_to_rgb2)(image_data, image_data_rgb);
  100.     // єфры хь тЁхьхээ√щ сєЇхЁ image_data
  101.     (*img_destroy)(image_data);
  102.     free(filedata);
  103.  
  104.     filedata = load_file_inmem("/rd/1/File managers/icons.ini", &read_bytes);
  105.     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,
  106.                                          filedata, filedata + read_bytes,
  107.                                          0x00FF00, 0xbbddff, 0x000000, 0xFFFFFF, 0xFF0000));
  108.  
  109.     // try devices "/" - good
  110.     brows.folder_data = read_folderdata("/rd/1");
  111.     brows.select_panel_counter = 1;  // if want to show selection
  112.  
  113. kolibri_handle_event_redraw(main_window);
  114. brows.all_redraw = 1;
  115. (*filebrowse_draw)(&brows);
  116.  
  117.  
  118. //???    set_os_keyb_mode(1); // needed for keyboard use in menu
  119.  
  120.     int extended_key = 0, act = 0;
  121.     do  /* Start of main activity loop */
  122.     {
  123.         switch(gui_event)
  124.         {
  125.         case KOLIBRI_EVENT_REDRAW:
  126. //???? start red
  127. //brows.marked_file = 1;
  128.             control_minimal_window_size(430, 500);
  129.             brows.all_redraw = 1;
  130.             kolibri_handle_event_redraw(main_window);
  131.             brows.all_redraw = 0;
  132.             break;
  133.         case KOLIBRI_EVENT_NONE:
  134.                         break;
  135.         case KOLIBRI_EVENT_KEY:
  136.             keypress = get_key();
  137.             if(keypress.state) break;
  138.             if (keypress.code == 0xE0){ extended_key = 1; break; }
  139.  
  140.             act = 0;
  141.             switch(keypress.ctrl_key)  // ascii scancode
  142.             {
  143.             case 80: // arrow down
  144.                 act = 1; break;
  145.             case 72: // arrow up
  146.                 act = 2; break;
  147.             case 81: // PageDown
  148.                 act = 3; break;
  149.             case 73: // PageUp
  150.                 act = 4; break;
  151.             case 71: // Home
  152.                 act = 5; break;
  153.             case 79: // End
  154.                 act = 6; break;
  155.             case 28: // Enter
  156.                 act = 7; break;
  157.             case 82: // Insert
  158.                 act = 8; break;
  159.             case 78: // NumPad+   select all
  160.                 act = 9; break;
  161.             case 74: // NumPad-   deselct
  162.                 act = 10; break;
  163.             case 55: // NumPad*  invert selection
  164.                 act = 11; break;
  165.             default:
  166.                 act = 12; // search by letter
  167.             }
  168.             brows.key_action = act;
  169.             brows.key_action_num = keypress.ctrl_key;
  170.  
  171.             debug_board_printf("key pressed [%X] %d, action %d, ext_flag = %d\n", keypress.val, brows.key_action_num, act, extended_key);
  172.  
  173.             if (extended_key) extended_key = 0;
  174.             (*filebrowse_key)(&brows);
  175.             //kolibri_handle_event_key(main_window);
  176.                         break;
  177.         case KOLIBRI_EVENT_BUTTON:
  178.             pressed_button = get_os_button();
  179.             switch (pressed_button)
  180.             {
  181.               case BTN_QUIT:
  182.                 return 0;
  183.                 break;
  184.             }
  185.             break;
  186.         case KOLIBRI_EVENT_MOUSE:
  187. //            mouse_pos = get_mouse_pos(POS_WINDOW); // window relative
  188. //            mouse_button = get_mouse_eventstate();
  189.             brows.select_flag = 0;
  190.             kolibri_handle_event_mouse(main_window);
  191.  
  192.  
  193.             if (brows.mouse_keys_delta == 3)  // double clicked in browser
  194.             {
  195.                 debug_board_printf("mouse_keys_delta == 3, name %s\n", brows.selected_BDVK_adress->fname);
  196.                 brows.mouse_keys_delta = 0;
  197.             }
  198.  
  199.             if(tbar[0].click)  // open
  200.             {
  201.                 tbar[0].click = 0;
  202.                 dlg_opensave->mode = OPEN;
  203.                 (*OpenDialog_start)(dlg_opensave);
  204.                 //debug_board_printf("status == %d, buf = %s\n", dlg_opensave->status, dlg_opensave->openfile_path);
  205.                 if (dlg_opensave->status != 2 && dlg_opensave->status != 0) // fail or cancel
  206.                 {
  207.                     (*path_show_prepare)(&pview);
  208.                     (*path_show_draw)(&pview);
  209.                 }
  210.             }
  211.             if(tbar[1].click)  // save
  212.             {
  213.                 tbar[1].click = 0;
  214.                 dlg_opensave->mode = SAVE;
  215.                 (*OpenDialog_start)(dlg_opensave);
  216.                 if (dlg_opensave->status != 2 && dlg_opensave->status != 0) // fail or cancel
  217.                     (*path_show_prepare)(&pview);
  218.  
  219.                 // just calling line below draws incomplete
  220.                 // kolibri_handle_event_redraw(main_window);
  221.             }
  222.             if(tbar[2].click)  // select
  223.             {
  224.                 tbar[2].click = 0;
  225.                 dlg_opensave->mode = SELECT;
  226.                 (*OpenDialog_start)(dlg_opensave);
  227.                 if (dlg_opensave->status != 2 && dlg_opensave->status != 0) // fail or cancel
  228.                 {
  229.                     (*path_show_prepare)(&pview);
  230.                     free(brows.folder_data);
  231.                     brows.folder_data = read_folderdata(dlg_opensave->openfile_path);
  232.                     brows.start_draw_line = brows.start_draw_cursor_line = 0;
  233.                 }
  234.                 // we may redraw here, or just wait next redraw event
  235.                 brows.all_redraw = 1;
  236.                 kolibri_handle_event_redraw(main_window);
  237.                 brows.all_redraw = 0;
  238.             }
  239.  
  240.             break;
  241.         }
  242.  
  243.         gui_event = get_os_event();
  244.     } while(1) ; /* End of main activity loop */
  245.  
  246.   return 0;
  247. }
  248.  
  249.  
  250. char*   load_file_inmem(char* fname, int32_t* read_sz)
  251. {
  252.     FILE *f = fopen(fname, "rb");
  253.     if (!f) {
  254.         debug_board_printf("Can't open file: %s", fname);
  255.         exit(1);
  256.     }
  257.     if (fseek(f, 0, SEEK_END)) {
  258.         debug_board_printf("Can't SEEK_END file: %s", fname);
  259.         exit(1);
  260.     }
  261.     int filesize = ftell(f);
  262.     rewind(f);
  263.     char* fdata = malloc(filesize);
  264.     if(!fdata) {
  265.         debug_board_printf("No memory for file %s", fname);
  266.         exit(1);
  267.     }
  268.     *read_sz = fread(fdata, 1, filesize, f);
  269.     if (ferror(f)) {
  270.         debug_board_printf("Error reading file %s", fname);
  271.         exit(1);
  272.     }
  273.     fclose(f);
  274.  
  275.     return fdata;
  276. }
  277.  
  278. void* read_folderdata(char* name)
  279. {
  280.     struct fs_dirinfo di;
  281.     struct fs_dirheader dhead;
  282.     assert(sizeof di == 25);
  283.  
  284.     memset(&di, 0, sizeof di);
  285.     di.ppath = name;
  286.     di.retval = (uint32_t)&dhead;
  287.     int rc = sf_file(1, &di);  // read dir size
  288.     if(rc) {
  289.         debug_board_printf("Error reading dir size %s", name);
  290.         exit(1);
  291.     }
  292.     di.size = dhead.totl_blocks;
  293.  
  294.     char *retdir = malloc(sizeof dhead + dhead.totl_blocks * sizeof(struct fsBDFE));
  295.     if(!retdir) {
  296.         debug_board_printf("No memory for dir %s", name);
  297.         exit(1);
  298.     }
  299.     di.retval = (uint32_t)retdir;
  300.     rc = sf_file(1, &di);  // read dir size
  301.     if(rc) {
  302.         debug_board_printf("Error 2 reading dir size %s", name);
  303.         exit(1);
  304.     }
  305.  
  306.     // manual clear mark flag (random junk in fname free space)
  307.     int i;
  308.     for (i = 0; i < dhead.totl_blocks; i++)
  309.         ((struct fsBDFE*)(retdir+32))[i].fname[259] = 0;
  310.  
  311.     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);
  312.  
  313.     return retdir;
  314. }
  315.  
  316.  
  317.  
  318. void control_minimal_window_size(int wmin, int hmin)
  319. {
  320.     char pinfo[1024];
  321.     get_proc_info(pinfo);
  322.  
  323.     int win_hight = *(int*)(pinfo + 46),
  324.         win_width = *(int*)(pinfo + 42);
  325.     char win_status = pinfo[70];
  326.  
  327.     if (win_status & 7) return;  // maximized, minimized or titlebar mode
  328.  
  329.     if (win_width < wmin)
  330.         __asm__ __volatile__("int $0x40" ::"a"(67), "b"(-1), "c"(-1), "d"(wmin), "S"(-1));  // SF_CHANGE_WINDOW x,y,w,h
  331.     if (win_hight < hmin)
  332.         __asm__ __volatile__("int $0x40" ::"a"(67), "b"(-1), "c"(-1), "d"(-1), "S"(hmin));  // x,y,w,h
  333.  
  334. }
  335.  
  336.  
  337.