Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 09:11:55

0001 // Author: Sergey Linev, GSI   7/12/2016
0002 
0003 /*************************************************************************
0004  * Copyright (C) 1995-2023, Rene Brun and Fons Rademakers.               *
0005  * All rights reserved.                                                  *
0006  *                                                                       *
0007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0009  *************************************************************************/
0010 
0011 #ifndef ROOT_TWebCanvas
0012 #define ROOT_TWebCanvas
0013 
0014 #include "TCanvasImp.h"
0015 
0016 #include "TString.h"
0017 #include "TList.h"
0018 #include "TWebPadOptions.h"
0019 
0020 #include <ROOT/RWebWindow.hxx>
0021 
0022 #include <vector>
0023 #include <string>
0024 #include <queue>
0025 #include <functional>
0026 #include <map>
0027 
0028 class TPad;
0029 class TPadWebSnapshot;
0030 class TWebPS;
0031 class TObjLink;
0032 class TExec;
0033 class TWebCanvasTimer;
0034 
0035 class TWebCanvas : public TCanvasImp {
0036 
0037 friend class TWebCanvasTimer;
0038 
0039 public:
0040    /// Function type for signals, invoked when canvas drawing or update is completed
0041    using UpdatedSignal_t = std::function<void()>;
0042 
0043    /// Function type for pad-related signals - like activate pad signal
0044    using PadSignal_t = std::function<void(TPad *)>;
0045 
0046    /// Function type for pad-click signals
0047    using PadClickedSignal_t = std::function<void(TPad *, int, int)>;
0048 
0049    /// Function type for signals, invoked when object is selected
0050    using ObjectSelectSignal_t = std::function<void(TPad *, TObject *)>;
0051 
0052 protected:
0053 
0054    /// Function called when pad painting produced
0055    using PadPaintingReady_t = std::function<void(TPadWebSnapshot *)>;
0056 
0057    struct WebConn {
0058       unsigned fConnId{0};             ///<! connection id
0059       Long64_t fCheckedVersion{0};     ///<! canvas version checked before sending
0060       Long64_t fSendVersion{0};        ///<! canvas version send to the client
0061       Long64_t fDrawVersion{0};        ///<! canvas version drawn (confirmed) by client
0062       UInt_t fLastSendHash{0};         ///<! hash of last send draw message, avoid looping
0063       std::map<std::string, std::string> fCtrl; ///<! different ctrl parameters which can be send at once
0064       std::queue<std::string> fSend;   ///<! send queue, processed after sending draw data
0065 
0066       WebConn(unsigned id) : fConnId(id) {}
0067       bool is_batch() const { return fConnId == 0; }
0068       bool match(unsigned id) const { return !is_batch() && ((fConnId == id) || (id == 0)); }
0069       void reset()
0070       {
0071          fCheckedVersion = fSendVersion = fDrawVersion = 0;
0072          fLastSendHash = 0;
0073       }
0074    };
0075 
0076    struct PadStatus {
0077       Long64_t fVersion{0};    ///<! last pad version
0078       bool _detected{false};   ///<! if pad was detected during last scan
0079       bool _modified{false};   ///<! if pad was modified during last scan
0080       bool _has_specials{false}; ///<! are there any special objects with painting
0081    };
0082 
0083    std::vector<WebConn> fWebConn;  ///<! connections
0084    TWebCanvasTimer *fTimer{nullptr}; ///<! timer to submit control messages
0085 
0086    std::map<TPad*, PadStatus> fPadsStatus; ///<! map of pads in canvas and their status flags
0087 
0088    std::shared_ptr<ROOT::RWebWindow> fWindow; ///!< configured display
0089 
0090    Bool_t fReadOnly{kFALSE};       ///<! in read-only mode canvas cannot be changed from client side
0091    Long64_t fCanvVersion{1};       ///<! actual canvas version, changed with every new Modified() call
0092    Long64_t fLastDrawVersion{0};   ///<! last draw version
0093    UInt_t fClientBits{0};          ///<! latest status bits from client like editor visible or not
0094    std::vector<TPad *> fAllPads;   ///<! list of all pads recognized during streaming
0095    std::map<TObject *,bool> fUsedObjs; ///<! map of used objects during streaming
0096    Int_t fStyleDelivery{0};        ///<! gStyle delivery to clients: 0:never, 1:once, 2:always
0097    Int_t fPaletteDelivery{1};      ///<! colors palette delivery 0:never, 1:once, 2:always, 3:per subpad
0098    Int_t fPrimitivesMerge{100};    ///<! number of PS primitives, which will be merged together
0099    Int_t fJsonComp{0};             ///<! compression factor for messages send to the client
0100    Bool_t fCanCreateObjects{kTRUE}; ///<! indicates if canvas allowed to create extra objects for interactive painting
0101    Bool_t fLongerPolling{kFALSE};  ///<! when true, make longer polling in blocking operations
0102    Bool_t fProcessingData{kFALSE}; ///<! flag used to prevent blocking methods when process data is invoked
0103    Bool_t fAsyncMode{kFALSE};      ///<! when true, methods like TCanvas::Update will never block
0104    Long64_t fStyleVersion{0};      ///<! current gStyle object version, checked every time when new snapshot created
0105    UInt_t fStyleHash{0};           ///<! last hash of gStyle
0106    Long64_t fColorsVersion{0};     ///<! current colors/palette version, checked every time when new snapshot created
0107    UInt_t fColorsHash{0};          ///<! last hash of colors/palette
0108    Int_t fTF1UseSave{1};           ///<! use save buffer for TF1/TF2, 0:off, 1:prefer, 2:force
0109    std::vector<int> fWindowGeometry; ///<! last received window geometry
0110    Bool_t fFixedSize{kFALSE};      ///<! is canvas size fixed
0111 
0112    UpdatedSignal_t fUpdatedSignal; ///<! signal emitted when canvas updated or state is changed
0113    PadSignal_t fActivePadChangedSignal; ///<! signal emitted when active pad changed in the canvas
0114    PadClickedSignal_t fPadClickedSignal; ///<! signal emitted when simple mouse click performed on the pad
0115    PadClickedSignal_t fPadDblClickedSignal; ///<! signal emitted when simple mouse click performed on the pad
0116    ObjectSelectSignal_t fObjSelectSignal; ///<! signal emitted when new object selected in the pad
0117 
0118    std::vector<std::unique_ptr<ROOT::RWebDisplayHandle>> fHelpHandles; ///<! array of handles for help widgets
0119 
0120    static std::string gCustomScripts;     ///<! custom JavaScript code or URL on JavaScript files to load before start drawing
0121    static std::vector<std::string> gCustomClasses;  ///<! list of custom classes, which can be delivered as is to client
0122 
0123    static UInt_t gBatchImageMode;           ///<! configured batch size
0124    static std::string gBatchMultiPdf;           ///<! name of current multi-page pdf file
0125    static std::vector<std::string> gBatchFiles; ///<! file names for batch job
0126    static std::vector<std::string> gBatchJsons; ///<! converted jsons batch job
0127    static std::vector<int> gBatchWidths;   ///<! batch job widths
0128    static std::vector<int> gBatchHeights;  ///<! batch job heights
0129 
0130    void Lock() override {}
0131    void Unlock() override {}
0132    Bool_t IsLocked() override { return kFALSE; }
0133 
0134    Bool_t IsWeb() const override { return kTRUE; }
0135    Bool_t PerformUpdate(Bool_t async) override;
0136    TVirtualPadPainter *CreatePadPainter() override;
0137 
0138    UInt_t CalculateColorsHash();
0139    void AddColorsPalette(TPadWebSnapshot &master);
0140    void AddCustomFonts(TPadWebSnapshot &master);
0141 
0142    void CreateObjectSnapshot(TPadWebSnapshot &master, TPad *pad, TObject *obj, const char *opt, TWebPS *masterps = nullptr);
0143    void CreatePadSnapshot(TPadWebSnapshot &paddata, TPad *pad, Long64_t version, PadPaintingReady_t func);
0144 
0145    void CheckPadModified(TPad *pad);
0146 
0147    Bool_t CheckCanvasModified(bool force_modified = false);
0148 
0149    void AddCtrlMsg(unsigned connid, const std::string &key, const std::string &value);
0150 
0151    void AddSendQueue(unsigned connid, const std::string &msg);
0152 
0153    Bool_t CheckDataToSend(unsigned connid = 0);
0154 
0155    Bool_t WaitWhenCanvasPainted(Long64_t ver);
0156 
0157    virtual Bool_t IsJSSupportedClass(TObject *obj, Bool_t many_primitives = kFALSE);
0158 
0159    Bool_t IsFirstConn(unsigned connid) const { return (connid != 0) && (fWebConn.size() > 1) && (fWebConn[1].fConnId == connid); }
0160 
0161    Bool_t IsFirstDrawn() const { return (fWebConn.size() > 1) && (fWebConn[1].fDrawVersion > 0); }
0162 
0163    void ShowCmd(const std::string &arg, Bool_t show);
0164 
0165    void AssignStatusBits(UInt_t bits);
0166 
0167    virtual Bool_t ProcessData(unsigned connid, const std::string &arg);
0168 
0169    virtual Bool_t DecodePadOptions(const std::string &, bool process_execs = false);
0170 
0171    virtual Bool_t CanCreateObject(const std::string &) { return !IsReadOnly() && fCanCreateObjects; }
0172 
0173    TPad *ProcessObjectOptions(TWebObjectOptions &item, TPad *pad, int idcnt = 1);
0174 
0175    TObject *FindPrimitive(const std::string &id, int idcnt = 1, TPad *pad = nullptr, TObjLink **objlnk = nullptr, TPad **objpad = nullptr);
0176 
0177    void ProcessExecs(TPad *pad, TExec *extra = nullptr);
0178 
0179    void ProcessLinesForObject(TObject *obj, const std::string &lines);
0180 
0181    void SetWindowGeometry(const std::vector<int> &arr);
0182 
0183    static std::string ProcessCustomScripts(bool batch);
0184 
0185    static bool FlushBatchImages();
0186 
0187 public:
0188    TWebCanvas(TCanvas *c, const char *name, Int_t x, Int_t y, UInt_t width, UInt_t height, Bool_t readonly = kTRUE);
0189    ~TWebCanvas() override;
0190 
0191    void CreateWebWindow();
0192 
0193    void ShowWebWindow(const ROOT::RWebDisplayArgs &user_args = "");
0194 
0195    const std::shared_ptr<ROOT::RWebWindow> &GetWebWindow() const { return fWindow; }
0196 
0197    virtual Bool_t IsReadOnly() const { return fReadOnly; }
0198 
0199    Int_t InitWindow() override;
0200    void Close() override;
0201    void Show() override;
0202 
0203    UInt_t GetWindowGeometry(Int_t &x, Int_t &y, UInt_t &w, UInt_t &h) override;
0204 
0205    void ShowMenuBar(Bool_t show = kTRUE) override { ShowCmd("Menu", show); }
0206    void ShowStatusBar(Bool_t show = kTRUE) override { ShowCmd("StatusBar", show); }
0207    void ShowEditor(Bool_t show = kTRUE) override { ShowCmd("Editor", show); }
0208    void ShowToolBar(Bool_t show = kTRUE) override { ShowCmd("ToolBar", show); }
0209    void ShowToolTips(Bool_t show = kTRUE) override { ShowCmd("ToolTips", show); }
0210 
0211    // web-canvas specific methods
0212 
0213    void ActivateInEditor(TPad *pad, TObject *obj);
0214 
0215    void ForceUpdate() override;
0216 
0217    void   SetWindowPosition(Int_t x, Int_t y) override;
0218    void   SetWindowSize(UInt_t w, UInt_t h) override;
0219    void   SetWindowTitle(const char *newTitle) override;
0220    void   SetCanvasSize(UInt_t w, UInt_t h) override;
0221    void   Iconify() override;
0222    void   RaiseWindow() override;
0223 
0224    /*
0225       virtual void   SetStatusText(const char *text = 0, Int_t partidx = 0);
0226       virtual void   ReallyDelete();
0227     */
0228 
0229    Bool_t HasEditor() const override;
0230    Bool_t HasMenuBar() const override;
0231    Bool_t HasStatusBar() const override;
0232    Bool_t HasToolBar() const override { return kFALSE; }
0233    Bool_t HasToolTips() const override;
0234 
0235    void SetUpdatedHandler(UpdatedSignal_t func) { fUpdatedSignal = func; }
0236    void SetActivePadChangedHandler(PadSignal_t func) { fActivePadChangedSignal = func; }
0237    void SetPadClickedHandler(PadClickedSignal_t func) { fPadClickedSignal = func; }
0238    void SetPadDblClickedHandler(PadClickedSignal_t func) { fPadDblClickedSignal = func; }
0239    void SetObjSelectHandler(ObjectSelectSignal_t func) { fObjSelectSignal = func; }
0240 
0241    void SetCanCreateObjects(Bool_t on = kTRUE) { fCanCreateObjects = on; }
0242    Bool_t GetCanCreateObjects() const { return fCanCreateObjects; }
0243 
0244    void SetStyleDelivery(Int_t val) { fStyleDelivery = val; }
0245    Int_t GetStyleDelivery() const { return fStyleDelivery; }
0246 
0247    void SetPaletteDelivery(Int_t val) { fPaletteDelivery = val; }
0248    Int_t GetPaletteDelivery() const { return fPaletteDelivery; }
0249 
0250    void SetPrimitivesMerge(Int_t cnt) { fPrimitivesMerge = cnt; }
0251    Int_t GetPrimitivesMerge() const { return fPrimitivesMerge; }
0252 
0253    void SetLongerPolling(Bool_t on) { fLongerPolling = on; }
0254    Bool_t GetLongerPolling() const { return fLongerPolling; }
0255 
0256    void SetAsyncMode(Bool_t on = kTRUE) { fAsyncMode = on; }
0257    Bool_t IsAsyncMode() const { return fAsyncMode; }
0258 
0259    Bool_t IsFixedSize() const { return fFixedSize; }
0260 
0261    static void SetCustomScripts(const std::string &src);
0262    static const std::string &GetCustomScripts();
0263 
0264    static void AddCustomClass(const std::string &clname, bool with_derived = false);
0265    static bool IsCustomClass(const TClass *cl);
0266 
0267    static Font_t AddFont(const char *name, const char *ttffile, Int_t precision = 2);
0268 
0269    static TString CreatePadJSON(TPad *pad, Int_t json_compression = 0, Bool_t batchmode = kFALSE);
0270    static TString CreateCanvasJSON(TCanvas *c, Int_t json_compression = 0, Bool_t batchmode = kFALSE);
0271    static Int_t StoreCanvasJSON(TCanvas *c, const char *filename, const char *option = "");
0272 
0273    static bool ProduceImage(TPad *pad, const char *filename, Int_t width = 0, Int_t height = 0);
0274 
0275    static bool ProduceImages(std::vector<TPad *> pads, const char *filename, Int_t width = 0, Int_t height = 0);
0276 
0277    static void BatchImageMode(UInt_t n = 100);
0278 
0279    static TCanvasImp *NewCanvas(TCanvas *c, const char *name, Int_t x, Int_t y, UInt_t width, UInt_t height);
0280 
0281    static TCanvas *CreateWebCanvas(const char *name, const char *title, UInt_t width = 1200, UInt_t height = 800);
0282 
0283    ClassDefOverride(TWebCanvas, 0) // Web-based implementation for TCanvasImp
0284 };
0285 
0286 #endif