Subversion Repositories Kolibri OS

Rev

Rev 7189 | Rev 7196 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #define MEMSIZE 4096 * 50
  2.  
  3. //===================================================//
  4. //                                                   //
  5. //                       LIB                         //
  6. //                                                   //
  7. //===================================================//
  8.  
  9. #include "../lib/file_system.h"
  10. #include "../lib/list_box.h"
  11. #include "../lib/gui.h"
  12. #include "../lib/random.h"
  13. #include "../lib/kfont.h"
  14. #include "../lib/collection.h"
  15.  
  16. #include "../lib/obj/libio.h"
  17. #include "../lib/obj/libimg.h"
  18. #include "../lib/obj/libini.h"
  19. #include "../lib/obj/proc_lib.h"
  20. #include "../lib/obj/box_lib.h"
  21.  
  22. #include "../lib/patterns/libimg_load_skin.h"
  23. #include "../lib/patterns/simple_open_dialog.h"
  24.  
  25. //===================================================//
  26. //                                                   //
  27. //                       DATA                        //
  28. //                                                   //
  29. //===================================================//
  30.  
  31. //simple open dialog data
  32. char default_dir[] = "/rd/1";
  33. od_filter filter2 = { 15, "MP3\0WAV\0XM\0\0" };
  34.  
  35. #define ABOUT_MESSAGE "Pixie Player v2.7
  36.  
  37. A tiny music folder player.
  38. Supports MP3, WAV, XM audio file formats.
  39.  
  40. Controls:
  41. Open file: O key
  42. Play/Stop: Space or P key
  43. Start playing selected file: Enter
  44. Goto next/previous track: Ctrl + Left/Right
  45. Change sound volume: Left/Right key
  46. Repeat: R
  47. Shuffle: S
  48. Mute: M
  49.  
  50. kolibri-n.org & aspero.pro"
  51.  
  52. scroll_bar scroll1 = { 5,200,398,44,0,2,115,15,0,0xeeeeee,0xBBBbbb,0xeeeeee,
  53.         0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};
  54.  
  55. proc_info Form;
  56. llist list;
  57.  
  58. char pixie_ini_path[4096];
  59. char work_folder[4096];
  60. char current_filename[256];
  61.  
  62. enum {
  63.         BUTTON_WINDOW_CLOSE = 1,
  64.         BUTTON_WINDOW_MINIMIZE,
  65.         BUTTON_WINDOW_REDUCE,
  66.         BUTTON_PLAYBACK_PLAY_PAUSE = 10,
  67.         BUTTON_PLAYBACK_PREV,
  68.         BUTTON_PLAYBACK_NEXT,
  69.         BUTTON_REPEAT,
  70.         BUTTON_SHUFFLE,
  71.         BUTTON_OPEN_DIALOG,
  72.         BUTTON_SHOW_VOLUME
  73. };
  74.  
  75. int player_run_id;
  76. int notify_run_id;
  77.  
  78. bool repeat;
  79. bool shuffle;
  80.  
  81. int current_playing_file_n=0;
  82.  
  83. word win_x_normal, win_y_normal;
  84. word win_x_small, win_y_small;
  85.  
  86. byte window_mode;
  87. enum {
  88.         WINDOW_MODE_NORMAL,
  89.         WINDOW_MODE_SMALL
  90. };
  91.  
  92. byte playback_mode;
  93. enum {
  94.         PLAYBACK_MODE_STOPED,
  95.         PLAYBACK_MODE_PLAYING
  96. };
  97.  
  98. collection music_col;
  99.  
  100. #define LAST_FOLDER_EXISTS 1
  101.  
  102. //===================================================//
  103. //                                                   //
  104. //                       CODE                        //
  105. //                                                   //
  106. //===================================================//
  107.  
  108. #include "get_files_list.h"
  109. #include "settings.h"
  110.  
  111. void LoadLibraries()
  112. {
  113.         load_dll(boxlib, #box_lib_init,0);
  114.         load_dll(libio, #libio_init,1);
  115.         load_dll(libimg, #libimg_init,1);
  116.         load_dll(libini, #lib_init,1);
  117.         load_dll(Proc_lib, #OpenDialog_init,0);
  118.         OpenDialog_init stdcall (#o_dialog);
  119. }
  120.  
  121. void main()
  122. {
  123.         int tempstr;
  124.         tempstr = abspath("pixie.ini");
  125.         strcpy(#pixie_ini_path, tempstr);
  126.         list.SetFont(8, 16, 13);
  127.         LoadLibraries();
  128.         LoadIniConfig();
  129.         if (work_folder) param=LAST_FOLDER_EXISTS;
  130.         if (!param) notify("'Pixie Player\nPress O key to open MP3/WAV/XM file' -St");
  131.         kfont.init(DEFAULT_FONT);      
  132.         SetEventMask(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER);
  133.         loop()
  134.         {
  135.           WaitEventTimeout(10);
  136.           switch(EAX & 0xFF) {
  137.                 case evMouse:
  138.                         if (!CheckActiveProcess(Form.ID)) break;
  139.                         mouse.get();
  140.                         scrollbar_v_mouse (#scroll1);
  141.                         if (list.first != scroll1.position)
  142.                         {
  143.                                 list.first = scroll1.position;
  144.                                 DrawPlayList();
  145.                                 break;
  146.                         }
  147.                         if (list.MouseOver(mouse.x, mouse.y))
  148.                         {
  149.                                 if (mouse.vert) && (list.MouseScroll(mouse.vert)) DrawPlayList();
  150.                                 if (mouse.dblclick) EventStartPlayingSelectedItem();
  151.                                 if (mouse.down) && (mouse.key&MOUSE_LEFT)
  152.                                         && (list.ProcessMouse(mouse.x, mouse.y)) DrawPlayList();
  153.                                 if (mouse.down) && (mouse.key&MOUSE_RIGHT) CreateThread(#EventShowAbout,#menu_stak+4092);
  154.                         }
  155.                         if(mouse.key&MOUSE_LEFT) && (mouse.x<14)
  156.                                 && (window_mode == WINDOW_MODE_SMALL) EventDragWindow();
  157.                         break;
  158.                 case evButton:
  159.                         switch(GetButtonID()) {
  160.                                 case BUTTON_WINDOW_CLOSE: EventExitApp(); break;
  161.                                 case BUTTON_WINDOW_MINIMIZE: MinimizeWindow(); break;
  162.                                 case BUTTON_WINDOW_REDUCE: EventChangeWindowMode(); break;
  163.                                 case BUTTON_PLAYBACK_PREV: EventPlaybackPrevious();     break;
  164.                                 case BUTTON_PLAYBACK_NEXT: EventPlaybackNext(); break;
  165.                                 case BUTTON_PLAYBACK_PLAY_PAUSE: EventPlayAndPause(); break;
  166.                                 case BUTTON_REPEAT: EventRepeatClick(); break;
  167.                                 case BUTTON_SHUFFLE: EventShuffleClick(); break;
  168.                                 case BUTTON_OPEN_DIALOG: EventFileDialogOpen(); break;
  169.                                 case BUTTON_SHOW_VOLUME: RunProgram("/sys/@VOLUME", NULL); break;
  170.                         }
  171.                         break;   
  172.                 case evKey:
  173.                         GetKeys();
  174.                         if (key_modifier&KEY_LCTRL) || (key_modifier&KEY_RCTRL) {
  175.                                 if (key_scancode==SCAN_CODE_LEFT) EventPlaybackPrevious();
  176.                                 if (key_scancode==SCAN_CODE_RIGHT) EventPlaybackNext();
  177.                                 break;
  178.                         }              
  179.                         if (key_scancode==SCAN_CODE_KEY_O) EventFileDialogOpen();
  180.                         if (key_scancode==SCAN_CODE_KEY_M) RunProgram("/sys/@VOLUME", "m");
  181.                         if (key_scancode==SCAN_CODE_KEY_R) EventRepeatClick();
  182.                         if (key_scancode==SCAN_CODE_KEY_S) EventShuffleClick();
  183.                         if (key_scancode==SCAN_CODE_RIGHT) RunProgram("/sys/@VOLUME", "+");
  184.                         if (key_scancode==SCAN_CODE_LEFT)  RunProgram("/sys/@VOLUME", "-");
  185.                         if (key_scancode==SCAN_CODE_ENTER) EventStartPlayingSelectedItem();
  186.                         if (key_scancode==SCAN_CODE_KEY_P)||(key_scancode==SCAN_CODE_SPACE) EventPlayAndPause();
  187.                         if (list.ProcessKey(key_scancode)) DrawPlayList();
  188.                         break;
  189.                 case evReDraw:
  190.                         if (window_mode == WINDOW_MODE_NORMAL)
  191.                                 DefineDragableWindow(win_x_normal, win_y_normal, skin.w - 1, skin.h + list.h-1);
  192.                         if (window_mode == WINDOW_MODE_SMALL)
  193.                                 DefineDragableWindow(win_x_small, win_y_small, WIN_W_SMALL, WIN_H_SMALL);
  194.                         draw_window();
  195.                         if (param[0]) {
  196.                                 if (param==LAST_FOLDER_EXISTS) EventOpenFolder(NULL);
  197.                                 else EventOpenFolder(#param);
  198.                                 param[0] = NULL;
  199.                         }
  200.                         break;
  201.                 default:
  202.                         EventCheckSongFinished();
  203.           }
  204.   }
  205. }
  206.  
  207.  
  208. void DrawPlayList()
  209. {
  210.         int i;
  211.         int yyy;
  212.         char temp_filename[4096];
  213.         dword text_color, bg_color;
  214.         for (i=0; i<list.visible; i++;)
  215.         {
  216.                 strcpy(#temp_filename, files_mas[i + list.first] * 304 + buf + 72);
  217.                 temp_filename[strrchr(#temp_filename, '.')-1] = '\0';
  218.                 //if (strlen(#temp_filename)>47) strcpy(#temp_filename+44, "...");
  219.                
  220.                 yyy = i*list.item_h+list.y;
  221.                
  222.                 //this is selected file
  223.                 if (list.cur_y - list.first == i)
  224.                 {
  225.                         if (i>=list.count) continue;
  226.                         bg_color = theme.color_list_active_bg;
  227.                         text_color = theme.color_list_text;
  228.                 }
  229.                 //this is not selected file
  230.                 else
  231.                 {
  232.                         if (i>=list.count) continue;
  233.                         bg_color = theme.color_list_bg;
  234.                         text_color = theme.color_list_text;
  235.                 }
  236.                 //this is cur_y playing file
  237.                 if (i + list.first == current_playing_file_n)
  238.                 && (playback_mode == PLAYBACK_MODE_PLAYING)
  239.                 {
  240.                         text_color = theme.color_list_active_text;
  241.                 }
  242.                 DrawBar(list.x, yyy, list.w, list.item_h, bg_color);
  243.                 kfont.WriteIntoWindow(6, yyy+list.text_y, bg_color,
  244.                         text_color, list.font_type, #temp_filename);
  245.         }
  246.         DrawBar(list.x,list.visible * list.item_h + list.y, list.w,
  247.                 -list.visible * list.item_h + list.h, theme.color_list_bg);
  248.         DrawScroller();
  249. }
  250.  
  251.  
  252. void draw_window() {
  253.         GetProcessInfo(#Form, SelfInfo);
  254.         DrawTopPanel();
  255.         IF (Form.status_window>=2) return;
  256.         if (window_mode == WINDOW_MODE_NORMAL)
  257.         {
  258.                 DrawPlayList();
  259.                 DrawRectangle(0, skin.h-1, skin.w-1, list.h+1, theme.color_list_border);
  260.         }
  261. }
  262.  
  263. dword GetSongTitle()
  264. {
  265.         char cur_y_playing_title[245];
  266.         strcpy(#cur_y_playing_title, #current_filename);
  267.         cur_y_playing_title[strrchr(#cur_y_playing_title, '.')-1] = '\0';
  268.         //if (strlen(#cur_y_playing_title) > 36) strcpy(#cur_y_playing_title + 34, "...");
  269.         return #cur_y_playing_title;
  270. }
  271.  
  272.  
  273. void DrawTopPanel()
  274. {
  275.        
  276.         int button_y;
  277.         //Mode depended
  278.         if (window_mode == WINDOW_MODE_NORMAL)
  279.         {
  280.                 button_y = 46;
  281.                 img_draw stdcall(skin.image, 0, 0, skin.w, skin.h, 0, 0);
  282.                 if (playback_mode != PLAYBACK_MODE_STOPED)
  283.                         img_draw stdcall(skin.image, 46, button_y, 41, 21, skin.w+1, WIN_H_SMALL+1);
  284.                 if (repeat)
  285.                         img_draw stdcall(skin.image, 177, button_y+2, 17,17,skin.w+43, WIN_H_SMALL+1);
  286.                 if (shuffle)
  287.                         img_draw stdcall(skin.image, 196, button_y+2, 17,17, skin.w+62, WIN_H_SMALL+1);
  288.  
  289.                 if (!work_folder) DrawPixieTitle("Pixie");
  290.                 else DrawPixieTitle(#work_folder + strrchr(#work_folder, '/'));
  291.                 kfont.WriteIntoWindow(8, 24, theme.color_top_panel_bg,
  292.                         theme.color_top_panel_song_name, list.font_type, GetSongTitle());
  293.                 //Playing control buttons
  294.                 DefineHiddenButton(7, button_y, 38, 20, BUTTON_PLAYBACK_PREV);
  295.                 DefineHiddenButton(47, button_y, 38, 20, BUTTON_PLAYBACK_PLAY_PAUSE);
  296.                 DefineHiddenButton(87, button_y, 38, 20, BUTTON_PLAYBACK_NEXT);
  297.                 //Window control buttons
  298.                 DefineHiddenButton(Form.width - 27, 1, 26, 15, BUTTON_WINDOW_CLOSE);
  299.                 DefineHiddenButton(Form.width - 55, 1, 26, 15, BUTTON_WINDOW_MINIMIZE);
  300.                 DefineHiddenButton(Form.width - 83, 1, 26, 15, BUTTON_WINDOW_REDUCE);
  301.                 //Other buttons
  302.                 DefineHiddenButton(Form.width - 53, button_y, 22, 20, BUTTON_OPEN_DIALOG);
  303.                 DefineHiddenButton(Form.width - 29, button_y, 22, 20, BUTTON_SHOW_VOLUME);
  304.                 DefineHiddenButton(178, button_y+3, 17, 16, BUTTON_REPEAT);
  305.                 DefineHiddenButton(197, button_y+3, 17, 16, BUTTON_SHUFFLE);
  306.         }
  307.         else if (window_mode == WINDOW_MODE_SMALL)
  308.         {
  309.                 button_y = 7;
  310.                 img_draw stdcall(skin.image, 0, 0, WIN_W_SMALL, WIN_H_SMALL, skin.w-1, 0);
  311.                 DefineHiddenButton(0, 0, WIN_W_SMALL, WIN_H_SMALL, 99 + BT_NOFRAME);
  312.                 //Playing control buttons
  313.                 DefineHiddenButton(20, button_y, 24, 16, BUTTON_PLAYBACK_PREV);
  314.                 DefineHiddenButton(46, button_y, 24, 16, BUTTON_PLAYBACK_PLAY_PAUSE);
  315.                 DefineHiddenButton(72, button_y, 24, 16, BUTTON_PLAYBACK_NEXT);
  316.                 //Window control buttons
  317.                 DefineHiddenButton(Form.width - 20, 1, 19, 13, BUTTON_WINDOW_CLOSE);
  318.                 DefineHiddenButton(Form.width - 20, 16, 19, 13, BUTTON_WINDOW_REDUCE);
  319.         }
  320. }
  321.  
  322.  
  323. void DrawScroller()
  324. {
  325.         scroll1.max_area = list.count;
  326.         scroll1.cur_area = list.visible;
  327.         scroll1.position = list.first;
  328.         scroll1.all_redraw = 0;
  329.         scroll1.start_x = skin.w - scroll1.size_x-1;
  330.         scroll1.start_y = list.y-1;
  331.         scroll1.size_y = list.h+2;
  332.         if (list.count > list.visible) scrollbar_v_draw(#scroll1);
  333. }
  334.  
  335. void DrawPixieTitle(dword _title)
  336. {
  337.         kfont.WriteIntoWindow(8, 5, theme.color_top_panel_bg,
  338.                 theme.color_top_panel_folder_name, list.font_type, _title);
  339. }
  340.  
  341. //===================================================//
  342. //                                                   //
  343. //                     EVENTS                        //
  344. //                                                   //
  345. //===================================================//
  346.  
  347.  
  348. void EventOpenFolder(dword _open_path)
  349. {
  350.         if (!_open_path)
  351.         {
  352.                 OpenDirectory(#work_folder);
  353.         }
  354.         else
  355.         {
  356.                 strcpy(#work_folder, _open_path);
  357.                 work_folder[strrchr(#work_folder, '/')-1]='\0';
  358.                 OpenDirectory(#work_folder);
  359.                 SetOpenedFileFirst(_open_path);
  360.         }
  361.         list.SetSizes(1, skin.h, skin.w-1, 22*15, 22);
  362.         if (list.count <= list.visible)
  363.         {
  364.                 list.h = list.count * list.item_h;
  365.                 list.visible = list.count;
  366.                 list.w -= 1;
  367.         }
  368.         else
  369.         {
  370.                 list.w -= scroll1.size_x;
  371.         }
  372.         MoveSize(OLD, OLD, OLD, skin.h + list.h);
  373.         list.KeyHome();
  374.         current_playing_file_n=0;
  375.         EventStopPlayingMp3();
  376.         if (_open_path) EventStartPlayingMp3();
  377. }
  378.  
  379.  
  380. void EventStopPlayingMp3()
  381. {
  382.         if (player_run_id) player_run_id = KillProcess(player_run_id);
  383.         if (notify_run_id) notify_run_id = KillProcess(notify_run_id);
  384.         playback_mode = PLAYBACK_MODE_STOPED;
  385.         DrawTopPanel();
  386.         DrawPlayList();
  387. }
  388.  
  389.  
  390. void EventStartPlayingMp3()
  391. {
  392.         word i;
  393.         char item_path[4096];
  394.         char notify_message[512];
  395.         EventStopPlayingMp3();
  396.         if (current_playing_file_n >= list.count) {
  397.                 current_playing_file_n = list.count-1;
  398.                 return;
  399.         }
  400.         if (current_playing_file_n < 0) {
  401.                 current_playing_file_n = 0;
  402.                 return;
  403.         }
  404.         playback_mode = PLAYBACK_MODE_PLAYING;
  405.         strlcpy(#current_filename, Getcur_yItemName(), sizeof(current_filename));
  406.         sprintf(#item_path,"-h %s/%s",#work_folder,#current_filename);
  407.         DrawPlayList();
  408.         DrawTopPanel();
  409.         player_run_id = RunProgram("/sys/media/ac97snd", #item_path);  
  410.         sprintf(#notify_message,"'Now playing:\n%s' -St",#current_filename);
  411.         if (!repeat)
  412.         {
  413.                 for (i=2; i<strlen(#notify_message)-6; i++)
  414.                 {
  415.                         //replace ' char to avoid @notify misunderstood
  416.                         if (notify_message[i]=='\'') notify_message[i]=96;
  417.                 }
  418.                 notify_run_id = notify(#notify_message);
  419.         }
  420. }
  421.  
  422.  
  423. void EventPlayAndPause()
  424. {
  425.         if (playback_mode == PLAYBACK_MODE_PLAYING)
  426.         {
  427.                 playback_mode = PLAYBACK_MODE_STOPED;
  428.                 EventStopPlayingMp3();
  429.         }
  430.         else
  431.         {
  432.                 playback_mode = PLAYBACK_MODE_PLAYING;
  433.                 EventStartPlayingMp3();
  434.         }
  435. }
  436.  
  437.  
  438. void EventChangeWindowMode()
  439. {
  440.         if (window_mode == WINDOW_MODE_NORMAL)
  441.         {
  442.                 window_mode = WINDOW_MODE_SMALL;
  443.                 win_x_normal = Form.left;
  444.                 win_y_normal = Form.top;
  445.                 MoveSize(OLD, OLD, WIN_W_SMALL-1, WIN_H_SMALL-1);
  446.                 MoveSize(OLD, win_y_small, OLD, OLD);
  447.                 MoveSize(win_x_small, OLD, OLD, OLD);
  448.         }
  449.         else
  450.         {
  451.                 window_mode = WINDOW_MODE_NORMAL;
  452.                 win_x_small = Form.left;
  453.                 win_y_small = Form.top;
  454.                 MoveSize(win_x_normal, win_y_normal, skin.w -1 ,skin.h + list.h);
  455.         }
  456. }
  457.  
  458. void EventExitApp()
  459. {
  460.         EventStopPlayingMp3();
  461.         SaveIniConfig();
  462.         ExitProcess();
  463. }
  464.  
  465. void EventPlaybackPrevious()
  466. {
  467.         if (shuffle) current_playing_file_n = random(list.count);
  468.         else current_playing_file_n--;
  469.         EventStartPlayingMp3();
  470. }
  471.  
  472. void EventPlaybackNext()
  473. {
  474.         if (shuffle) current_playing_file_n = random(list.count);
  475.         else current_playing_file_n++;
  476.         EventStartPlayingMp3();
  477. }
  478.  
  479. void EventStartPlayingSelectedItem()
  480. {
  481.         current_playing_file_n=list.cur_y;
  482.         EventStartPlayingMp3();
  483. }
  484.  
  485. void EventFileDialogOpen()
  486. {
  487.         OpenDialog_start stdcall (#o_dialog);
  488.         if (o_dialog.status==1) EventOpenFolder(#openfile_path);
  489. }
  490.  
  491. void EventCheckSongFinished()
  492. {
  493.         if (playback_mode == PLAYBACK_MODE_PLAYING)
  494.         && (!GetProcessSlot(player_run_id)) {
  495.                 if (repeat) EventStartPlayingMp3();
  496.                 else EventPlaybackNext();
  497.         }
  498. }
  499.  
  500. void EventRepeatClick()
  501. {
  502.         repeat ^= 1;
  503.         DrawTopPanel();
  504. }
  505.  
  506. void EventShuffleClick()
  507. {
  508.         shuffle ^= 1;
  509.         DrawTopPanel();
  510. }
  511.  
  512. void EventShowAbout()
  513. {
  514.         proc_info pop_up;
  515.         loop() switch(WaitEvent())
  516.         {
  517.                 case evButton:
  518.                         ExitProcess();
  519.                         break;
  520.                 case evKey:
  521.                         GetKeys();
  522.                         if (key_scancode == SCAN_CODE_ESC) ExitProcess();
  523.                         break;
  524.                 case evReDraw:
  525.                         DefineDragableWindow(150, 200, 400, 327);
  526.                         GetProcessInfo(#pop_up, SelfInfo);
  527.                         DrawBar(0, 0, pop_up.width, pop_up.height, theme.color_top_panel_bg);
  528.                         DrawRectangle(0, 0, pop_up.width, pop_up.height, theme.color_list_border);
  529.                         WriteTextLines(10, 10, 0x90, theme.color_top_panel_song_name, ABOUT_MESSAGE, 19);
  530.  
  531.                         DefineHiddenButton(pop_up.width - 27, 1, 26, 15, BUTTON_WINDOW_CLOSE);
  532.                         img_draw stdcall(skin.image, pop_up.width-28, 0, 28, 18, skin.w - 29, 0);
  533.                         DrawCaptButton(pop_up.width-10-80, pop_up.height - 34, 80, 24, 2,
  534.                           theme.color_list_active_bg, theme.color_top_panel_song_name, "Cool");
  535.         }
  536. }
  537.  
  538.  
  539. stop:
  540.  
  541. char menu_stak[4096];