// Copyright (c) CNES 2008 // // This software is part of CelestLab, a CNES toolbox for Scilab // // This software is governed by the CeCILL license under French law and // abiding by the rules of distribution of free software. You can use, // modify and/ or redistribute the software under the terms of the CeCILL // license as circulated by CEA, CNRS and INRIA at the following URL // 'http://www.cecill.info'. // Demo tool for CelestLab // Author: A. Lamy // ------------------------------------------------------------- // main // ------------------------------------------------------------- function [] = CL__demos() // repertoire "racine des demos" rep_demos = fullfile(CL_home(), "demos"); // fichier logo CelestLab nomfic_logo = fullfile(CL_home(), "data", "misc", "logo_celestlab_small.png"); CL__demos_main(rep_demos, nomfic_logo); endfunction // ------------------------------------------------------------- // main function // ------------------------------------------------------------- function CL__demos_main(rep_base, nomfic_logo) frame_wl = 200; // Frame width (left) frame_wr = 260; // Frame width (right) frame_h = 220; // Frame height (left) m_x = 15; // x margin m_y = 15; // y margin dy_titre = 30; dy_logo = 136; // exact dimension logo y dx_logo = 121; // exact dimension logo x dy_box = 20; // "checkbox" area (< dy_logo) dx = [m_x, frame_wl, m_x, frame_wr, m_x]; dy = [m_y, dy_box, dy_logo - dy_box, m_y, frame_h, dy_titre]; px = [0,cumsum(dx)]; py = [0,cumsum(dy)]; dim = [px($), py($)]; cadre_1 = [ px(2), py(5), dx(2), dy(5)]; cadre_2 = [ px(4), py(3), dx(4), sum(dy(3:5))]; cadre_logo = [ px(1), py(1), sum(dx(1:3)), sum(dy(1:4))]; cadre_box = [ px(4), py(2), 100, dy_box ]; // 200: size along x // change default values temporarily figdef = gdf(); figdef.figure_position = [20,20]; figdef.figure_size = [100,100]; // no axes if (CL__scilabVersion() >= 550) fig = figure("Figure_name", "CelestLab Demo Tool", "Tag", "CL_demoTool", ... "visible", "off", "default_axes", "off"); else fig = figure("Figure_name", "CelestLab Demo Tool", "Tag", "CL_demoTool", ... "visible", "off"); end fig.immediate_drawing = "off"; fig.background = -2; toolbar(fig.figure_id, "off"); delmenu(fig.figure_id, gettext("&File")); delmenu(fig.figure_id, gettext("&?")); delmenu(fig.figure_id, gettext("&Tools")); delmenu(fig.figure_id, gettext("&Edit")); hm1 = uimenu( "parent", fig, "label" , 'File'); hm2 = uimenu( "parent", fig, "label" , 'Options'); hm3 = uimenu( "parent", fig, "label" , '?'); fig.axes_size = dim; uimenu( "parent" , hm1, ... "label" , 'Quit', ... "callback" , "CL__demos_cb_quit()" ); uimenu( "parent" , hm2, ... "label" , 'Debug mode ...', ... "callback" , "CL__demos_cb_debug_mode()" ); uimenu( "parent" , hm3, ... "label" , 'Help ...', ... "callback" , "CL__demos_cb_help()" ); uimenu( "parent" , hm3, ... "label" , 'About ...', ... "callback" , "CL__demos_cb_about()" ); // disable "resize" // only from version 5.5 if (CL__scilabVersion() >= 550) fig.resize = "off"; end // read data [topics, contents] = CL__demos_gen_data(rep_base); // list of "topics" h1 = CL__demos_createListe(fig, "Topics", cadre_1, "liste1"); CL__demos_createLogo(fig, nomfic_logo, cadre_logo, dx_logo, dy_logo); // list of "applications" h2 = CL__demos_createListe(fig, "Applications", cadre_2, "liste2"); // other options (check boxes) h3 = CL__demos_createCheckbox(fig, "Keep Plots", cadre_box, "Keep"); h4 = CL__demos_createCheckbox(fig, "Show Info", cadre_box+[110,0,0,0], "View"); cb_actif = 0; // 1 = call back en cours listfen = list(); // list of created windows numtopic = 0; // current topic number numchoix = 0; // current application number // activation demo = tlist(['demo', 'topics', 'contents', 'h1', 'h2', 'h3', 'h4', 'fig', ... 'numtopic', 'numchoix', 'listfen', 'cb_actif', 'db_mode'], ... topics, contents, h1, h2, h3, h4, fig, ... numtopic, numchoix, listfen, cb_actif); set(demo.h1, "string", strcat(topics(:,1),"|")); set(demo.h1, "user_data", topics); set(demo.h3, "value", 0); set(demo.h4, "value", 0); demo.fig.immediate_drawing = "on"; // visible "off" removed because not OK in scilab 5.5 // demo.fig.visible = "off"; // to be sure that no plot can appear in the plot demo.cb_actif = 0; // 1 = call back en cours demo.listfen = list(); demo.db_mode = 0; // 1 = mode actif set(fig,"user_data",demo); // demo data -> "user_data" fig.immediate_drawing = "on"; fig.visible = "on"; // restore default figure(); sdf(); endfunction // ------------------------------------------------------------- // creation of list of choices // => "handle" to the list // ------------------------------------------------------------- function [h] = CL__demos_createListe(fig, titre, cadre, tag) // frame uicontrol( ... "parent" , fig,... "relief" , "groove",... "style" , "frame",... "units" , "pixels",... "position" , cadre,... "horizontalalignment" , "center", ... "background" , [1 1 1], ... "visible" , "on", ... "tag" , "frame"); // Frame title margey = 3; htxt = uicontrol( ... "parent" , fig,... "style" , "text",... "string" , "",... "units" , "pixels",... "position" , [ cadre(1), cadre(2)+cadre(4)+margey-2, cadre(3), 20],... "fontunits" , "points",... "fontSize" , 11,... "fontWeight" , "normal",... "horizontalAlignment" , "center", ... "background" , [1 1 1], ... "visible" , "on", ... "tag" , "title_frame"); // List Box margex = 6; margey = 6; h = uicontrol( ... "parent" , fig,... "style" , "listbox",... "units" , "pixels",... "position" , [ cadre(1)+margex cadre(2)+margey cadre(3)-2*margex cadre(4)-2*margey ],... "fontunits" , "points",... "fontSize" , 12,... "relief" , "flat",... "horizontAlalignment" , "left", ... "BackgroundColor" , [255/255 , 255/255 , 255/255 ], ... "callback" , "CL__demos_cb()",... "visible" , "on", ... "tag" , tag); // title again ! (because of scilab bug in previous versions) set(htxt, "string", titre); endfunction // ------------------------------------------------------------- // Logo // ------------------------------------------------------------- function [h] = CL__demos_createLogo(fig,nomfic,cadre, dimx, dimy) str = ""; str = str + ""; str = str + ""; h = uicontrol( ... "parent" , fig,... "style" , "text",... "string" , str,... "units" , "pixels",... "position" , cadre,... "background" , [1 1 1], ... "tag" , "my_text", ... "horizontalalignment" , "center", ... "verticalalignment" , "middle" ... ); endfunction // ------------------------------------------------------------- // creation of checkbox // => "handle" of the checkbox // ------------------------------------------------------------- function [h] = CL__demos_createCheckbox(fig, titre, cadre, tag) h = uicontrol( ... "parent" , fig,... "style" , "checkbox",... "string" , titre,... "units" , "pixels",... "position" , cadre,... "background" , [1 1 1], ... "foregroundColor" , [0 0 0], ... "tag" , tag, ... "callback" , "CL__demos_cb()",... "horizontalalignment" , "left", ... "verticalalignment" , "bottom" ... ); endfunction // ------------------------------------------------------------- // "call-back" for the lists // ------------------------------------------------------------- function CL__demos_cb() // get 'demo' structure (gcbo = calling object) fig = get(gcbo, "parent"); demo = get(fig, "user_data"); // internal data tag = get(gcbo,"tag"); // tag of calling object // does nothing if other callback function active if (demo.cb_actif == 1); return; end demo.cb_actif = 1; // inhibits other callbacks activations set(fig,"user_data",demo); // update data keep = get(demo.h3, "value"); view = get(demo.h4, "value"); debug_mode = demo.db_mode; if ((tag == "liste1" | tag == "liste2") & keep == 0) for k = 1:length(demo.listfen); f = demo.listfen(k); try, delete(f), end end demo.listfen = list(); end scf_save = scf; funcprot(0); // prevent warning as scf is redefined // redefinition of scf : // - stores the figure id // - initializes the default event handler // - NB : initializes user_data as a structure with 2 fields: // -> eventHandler : name of event handler function // -> PointerLocationData : reference information for slope function [f] = scf(varargin) rhs=argn(2); if (rhs == 0) demo = get(fig, "user_data"); f = scf_save(); f.axes_size = [630,420]; demo.listfen(length(demo.listfen)+1) = f; set(fig,"user_data",demo); ud = struct(); // ud.eventHandler = CL__demos_defUserHandler; ud.eventHandler = ""; ud.PointerLocationData = []; set(f, 'user_data', ud); f.event_handler = "CL__demos_userEvtHandler"; f.event_handler_enable = "off"; else f = scf_save(varargin(1)); end endfunction // script execution function [ierr] = exec_script(nomfic) oldfmt=format(); // save format for string() format('v', 10); // 10 digits CL_init(init_glob = %f); // initialisation des constantes au cas ou ierr = exec(nomfic, 'errcatch', -1); if (ierr <> 0) [str,n,lig,func] = lasterror(); // derniere erreur if (debug_mode == 1 & ~isempty(str)) mfprintf(%io(2), "*** STOP ***\n"); for (k = 1:size(str,"*")) mfprintf(%io(2), "=> Message: %s\n",str(k)); end if (func <> ""); mfprintf(%io(2), "=> Function: \n%s\n", func); end elseif (~isempty(str) & grep(str, "*** CelestLab: Cancelled") == []) messagebox(str, "Error", "error") end end format(oldfmt(2), oldfmt(1)); // restore format endfunction // print info if available // info file = same name as script (but .info instead of .sce) function disp_info(nomfic) try lignes = mgetl(nomfic); catch lignes = []; end if isempty(lignes); return; end mprintf("\nInfo:\n"); w = 0; infoex = %f; for k = 1:length(length(lignes)) if (length(lignes(k)) <= 3); continue; end lig1 = strstr(lignes(k), '//>'); if (length(lig1) == 0); continue; end lig = strstr(lig1, '>'); infoex = %t; mprintf("%s\n", lig); end if (~infoex); mprintf("None\n"); end endfunction if (tag == "liste1") demo.numtopic = get(gcbo, "value"); // affecte la liste des applis appli = demo.contents(demo.numtopic).noms; set(demo.h2, "string", strcat(appli(:,1),"|")); set(demo.h2, "user_data", appli); demo.numchoix = 0; // pas d'appli courante elseif (tag == "liste2") demo.numchoix = get(gcbo, "value"); scf(fig); nomchoix = demo.contents(demo.numtopic).noms(demo.numchoix); fig.info_message = nomchoix + ": in progress..."; nomfic = demo.contents(demo.numtopic).fics(demo.numchoix); // nom du script set(fig,"user_data",demo); // car modifie par scf() if (view == 1) mprintf("\n"); mprintf("-------------------------------------------\n"); mprintf("Script path:\n"); script_path = nomfic; if (getos() == "Windows") script_path = getlongpathname(script_path); end mprintf("%s\n", script_path); disp_info(nomfic); deff('$I(str)', 'mprintf(''%s\n'', str)'); mprintf("-------------------------------------------\n"); end // all figures are created invisible sdf(); // reset default figure g = gdf(); // default figure g.visible = "off"; ierr = exec_script(nomfic); sdf(); // reset default figure demo = get(fig, "user_data"); // get again in case of changes set(demo.h1, "value", demo.numtopic); // force selected numbers set(demo.h2, "value", demo.numchoix); set(demo.h2, "value", 0); // remove selection scf(fig); fig.info_message = " "; elseif (tag == "keep") value = get(demo.h3, "value"); end demo.cb_actif = 0; set(fig,"user_data",demo); endfunction // ------------------------------------------------------------- // "quit" call-back // ------------------------------------------------------------- function CL__demos_cb_quit() // closes all open windows fig = get(get(gcbo, "parent"),"parent"); demo = get(fig, "user_data"); for k = 1:length(demo.listfen); f = demo.listfen(k); try delete(f); end end delete(fig); endfunction // ------------------------------------------------------------- // "about" call-back // ------------------------------------------------------------- function CL__demos_cb_about() messagebox(["CelestLab Demo Tool" "CNES - DCT/SB"]); endfunction // ------------------------------------------------------------- // "debug mode" call-back // ------------------------------------------------------------- function CL__demos_cb_debug_mode() fig = get(get(gcbo, "parent"),"parent"); demo = get(fig, "user_data"); if (demo.db_mode == 1) // on old = "ON"; new = "OFF"; else old = "OFF"; new = "ON"; end l1=list(' Current value is: ',1, [old]); l2=list(' Change to: ',1, [new]); choix = x_choices("Debug mode: ", list(l1,l2)); if (~isempty(choix)) demo.db_mode = 1 - demo.db_mode; set(fig,"user_data",demo); end endfunction // ------------------------------------------------------------- // "help" call-back // ------------------------------------------------------------- function CL__demos_cb_help() // path to demos directory path = fullfile(CL_home(), "demos"); if (getos() == "Windows"); path = getlongpathname(path); end msg = [ "Select an item in the ''Topics'' list first, then an" "application." " " "Each application corresponds to a specific script (''.sce'')" "in the CelestLab ''demos'' directory." "The ''demos'' root path is: " path " " "Special features: " " " " - Keep Plots: " " If selected, graphic windows are not deleted" " when a new application is selected." " " " - Show Info:" " If selected, additional information is printed. " " (script path + any additional information " " present in the script)" " " " - Option -> Debug mode: " " If ''ON'', error/info messages are printed, if any. " " Default is ''OFF''." " " " " "Note: " " The CelestLab demo tool calls CL_init before executing " " the scripts. It follows that changing some of the values of the " " local variables %CL_xxx has no impact on the demo results." "------------------------------------------------------------------------- " ]; messagebox(msg, "CelestLab Demo Tool - Help", "info") endfunction // ------------------------------------------------------------- // lists ".sce" files in sub-directories of "path" // topics : list of sub-directories (1st level) // contents : list of "tlist(filename, filepaths)" // ------------------------------------------------------------- function [topics, contents] = CL__demos_gen_data(path) topics = []; contents = list(); // Code: listed = gsort(listfiles(path), 'lr', 'i'); // liste des sous-repertoires du repertoire 'demos' for d = listed' nomrep = fullfile(path,d); if isempty(strindex(d,'.')) & length(findfiles(nomrep, "*.sce")) <> 0 topics = [topics ; strsubst(d,"_", " ")]; fics = nomrep + filesep() + gsort(findfiles(nomrep,"*.sce"), 'lr', 'i'); noms = basename(fics); cont = tlist(["contents", "noms", "fics"], strsubst(noms,"_", " "), fics); contents = lstcat(contents, list(cont)); end end endfunction // ------------------------------------------------------------- // event handler // calls the handler in user_data (same interface) // ------------------------------------------------------------- function CL__demos_userEvtHandler(win, x, y, ibut) f = get_figure_handle(win); if isempty(f); return; end ud = f.user_data; if isstruct(ud) if isfield(ud, 'eventHandler') ud.eventHandler(win, x, y, ibut); end end endfunction // ------------------------------------------------------------- // Default event handler // -> pointer location in user coordinates (left button) // and reference for slope // -> slope (right button) // ------------------------------------------------------------- function CL__demos_defUserHandler(win, x, y, ibut) // NB : x,y : pixels function [s] = format_reel(x) s = sprintf("%.6g", x); s = strsubst(s, "e+00", "e+0"); s = strsubst(s, "e-00", "e-0"); endfunction function [s] = format_xy(x,y) s1 = "x: " + format_reel(x); s2 = "y: " + format_reel(y); s = sprintf("%-10s %-10s", s1, s2); endfunction // protection against interferences // check that all figures are visible and drawn or else does nothing list_fig_id = winsid(); for id = list_fig_id f = get_figure_handle(id); if ~is_handle_valid(f); return; end if ~(f.immediate_drawing == "on" & f.visible == "on"); return; end end f = get_figure_handle(win); if isempty(f); return; end if ~is_handle_valid(f); return; end if (f.immediate_drawing == "off" | f.visible == "off") return; // avoids interferences if plot not finished end // save current figure and axes f_save=gcf(); a_save=gca(); scf(f); ud = get(f, "user_data"); pos_ref = ud.PointerLocationData(1:2); ind_ref = ud.PointerLocationData(3); //xinfo(sprintf("win=%d x=%d y=%d but=%d", win,x,y,ibut)); if (ibut == -1) if isempty(pos_ref) // f.info_message = 'Left click: pointer location, Right click: slope'; f.info_message = " "; end return; end left = intersect(ibut, [0,3]); // 3 = left click right = intersect(ibut, [2,5]); // 5 = right click if (isempty(left) & isempty(right)); return; end h = CL_g_select(f, "Axes"); ok = 0; for k = 1:length(h) a=sca(h(k)); // selects h(k) as current axes if (a.view <> "2d"); continue; end // does nothing for 3D axes // xu, yu : user coordinates // rect : frame coordinates in pixels [xu, yu, rect] = xchange(x,y,"i2f"); if (x>=rect(1) & x<=rect(1)+rect(3) & y>=rect(2) & y<=rect(2)+rect(4)) ok = 1; s1 = format_xy(xu, yu); if ~isempty(left) pos_ref = [xu, yu]; // reference position stored ind_ref = k; s2 = ""; else if isempty(pos_ref) s2 = sprintf("slope: *** No reference position ***"); elseif k <> ind_ref s2 = sprintf("slope: *** Not the same axes ***"); else s1ref = format_xy(pos_ref(1), pos_ref(2)); s2ref = "<= reference position"; f.info_message = sprintf("%-25s %s", s1ref, s2ref); sleep(1000); if xu == pos_ref(1) if yu == pos_ref(2) s2 = "=> slope: undefined" else s2 = "=> slope: infinity" end else pente = (pos_ref(2)-yu)/(pos_ref(1)-xu); s2 = "=> slope: " + format_reel(pente); end end end f.info_message = sprintf("%-25s %s", s1, s2); break; end end if (ok == 0) // out of frame => reinitializes f.info_message = ' '; pos_ref= []; ind_ref = []; end // store ref location ud.PointerLocationData = [pos_ref, ind_ref]; set(f, "user_data", ud); // restore cuurent figure and axes scf(f_save); sca(a_save); endfunction