Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/TRecorder.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // @(#)root/gui:$Id$
0002 // Author: Katerina Opocenska   11/09/2008
0003 
0004 /*************************************************************************
0005 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
0006 * All rights reserved.                                                  *
0007 *                                                                       *
0008 * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010 *************************************************************************/
0011 
0012 #ifndef ROOT_TRecorder
0013 #define ROOT_TRecorder
0014 
0015 
0016 #include "TApplication.h"
0017 #include "TError.h"
0018 #include "TTimer.h"
0019 #include "TGClient.h"
0020 #include "TGFrame.h"
0021 #include "TCanvas.h"
0022 #include "THashList.h"
0023 
0024 #include <ctime>
0025 #include <iostream>
0026 
0027 class TMutex;
0028 class TTree;
0029 class TFile;
0030 class TGPictureButton;
0031 class TGCheckButton;
0032 class TGLabel;
0033 class TRecorderState;
0034 
0035 
0036 /** \class TRecEvent
0037     \ingroup guirecorder
0038 
0039 Abstract class that defines interface for a class storing
0040 information about 1 ROOT event.
0041 Time of event is stored and this event can be replayed.
0042 Classes TRecCmdEvent and TRecGuiEvent implements this interface
0043 for command line and GUI events respectively.
0044 
0045 */
0046 
0047 
0048 class TRecEvent : public TObject
0049 {
0050 private:
0051    TTime   fEventTime;          // Time of original event execution
0052 
0053 public:
0054    //---- Types of events recorded in ROOT.
0055    enum ERecEventType {
0056       kCmdEvent,     // Commandline event
0057       kGuiEvent,    // GUI event
0058       kExtraEvent
0059    };
0060 
0061    // Replays (executes) the stored event again
0062    virtual void ReplayEvent(Bool_t showMouseCursor = kTRUE) = 0;
0063 
0064    // Returns what kind of event it stores
0065    virtual ERecEventType GetType() const = 0;
0066 
0067    virtual TTime GetTime() const {
0068       // Returns time of original execution of stored event
0069       return fEventTime;
0070    }
0071 
0072    virtual void SetTime(TTime t) {
0073       // Sets time of event execution
0074       fEventTime = t;
0075    }
0076 
0077    ClassDefOverride(TRecEvent,1) // Abstract class. Defines basic interface for storing information about ROOT events
0078 };
0079 
0080 
0081 /** \class TRecCmdEvent
0082     \ingroup guirecorder
0083 
0084 Class used for storing information about 1 commandline event.
0085 It means 1 command typed in by user in the commandline,
0086 e.g 'new TCanvas'.
0087 
0088 */
0089 
0090 
0091 class TRecCmdEvent : public TRecEvent
0092 {
0093 private:
0094    TString fText;             // Text of stored command
0095 
0096 public:
0097    TRecCmdEvent() {
0098       // Creates new empty  TRecCmdEvent
0099    }
0100 
0101    void SetText(const char *text) {
0102       // Saves text of a command
0103       fText = text;
0104    }
0105 
0106    const char *GetText() const {
0107       // Returns stored text of the command
0108       return fText.Data();
0109    }
0110 
0111    ERecEventType GetType() const override {
0112       // Returns what kind of event it stores (commandline event)
0113       return TRecEvent::kCmdEvent;
0114    }
0115 
0116    void ReplayEvent(Bool_t) override {
0117       // Stored command is executed again
0118       std::cout << GetText() << std::endl;
0119       gApplication->ProcessLine(GetText());
0120    }
0121 
0122    ClassDefOverride(TRecCmdEvent,1) // Class stores information about 1 commandline event (= 1 command typed by user in commandline)
0123 };
0124 
0125 
0126 
0127 /** class TRecExtraEvent
0128     \ingroup guirecorder
0129 
0130 Class used for storing information about 1 extra event.
0131 It means 1 TPaveLabel or 1 TLatex event produced in the Canvas
0132 
0133 */
0134 
0135 
0136 class TRecExtraEvent : public TRecEvent
0137 {
0138 private:
0139    TString fText;             // Text of stored command
0140 
0141 public:
0142    TRecExtraEvent() {
0143       // Creates new empty  TRecExtraEvent
0144    }
0145 
0146    void SetText(TString text) {
0147       // Saves text of a command (PaveLabel or Text)
0148       fText = text;
0149    }
0150 
0151    TString GetText() const {
0152       // Returns stored text of the command
0153       return fText;
0154    }
0155 
0156    ERecEventType GetType() const override {
0157       // Returns what kind of event it stores (Especial event)
0158       return TRecEvent::kExtraEvent;
0159    }
0160 
0161    void ReplayEvent(Bool_t) override {
0162       // Stored event is executed again
0163 
0164       gApplication->ProcessLine(GetText());
0165    }
0166 
0167    ClassDefOverride(TRecExtraEvent,1) // Class stores information about extra events
0168 };
0169 
0170 
0171 /** class TRecGuiEvent
0172     \ingroup guirecorder
0173 
0174 Class used for storing information about 1 GUI event in ROOT.
0175 For list of possible GUI events see EGEventType.
0176 
0177 */
0178 
0179 
0180 class TRecGuiEvent : public TRecEvent
0181 {
0182 protected:
0183    friend class TRecorderInactive;
0184    friend class TRecorderPaused;
0185    friend class TRecorderRecording;
0186    friend class TRecorderReplaying;
0187 
0188    EGEventType    fType;            // Type of event (see EGEventType)
0189    Window_t       fWindow;          // Window ID which reported event is relative to
0190    Time_t         fTime;            // Time event occured in ms
0191    Int_t          fX;               // Pointer x coordinate in event window
0192    Int_t          fY;               // Pointer y coordinate in event window
0193    Int_t          fXRoot;           // x coordinate relative to root
0194    Int_t          fYRoot;           // y coordinate relative to root
0195    UInt_t         fCode;            // Key or button code
0196    UInt_t         fState;           // Key or button mask
0197    UInt_t         fWidth;           // Width of exposed area
0198    UInt_t         fHeight;          // Height of exposed area
0199    Int_t          fCount;           // If non-zero, at least this many more exposes
0200    Bool_t         fSendEvent;       // True if event came from SendEvent
0201    Handle_t       fHandle;          // General resource handle (used for atoms or windows)
0202    Int_t          fFormat;          // Next fields only used by kClientMessageEvent
0203    Long_t         fUser[5];         // 5 longs can be used by client message events
0204                                     // NOTE: only [0], [1] and [2] may be used.
0205                                     // [1] and [2] may contain > 32 bit quantities
0206                                     // (i.e. pointers on 64 bit machines)
0207    Window_t       fMasked;          // If non-zero, event recorded in HandleMaskEvent()
0208 
0209 public:
0210    //---- Types of kConfigureNotify GUI event
0211    enum EConfigureNotifyType {
0212       kCNMove       = 0,      // Movement of a window (Linux)
0213       kCNResize     = 1,      // Resize of a window (Linux)
0214       kCNMoveResize = 2,      // Movement, resize or both (Windows)
0215       kCNFilter     = 3       // Not replaybale (filtered event).
0216    };
0217    //---- Aliases for non cross-platform atoms.
0218    enum ERootAtoms {
0219       kWM_DELETE_WINDOW = 10001,
0220       kROOT_MESSAGE     = 10002
0221    };
0222 
0223    ERecEventType GetType() const override {
0224       // Returns what kind of event it stores (GUI event)
0225       return TRecEvent::kGuiEvent;
0226    }
0227 
0228    void    ReplayEvent(Bool_t showMouseCursor = kTRUE) override;
0229    static Event_t *CreateEvent(TRecGuiEvent *ge);
0230 
0231    ClassDefOverride(TRecGuiEvent,1) // Class stores information about 1 GUI event in ROOT
0232 };
0233 
0234 
0235 /** \class  TRecWinPair
0236     \ingroup guirecorder
0237 
0238 Class used for storing of window IDs mapping.
0239 Remapping of window IDs is needed for replaying events.
0240   - ID of original window is stored in fKey.
0241   - ID of a new window is stored in fValue.
0242 
0243 Whenever an event is replayed, its referenced window ID is changed
0244 from original to a new one according to the appropriate mapping.
0245 
0246 */
0247 
0248 
0249 class TRecWinPair : public TObject
0250 {
0251 protected:
0252    friend class TRecorderReplaying;
0253 
0254    Window_t    fKey;    // ID of original window (for which an event was originally recorded)
0255    Window_t    fValue;  // ID of a new window (for which an event is being replayed)
0256 
0257 public:
0258    // Creates a new key-value mapping of window IDs
0259    TRecWinPair(Window_t key, Window_t value): fKey(key), fValue(value) {}
0260 
0261    ClassDefOverride(TRecWinPair,1) // Class used for storing of window IDs mapping. Needed for replaying events.
0262 };
0263 
0264 
0265 class TRecorder : public TObject
0266 {
0267 private:
0268    TRecorderState *fRecorderState;   //! Current state of recorder
0269 
0270    TRecorder(const TRecorder&);            // Not implemented.
0271    TRecorder &operator=(const TRecorder&); // Not implemented.
0272 
0273 protected:
0274    friend class TRecorderState;
0275    friend class TRecorderInactive;
0276    friend class TRecorderPaused;
0277    friend class TRecorderRecording;
0278    friend class TRecorderReplaying;
0279 
0280    TString      fFilename;           // Events file name
0281    // Changes state to the new one.
0282    // See class documentation for information about state changing.
0283    void  ChangeState(TRecorderState *newstate, Bool_t deletePreviousState = kTRUE);
0284 
0285 public:
0286    //---- Modes of replaying. Only kRealtime implemented so far
0287    enum EReplayModes {
0288       kRealtime
0289    };
0290    //---- States of recorder. In every moment, recorder is in right
0291    // one of these states.
0292    enum ERecorderState {
0293       kInactive,
0294       kRecording,
0295       kPaused,
0296       kReplaying
0297    };
0298 
0299    // Creates recorder and sets its state as INACTIVE
0300    TRecorder();
0301    TRecorder(const char *filename, Option_t *option = "READ");
0302 
0303    // Deletes recorder together with its current state
0304    ~TRecorder() override;
0305 
0306    void Browse(TBrowser *) override;
0307 
0308    // Starts recording of events to the given file
0309    void Start(const char *filename, Option_t *option = "RECREATE", Window_t *w = nullptr, Int_t winCount = 0);
0310 
0311    // Stops recording of events
0312    void Stop(Bool_t guiCommand = kFALSE);
0313 
0314    // Replays recorded events from given file
0315    Bool_t Replay(const char *filename, Bool_t showMouseCursor = kTRUE, TRecorder::EReplayModes mode = kRealtime);
0316 
0317    // Replays recorded events from current file
0318    void Replay() { Replay(fFilename); }   // *MENU*
0319 
0320    // Pauses replaying
0321    void Pause();
0322 
0323    // Resumes paused replaying
0324    void Resume();
0325 
0326    // Stops (cancels) replaying
0327    void ReplayStop();
0328 
0329    // Prints out the list of recorded commandline events
0330    void ListCmd(const char *filename);
0331 
0332    // Prints out the list of recorded GUI events
0333    void ListGui(const char *filename);
0334 
0335    // Gets current state of recorder
0336    virtual TRecorder::ERecorderState GetState() const;
0337 
0338    // Saves all the canvases previous to the TRecorder
0339    void PrevCanvases(const char *filename, Option_t *option);
0340 
0341    ClassDefOverride(TRecorder,2) // Class provides direct recorder/replayer interface for a user.
0342 };
0343 
0344 /** \class TRecorderState
0345     \ingroup guirecorder
0346 
0347 Abstract class that defines interface for a state of recorder.
0348 Inherited classes are:
0349   - TRecorderInactive
0350   - TRecorderRecording
0351   - TRecorderReplaying
0352   - TRecorderPaused
0353 
0354 See TRecorder for more information about creating, using,
0355 changing and deleting states.
0356 
0357 */
0358 
0359 
0360 class TRecorderState
0361 {
0362 protected:
0363    friend class TRecorder;
0364    void ChangeState(TRecorder *r, TRecorderState *s, Bool_t deletePreviousState) { r->ChangeState(s, deletePreviousState); }
0365 
0366 public:
0367    virtual ~TRecorderState() {}
0368    virtual void   Start(TRecorder *, const char *, Option_t *, Window_t *, Int_t) {}
0369    virtual void   Stop(TRecorder *, Bool_t ) {}
0370    virtual Bool_t Replay(TRecorder *, const char *, Bool_t, TRecorder::EReplayModes) { return false; }
0371    virtual void   Pause(TRecorder *) {}
0372    virtual void   Resume(TRecorder *) {}
0373    virtual void   ReplayStop(TRecorder *) {}
0374 
0375    virtual void   ListCmd(const char *) {}
0376    virtual void   ListGui(const char *) {}
0377 
0378    virtual void   PrevCanvases(const char *, Option_t *) {}
0379 
0380    virtual TRecorder::ERecorderState GetState() const = 0;
0381 
0382    ClassDef(TRecorderState, 0) // Abstract class that defines interface for a state of recorder
0383 };
0384 
0385 /** \class TRecorderReplaying
0386     \ingroup guirecorder
0387 Represents state of TRecorder when replaying previously recorded
0388 events.
0389 
0390 Not intended to be used by a user directly.
0391 
0392 */
0393 
0394 
0395 class TRecorderReplaying : public TRecorderState
0396 {
0397 private:
0398     ~TRecorderReplaying() override;
0399    Bool_t   PrepareNextEvent();
0400    Bool_t   RemapWindowReferences();
0401    Bool_t   CanOverlap();
0402 
0403    Bool_t   FilterEvent(TRecGuiEvent *e);
0404 
0405    TRecorder  *fRecorder;  // Reference to recorder (owner of this state) is kept in order to switch
0406                            // recorder to INACTIVE state after replaying is finished
0407 
0408    TFile      *fFile;      // ROOT file which the recorded events are being read from
0409 
0410 
0411    TCanvas    *fCanv;      // Used to record the previous canvases
0412 
0413 
0414    TTimer     *fTimer;     // Timer used for replaying
0415 
0416    TTree      *fWinTree;   // TTree with recorded windows (=registered during recording)
0417    TTree      *fGuiTree;   // TTree with recorded GUI events
0418    TTree      *fCmdTree;   // TTree with recorded commandline events
0419    TTree      *fExtraTree; // TTree with recorded extra events (PaveLabels and Texts)
0420 
0421    ULong64_t       fWin;            // Window ID being currently mapped
0422    TRecGuiEvent   *fGuiEvent;       // GUI event being currently replayed
0423    TRecCmdEvent   *fCmdEvent;       // Commandline event being currently replayed
0424    TRecExtraEvent *fExtraEvent;     // Extra event being currently replayed
0425 
0426    Int_t       fRegWinCounter;      // Counter of registered windows when replaying
0427    Int_t       fGuiTreeCounter;     // Counter of GUI events that have been replayed
0428    Int_t       fCmdTreeCounter;     // Counter of commandline events that have been replayed
0429    Int_t       fExtraTreeCounter;   // Counter of extra events that have been replayed
0430 
0431    Int_t       fWinTreeEntries;     // Number of registered windows during _recording_
0432 
0433    TMutex      *fMutex;
0434 
0435    TList      *fWindowList;         // List of TRecWinPair objects. Mapping of window IDs is stored here.
0436 
0437    TRecEvent  *fNextEvent;          // The next event that is going to be replayed (GUI event or commandline)
0438 
0439    TTime       fPreviousEventTime;  // Execution time of the previously replayed event.
0440                                     // It is used for computing time difference between two events.
0441 
0442    Bool_t      fWaitingForWindow;   // Signalizes that we wait for a window to be registered in order
0443                                     // to replay the next event fNextEvent.
0444                                     // Registration of windows can last different time when recording and replaying.
0445                                     // If there is an event ready to be replayed but the corresponding windows has not been yet
0446                                     // registered, we wait (postopone fNextEvent) until it is registered.
0447 
0448    Bool_t      fEventReplayed;      // Signalizes that the last event sent to the replaying has been already replayed.
0449                                     // Sometimes an execution of an event can take more time than during recording.
0450                                     // This ensures that the next event is sent to replaying AFTER
0451                                     // the replaying of the previous one finishes and not earlier.
0452                                     // Exceptions: ButtonPress and ButtonRelease events (See TRecorderReplaying::CanBeOverlapped)
0453 
0454    Bool_t      fShowMouseCursor;    // Specifies if mouse cursor should be also replayed
0455 
0456    Bool_t      fFilterStatusBar;    // Special flag to filter status bar element
0457 
0458 protected:
0459    friend class TRecorderInactive;
0460    friend class TRecorderPaused;
0461 
0462    TRecorderReplaying(const char *filename);
0463    Bool_t     Initialize(TRecorder *r, Bool_t showMouseCursor, TRecorder::EReplayModes mode);
0464 
0465 public:
0466    TRecorder::ERecorderState GetState() const override { return TRecorder::kReplaying; }
0467 
0468    void   Pause(TRecorder *r) override;
0469    virtual void   Continue();
0470    void   ReplayStop(TRecorder *r) override;
0471 
0472    void           RegisterWindow(Window_t w);   //SLOT
0473    void           ReplayRealtime();             //SLOT
0474 
0475    ClassDefOverride(TRecorderReplaying, 0) // Represents state of TRecorder when replaying
0476 };
0477 
0478 /** \class TRecorderRecording
0479     \ingroup guirecorder
0480 Represents state of TRecorder when recording events.
0481 
0482 Not intended to be used by a user directly.
0483 
0484 */
0485 
0486 
0487 class TRecorderRecording: public TRecorderState
0488 {
0489 private:
0490    ~TRecorderRecording() override;
0491    Bool_t  IsFiltered(Window_t id);
0492    void    SetTypeOfConfigureNotify(Event_t *e);
0493    void    CopyEvent(Event_t *e, Window_t wid);
0494 
0495    TRecorder          *fRecorder;         // Reference to recorder (owner of this state) is kept in order to switch
0496                                           // recorder back to INACTIVE state after recording is finished
0497 
0498    TFile              *fFile;             // ROOT file to store recorded events in
0499    TTimer             *fTimer;            // Timer used for recording
0500    TTimer             *fMouseTimer;       // Timer used for recording mouse position
0501    Long64_t            fBeginPave;        // TLatex/TPaveLabel edition starting time
0502 
0503    TTree              *fWinTree;          // TTree with registered windows
0504    TTree              *fGuiTree;          // TTree with recorded GUI events
0505    TTree              *fCmdTree;          // TTree with recorded commandline events
0506    TTree              *fExtraTree;        // TTree with recorded extra events (PaveLabels and Texts)
0507 
0508    ULong64_t           fWin;              // The newest registered window to be stored in TTree
0509    TRecGuiEvent       *fGuiEvent;         // The newest GUI event to be stored in TTree
0510    TRecCmdEvent       *fCmdEvent;         // The newest commandline event to be stored in TTree
0511    TRecExtraEvent     *fExtraEvent;       // The newest extra event to be stored in TTree
0512 
0513    Bool_t              fCmdEventPending;  // Indication if there is a still pending commandline event that should be stored.
0514                                           // Commandline events are stored with 1 event delay to ensure skipping
0515                                           // the last event 'TRecorder::Stop' that is not supposed to be recorded
0516 
0517    Int_t               fRegWinCounter;    // Counter of registered ROOT windows.
0518                                           // It is increased every time when a new window is registered
0519 
0520    Int_t               fFilteredIdsCount; // Only when GUI for recorder is used: Count of windows in GUI recorder
0521    Window_t           *fFilteredIds;      // Only when GUI for recorder is used: IDs of windows that creates that GUI.
0522                                           // Events for GUI recorder are not recorded.
0523    Bool_t              fFilterEventPave;  // Special flag to filter events during the pave recording
0524 
0525 protected:
0526    friend class TRecorderInactive;
0527    TRecorderRecording(TRecorder *r, const char *filename, Option_t *option, Window_t *w, Int_t winCount);
0528 
0529    Bool_t StartRecording();
0530 
0531 public:
0532    TRecorder::ERecorderState GetState() const override { return TRecorder::kRecording; }
0533 
0534    void Stop(TRecorder *r, Bool_t guiCommand) override;
0535 
0536    void  RegisterWindow(Window_t w);               //SLOT
0537    void  RecordCmdEvent(const char *line);         //SLOT
0538    void  RecordGuiEvent(Event_t *e, Window_t wid); //SLOT
0539    void  RecordGuiBldEvent(Event_t *e);            //SLOT
0540    void  RecordGuiCNEvent(Event_t *e);             //SLOT
0541    void  RecordMousePosition();
0542    void  RecordPave(const TObject *obj);           //SLOT
0543    void  RecordText(const TObject *obj);           //SLOT
0544    void  FilterEventPave();                        //SLOT
0545    void  StartEditing();                           //SLOT
0546 
0547    void  RecordExtraEvent(TString line, TTime extTime);
0548 
0549    ClassDefOverride(TRecorderRecording, 0) // Represents state of TRecorder when recording events
0550 };
0551 
0552 /** \class TRecorderInactive
0553     \ingroup guirecorder
0554 
0555 Represents state of TRecorder just after its creation.
0556 Nor recording neither replaying is being executed in this state.
0557 
0558 Not intended to be used by a user directly.
0559 
0560 */
0561 
0562 
0563 class TRecorderInactive : public TRecorderState
0564 {
0565 
0566 private:
0567    TSeqCollection *fCollect;
0568 
0569 public:
0570           ~TRecorderInactive() override {}
0571    TRecorderInactive() : fCollect(nullptr) {}
0572 
0573    void   ListCmd(const char *filename) override;
0574    void   ListGui(const char *filename) override;
0575 
0576    void   Start(TRecorder *r, const char *filename, Option_t *option, Window_t *w = nullptr, Int_t winCount = 0) override;
0577    Bool_t Replay(TRecorder *r, const char *filename, Bool_t showMouseCursor, TRecorder::EReplayModes mode) override;
0578 
0579    TRecorder::ERecorderState GetState() const override { return TRecorder::kInactive; }
0580 
0581    static void    DumpRootEvent(TRecGuiEvent *e, Int_t n);
0582    static long    DisplayValid(Long_t n) { return ( n < 0 ? -1 : n); }
0583 
0584    void PrevCanvases(const char *filename, Option_t *option) override;
0585 
0586    ClassDefOverride(TRecorderInactive, 0) // Represents state of TRecorder after its creation
0587 };
0588 
0589 /** \class TRecorderPaused
0590     \ingroup guirecorder
0591 
0592 Represents state of TRecorder when replaying was paused
0593 by a user.
0594 The paused replaying is remembered and after Resume call can
0595 be continued again.
0596 
0597 Not intended to be used by a user directly.
0598 
0599 */
0600 
0601 
0602 class TRecorderPaused: public TRecorderState
0603 {
0604 private:
0605    ~TRecorderPaused() override {}
0606 
0607    TRecorderReplaying       *fReplayingState;      // Replaying that is paused
0608 
0609 protected:
0610    friend class TRecorderReplaying;
0611    TRecorderPaused(TRecorderReplaying *state);
0612 
0613 public:
0614    TRecorder::ERecorderState GetState() const override { return TRecorder::kPaused; }
0615 
0616    void Resume(TRecorder *r) override;
0617    void ReplayStop(TRecorder *r) override;
0618 
0619    ClassDefOverride(TRecorderPaused, 0) // Represents state of TRecorder when paused
0620 };
0621 
0622 
0623 /** \class TGRecorder
0624     \ingroup guirecorder
0625 
0626 Provides GUI for TRecorder class.
0627 
0628 */
0629 
0630 class TGRecorder : public TGMainFrame
0631 {
0632 private:
0633    TRecorder          *fRecorder;          // Recorder
0634 
0635    TGPictureButton    *fStartStop;         // Button for start and stop of recording
0636    TGPictureButton    *fReplay;            // Button for start of replaying
0637 
0638    TGLabel            *fStatus;            // Label with actual status
0639    TGLabel            *fTimeDisplay;       // Label with time counter
0640    TGCheckButton      *fCursorCheckBox;    // Check box "Show mouse cursor" for replaying
0641 
0642    TTimer             *fTimer;             // Timer for handling GUI of recorder
0643    time_t              fStart, fElapsed;   // playing/recording time
0644 
0645    static const Int_t  fgWidgetsCount = 12;            // Number of windows in GUI recorder
0646    Window_t            fFilteredIds[fgWidgetsCount];   // IDs of these windows in GUI recorder
0647 
0648    void                SetDefault();
0649 
0650 public:
0651    TGRecorder(const TGWindow *p = nullptr, UInt_t w = 230, UInt_t h = 150);
0652    ~TGRecorder() override;
0653 
0654    void StartStop();
0655    void Update();
0656    void Replay();
0657 
0658    ClassDefOverride(TGRecorder,0) // GUI class of the event recorder.
0659 };
0660 
0661 #endif // ROOT_TRecorder