File indexing completed on 2024-03-03 03:49:30

0001 /*
0002     KmPlot - a math. function plotter for the KDE-Desktop
0003 
0004     SPDX-FileCopyrightText: 1998, 1999, 2000, 2002 Klaus-Dieter Möller <kd.moeller@t-online.de>
0005     SPDX-FileCopyrightText: 2006 David Saxton <david@bluehaze.org>
0006 
0007     This file is part of the KDE Project.
0008     KmPlot is part of the KDE-EDU Project.
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 
0012 */
0013 
0014 #ifndef View_included
0015 #define View_included
0016 
0017 #include "function.h"
0018 
0019 // Qt includes
0020 #include <QDebug>
0021 #include <QEasingCurve>
0022 #include <QEvent>
0023 #include <QKeyEvent>
0024 #include <QMouseEvent>
0025 #include <QPixmap>
0026 #include <QPointer>
0027 #include <QPropertyAnimation>
0028 #include <QResizeEvent>
0029 
0030 // KDE includes
0031 #include <KTextEdit>
0032 #include <KToggleAction>
0033 
0034 class KSliderWindow;
0035 class MainDlg;
0036 class QPaintEvent;
0037 class QTextDocument;
0038 class QMenu;
0039 class QElapsedTimer;
0040 
0041 //@{
0042 /// Some abbreviations for horizontal and vertical lines.
0043 #define Line drawLine
0044 #define Lineh(x1, y, x2) drawLine(QPointF(x1, y), QPointF(x2, y))
0045 #define Linev(x, y1, y2) drawLine(QPointF(x, y1), QPointF(x, y2))
0046 //@}
0047 
0048 /**
0049  * For drawing the area of a (Cartesian) plot.
0050  */
0051 class IntegralDrawSettings
0052 {
0053 public:
0054     IntegralDrawSettings();
0055 
0056     Plot plot;
0057     double dmin, dmax;
0058     /// Set to true when calculating the area under the graph
0059     bool draw;
0060 };
0061 
0062 /**
0063  * @short This class contains the plots.
0064  *
0065  * It is the central widget of MainDlg.
0066  * @see MainDlg, MainDlg::view
0067  */
0068 class View : public QWidget
0069 {
0070     Q_OBJECT
0071     Q_PROPERTY(QRectF viewport READ getViewport WRITE setViewport)
0072 public:
0073     /// Constructor
0074     View(bool readOnly, QMenu *functionPopup, QWidget *parent);
0075     virtual ~View();
0076 
0077     /// There is only one view.
0078     static View *self()
0079     {
0080         return m_self;
0081     }
0082 
0083     enum PlotMedium {
0084         Screen,
0085         Printer,
0086         SVG,
0087         Pixmap,
0088     };
0089     /**
0090      * Draw the plot to \p dev, which is of the given \p medium.
0091      */
0092     void draw(QPaintDevice *dev, PlotMedium medium);
0093 
0094     enum ExtremaType {
0095         Minimum,
0096         Maximum,
0097     };
0098     /**
0099      * Finding the minimum or maximum value.
0100      * \return The (x,y) coordinates of the extrema point.
0101      */
0102     QPointF findMinMaxValue(const Plot &plot, ExtremaType type, double dmin, double dmax);
0103     /**
0104      * Calculates the area between the given plot and the x-axis
0105      * (from x = \p dmin to x = \p dmax). The area will also be colored in.
0106      * \return the area.
0107      */
0108     double areaUnderGraph(IntegralDrawSettings settings);
0109     /**
0110      * \return if the calculation was cancelled by the user.
0111      */
0112     bool isCalculationStopped();
0113     /**
0114      * Used in posToString for requesting how the position string is to be
0115      * created.
0116      */
0117     enum PositionFormatting {
0118         DecimalFormat, ///< Plain text, using no scientific notation; just decimal expansion.
0119         ScientificFormat, ///< Rich text possibly using scientific notation (mult x 10 ^ exp).
0120     };
0121     /**
0122      * @return a string for displaying the x or y coordinate in the statusbar.
0123      * \param x The number to convert to a string.
0124      * \param delta is the amount by which the value varies over one pixel in
0125      * the view. This is for choosing an appropriate number of decimals so that
0126      * moving the cursor shows a nice change in the string.
0127      * \param format How the number should be represented as a string.
0128      * \param color If using scientific mode, the color to format the text.
0129      */
0130     QString posToString(double x, double delta, PositionFormatting format, const QColor &color = Qt::black) const;
0131 
0132     /// Slider controlling parameter values
0133     QPointer<KSliderWindow> m_sliderWindow;
0134     /// Menu actions for the sliders
0135     KToggleAction *m_menuSliderAction;
0136     void updateSliders(); /// show only needed sliders
0137 
0138     /**
0139      * Convert \p width_mm (millimeters) to the equivalent length when
0140      * drawing using \p painter.
0141      */
0142     double millimetersToPixels(double width_mm, QPaintDevice *device) const;
0143     /**
0144      * The inverse of millimetersToPixels().
0145      */
0146     double pixelsToMillimeters(double width_pixels, QPaintDevice *device) const;
0147 
0148     /** Current plot x-range. */
0149     double m_xmin;
0150     double m_xmax;
0151     /** Current plot y-range. */
0152     double m_ymin;
0153     double m_ymax;
0154 
0155     /// trace mode stuff, must be accessible in FunctionTools
0156     Plot m_currentPlot;
0157     /**
0158      * Convenience function for calculating the value of \p eq using the
0159      * given \p mode
0160      */
0161     double value(const Plot &plot, int eq, double x, bool updateFunction);
0162     /**
0163      * \return the real position of the function (similar to calling
0164      * value(), but returns both coordinates).
0165      */
0166     QPointF realValue(const Plot &plot, double x, bool updateFunction);
0167     /**
0168      * \return the (signed) curvature (in screen coordinates) of the plot
0169      * at \p x (and \p y for implicit functions).
0170      */
0171     double pixelCurvature(const Plot &plot, double x, double y = 0);
0172     /**
0173      * \return the angle of the normal (in radians) of the plot when viewed
0174      * on the screen.
0175      */
0176     double pixelNormal(const Plot &plot, double x, double y = 0);
0177     /**
0178      * Animates zooming from the current zoom rect to the one given (in real
0179      * coordinates)
0180      */
0181     void animateZoom(const QRectF &newCoords);
0182 
0183     /// Methods for the Print Dialog to set options for drawing
0184     void setPrintHeaderTable(bool status);
0185     void setPrintBackground(bool status);
0186     void setPrintWidth(double width);
0187     void setPrintHeight(double height);
0188 
0189     /**
0190      * Which part of the status bar.
0191      */
0192     enum StatusBarSection {
0193         XSection = 0,
0194         YSection = 1,
0195         RootSection = 2,
0196         FunctionSection = 3,
0197         SectionCount = 4,
0198 
0199     };
0200 
0201     /**
0202      * Crosshair position in real coordinates
0203      */
0204     QPointF getCrosshairPosition() const;
0205 
0206 public slots:
0207     /// Called when the user want to cancel the drawing
0208     void stopDrawing();
0209 
0210     /// Called when the graph should be updated
0211     void drawPlot();
0212     /// Called when a function is deleted
0213     void functionRemoved(int id);
0214     /// Slots for the three first items in popup menu
0215     void hideCurrentFunction();
0216     void removeCurrentPlot();
0217     void editCurrentPlot();
0218     void animateFunction();
0219     /// Slots for the zoom menu
0220     void zoomIn();
0221     void zoomOut();
0222     void zoomToTrigonometric();
0223 
0224 protected slots:
0225     /// Unchecks menu item when the slider window is closed
0226     void sliderWindowClosed();
0227     /// Restore the mouse cursor when a drawing is finished
0228     void updateCursor();
0229 
0230 signals:
0231     void setStatusBarText(const QString &);
0232     void updateRootValue(bool haveRoot, double rootValue);
0233 
0234 protected:
0235     /// called when focus is lost
0236     void focusOutEvent(QFocusEvent *) Q_DECL_OVERRIDE;
0237     /// called when focus is gained
0238     void focusInEvent(QFocusEvent *) Q_DECL_OVERRIDE;
0239     void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
0240     void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;
0241     /// Updating the cross hair.
0242     void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
0243     /// Clearing the cross hair.
0244     void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
0245     /// Toggles the trace mode if the cursor is near to a plot.
0246     void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
0247     /// when a key is pressed and the graph widget has focus
0248     void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
0249     /// called when a mouse key is released
0250     void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
0251     /// called for zooming with Ctrl+mouse wheel
0252     void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
0253     /// Is needed to be reimplement so that the user can stop a preview-drawing
0254     bool event(QEvent *e) Q_DECL_OVERRIDE;
0255     /**
0256      * Updates csxpos and csypos from the current mouse position.
0257      * @return whether the crosshair is within the bounds of the diagram.
0258      */
0259     bool updateCrosshairPosition();
0260 
0261 private:
0262     /**
0263      * Fills the popup menu according to the currently selected plot.
0264      */
0265     void fillPopupMenu();
0266     /**
0267      * For using in automatic tic spacing. Given \p range (e.g. x_max-x_min)
0268      * and the \p length_mm (in millimeters), it aims to find a "nice"
0269      * spacing distance that is visually pleasing and also fits the base 10
0270      * number system in use (i.e. is a decimal multiple of 1, 2 or 5).
0271      */
0272     double niceTicSpacing(double length_mm, double range);
0273     /**
0274      * For using in manual tic spacing. Given a size in screen \p pixels for
0275      * the given \p range (e.g. x_max-x_min), make sure the \p spacing distance
0276      * is at least \p minPixels large. If zooming out too far, the spacing is
0277      * doubled until this conditions is met, effectively omitting tics. If zooming in
0278      * too far, the spacing is halved until at least two tics are visible, effectively
0279      * inserting additional tics.
0280      */
0281     double validatedTicSpacing(double spacing, double range, double pixels, double minPixels);
0282     /**
0283      * When zoomed in on part of a circle, it looks nearly straight. KmPlot
0284      * uses this to quickly draw curves that are mostly straight. Given the
0285      * curvature, this function returns the maximum length of line that can
0286      * be used to draw a part of a curve with the given curvature without
0287      * the curve starting to look jagged.
0288      */
0289     static double maxSegmentLength(double curvature);
0290     /**
0291      * \return an appropriate value to use in numerical differentiation.
0292      */
0293     double h(const Plot &plot) const;
0294     /**
0295      * Initializes the size, scaling, etc variables from the given paint
0296      * device.
0297      */
0298     void initDrawing(QPaintDevice *device, PlotMedium medium);
0299     /**
0300      * Print out table with additional information. Only for printing.
0301      */
0302     void drawHeaderTable(QPainter *);
0303     /// Draw the grid.
0304     void drawGrid(QPainter *);
0305     /**
0306      * Draw the axes.
0307      */
0308     void drawAxes(QPainter *painter);
0309     /**
0310      * Draw the axes' labels.
0311      */
0312     void drawLabels(QPainter *painter);
0313     /**
0314      * Draw the labels for the x-axis (this function is called from
0315      * drawLabels).
0316      * \a painter The QPainter to draw the labels with
0317      * \a endLabelWidth_mm the distance of the "x" label from the edge.
0318      */
0319     void drawXAxisLabels(QPainter *painter, double endLabelWidth_mm);
0320     /**
0321      * Draw the labels for the y-axis (this function is called from
0322      * drawLabels).
0323      */
0324     void drawYAxisLabels(QPainter *painter);
0325     /**
0326      * Draw a non-implicit function.
0327      */
0328     void drawFunction(Function *function, QPainter *painter);
0329     /**
0330      * Draw the function plots (other than implicit).
0331      */
0332     void drawPlot(const Plot &plot, QPainter *);
0333     /**
0334      * Draw the tangent field (for a differential function).
0335      */
0336     void drawTangentField(const Plot &plot, QPainter *painter);
0337     /**
0338      * Draw an implicit function.
0339      */
0340     void drawImplicit(Function *function, QPainter *);
0341     /**
0342      * Draw the extrema points, function names, etc. This needs to be done
0343      * after the functions have all been drawn so that the label positioning
0344      * knows where the plots have been drawn.
0345      */
0346     void drawFunctionInfo(QPainter *painter);
0347     /**
0348      * Initializes for the drawLabel function, called before drawing has
0349      * started.
0350      */
0351     void initDrawLabels();
0352     /**
0353      * Draw text (e.g. showing the value of an extrema point or a function
0354      * name) at the given (real) position.
0355      */
0356     void drawLabel(QPainter *painter, const QColor &color, const QPointF &realPos, const QString &text);
0357     /**
0358      * Used by plotImplicit to draw the plot in the square associated with
0359      * the given point.
0360      */
0361     void drawImplicitInSquare(const Plot &plot, QPainter *, double x, double y, Qt::Orientations orientation, QList<QPointF> *singular);
0362     /**
0363      * \return whether should draw the pixel from the given line length,
0364      * according to the given pen style (used in plotfkt).
0365      */
0366     bool penShouldDraw(double totalLength, const Plot &plot);
0367     /**
0368      * \return An appropriate pen for drawing the plot.
0369      */
0370     QPen penForPlot(const Plot &plot, QPainter *painter) const;
0371     /**
0372      * Used in findRoot.
0373      */
0374     enum RootAccuracy {
0375         PreciseRoot, ///< Will potential spend a long time finding a root to a high degree of accuracy
0376         RoughRoot, ///< Won't spend too long making a root accurate, giving up quickly if failed to find root
0377     };
0378     /**
0379      * Used in trace mode. Attempts to find the root of equation \p eq near
0380      * \p x (which is then set to the exact root if found).
0381      * \returns whether a root was found.
0382      */
0383     bool findRoot(double *x, const Plot &plot, RootAccuracy accuracy);
0384     /**
0385      * Equivalent function as above for implicit functions.
0386      */
0387     bool findRoot(double *x, double *y, const Plot &plot, RootAccuracy accuracy);
0388     /**
0389      * For use in the findRoot functions.
0390      * \p max_k maximum number of iterations
0391      * \p max_f the largest value of y which is deemed a root found
0392      */
0393     void setupFindRoot(const Plot &plot, RootAccuracy accuracy, double *max_k, double *max_f, int *n);
0394     /**
0395      * Finds the list of points (in function coordinates) at which the
0396      * derivative of the given plot is zero in the range of the currently
0397      * viewable segment of the plot.
0398      */
0399     QList<QPointF> findStationaryPoints(const Plot &plot);
0400     /**
0401      * Find all roots (at which the given plot is zero) in the range
0402      * [min,max].
0403      */
0404     QList<double> findRoots(const Plot &plot, double min, double max, RootAccuracy accuracy);
0405     /**
0406      * Changes the text in the statusbar.
0407      */
0408     void setStatusBar(const QString &text, StatusBarSection section);
0409     /**
0410      * \return whether the crosshairs should be shown for the current mouse
0411      * position, zoom mode, etc.
0412      */
0413     bool shouldShowCrosshairs() const;
0414     /**
0415      * Zooms in by amount \p zoomFactor (which will zooming out if less than 1)
0416      * from clicking at \p mousePos (in widget coordinates).
0417      */
0418     void zoomIn(const QPointF &mousePos, double zoomFactor);
0419     /**
0420      * Zooms in from having drawn \p zoomRect (which is in widget coordinates).
0421      */
0422     void zoomIn(const QRectF &zoomRect);
0423     /**
0424      * Zooms out from havoutg drawn \p zoomRect (which is out widget
0425      * coordinates).
0426      */
0427     void zoomOut(const QRectF &zoomRect);
0428     /**
0429      * Translates the view by \p dx, \p dy (in widget coordinates).
0430      */
0431     void translateView(int dx, int dy);
0432     /**
0433      * Finds the plot (if any) under the last mouse pos as recorded by
0434      * updateCrosshairPosition(). This sets csmode, cstype, csparam. If no plot
0435      * was found, then csmode is set to -1.
0436      * \return the function position of the closest plot if one was found.
0437      */
0438     QPointF getPlotUnderMouse();
0439     /**
0440      * Finds the closest point to \p pos (which is in real coordinates) to
0441      * the given function.
0442      * \return the parametization (angle, x or t) that gives the closest
0443      * point.
0444      */
0445     double getClosestPoint(const QPointF &pos, const Plot &plot);
0446     /**
0447      * Calculates the pixel distance from \p pos to the display point of the
0448      * given function at \p x.
0449      */
0450     double pixelDistance(const QPointF &pos, const Plot &plot, double x, bool updateFunction);
0451     /**
0452      * \param overlapEdge whether to give values that are slightly either
0453      * side of the view; this is useful for thick pens
0454      * \return an appropriate xmin value for the given function
0455      * plotting.
0456      */
0457     double getXmin(Function *function, bool overlapEdge = false);
0458     /**
0459      * \param overlapEdge whether to give values that are slightly either
0460      * side of the view; this is useful for thick pens
0461      * \return an appropriate xmax value for the given function for
0462      * plotting.
0463      */
0464     double getXmax(Function *function, bool overlapEdge = false);
0465 
0466     /**
0467      * How to behave in the *ToPixel functions.
0468      */
0469     enum ClipBehaviour {
0470         ClipAll, ///< Clips any points going over the edge of the diagram
0471         ClipInfinite, ///< Clips only infinite and NaN points going over the edge
0472     };
0473     /**
0474      * @name Transformations
0475      * These functions convert real coordinates to pixel coordinates and vice
0476      * versa.
0477      */
0478     double xToPixel(double x, ClipBehaviour clipBehaviour = ClipAll, double xIfNaN = 0);
0479     double yToPixel(double y, ClipBehaviour clipBehaviour = ClipAll, double yIfNaN = 0);
0480     QPointF toPixel(const QPointF &real, ClipBehaviour clipBehaviour = ClipAll, const QPointF &pixelIfNaN = QPointF());
0481     double xToReal(double x);
0482     double yToReal(double y);
0483     QPointF toReal(const QPointF &pixel);
0484     bool xclipflg; ///< clipflg is set to 1 if the plot is out of the plot area.
0485     bool yclipflg; ///< clipflg is set to 1 if the plot is out of the plot area.
0486     /**
0487      * Contains the settings for drawing the area under a graph (when
0488      * calculating the area from function tools.
0489      */
0490     IntegralDrawSettings m_integralDrawSettings;
0491     /**
0492      * Separation distance between the grid lines.
0493      */
0494     Value ticSepX, ticSepY;
0495     /**
0496      * Positions of the first grid line.
0497      */
0498     double ticStartX, ticStartY;
0499 
0500     /**
0501      * Mouse pointer previous for zooming.
0502      */
0503     QPoint m_previousMouseMovePos;
0504 
0505     QPointF m_crosshairPixelCoords;
0506     QPointF m_crosshairPosition; ///< in real coordinates
0507 
0508     /**
0509      * The t- or x- (angle) coordinate of the traced curve - when tracing a
0510      * polar or parametric curve.
0511      */
0512     double m_trace_x;
0513     /**
0514      * When tracing a Cartesian plot and the trace position nears the
0515      * x-axis, an attempt to find a root will be found. If found, this will
0516      * be set to true, and no further attempts will be made at finding a
0517      * root. Once the plot position moves away from the x-axis again, this
0518      * will be set to false.
0519      */
0520     bool m_haveRoot;
0521 
0522     /// @return whether cspos is in the range of the view or in the custom range for the given \p plot
0523     bool crosshairPositionValid(Function *plot) const;
0524 
0525     /// represents the Printer options set by user in the Print Dialog
0526     /// @see KPrinterDlg
0527     bool m_printHeaderTable;
0528     bool m_printBackground;
0529     double m_printWidth;
0530     double m_printHeight;
0531     /// if stop_calculating is true, the user has canceled drawing of an integral graph
0532     bool m_stopCalculating;
0533     /// the background color of the graph
0534     QColor m_backgroundColor;
0535     /// buffer the current window so all functions don't need to be re-drawn
0536     QPixmap buffer;
0537     /// the popup menu
0538     QMenu *m_popupMenu;
0539     /// The pointer to the popup menu's title
0540     QAction *m_popupMenuTitle;
0541     /// is set to true if an integral is calculated
0542     bool m_isDrawing;
0543     /**
0544      * Describes the state of the popup menu.
0545      */
0546     enum PopupStatus {
0547         NoPopup,
0548         Popup,
0549         PopupDuringTrace,
0550     };
0551     /// status of the popup menu
0552     PopupStatus m_popupMenuStatus;
0553     /// False if KmPlot is started as a program, otherwise true
0554     bool const m_readonly;
0555     /// For drawing diagram labels
0556     QFont m_labelFont;
0557     /**
0558      * The resolution of label positioning.
0559      */
0560     static const int LabelGridSize = 50;
0561     /**
0562      * Indicate which parts of the diagram have content (e.g. axis or
0563      * plots), so that they can be avoided when drawing diagram labels
0564      */
0565     bool m_usedDiagramArea[LabelGridSize][LabelGridSize];
0566     /**
0567      * Marks the given diagram rectangle (in screen coords) as 'used'.
0568      */
0569     void markDiagramAreaUsed(const QRectF &rect);
0570     /**
0571      * Marks the given diagram point (in screen coords) as 'used'.
0572      */
0573     void markDiagramPointUsed(const QPointF &point);
0574     /**
0575      * \return the m_usedDiagramArea coords for the screen rect.
0576      */
0577     QRect usedDiagramRect(const QRectF &rect) const;
0578     /**
0579      * \return the cost of occupying the given rectangle (as in whether it
0580      * overlaps other diagram content, etc).
0581      */
0582     int rectCost(QRectF rect) const;
0583 
0584     enum ZoomMode {
0585         Normal, ///< no zooming
0586         AnimatingZoom, ///< animating a current zooming
0587         ZoomIn, ///< zoom in
0588         ZoomOut, ///< zoom out
0589         ZoomInDrawing, ///< drawing a rectangle for zooming in
0590         ZoomOutDrawing, ///< drawing a rectangle for zooming out
0591         AboutToTranslate, ///< user has clicked on an empty spot, but hasn't moved the mouse yet
0592         Translating, ///< dragging the view with the mouse
0593     };
0594 
0595     /// The current editing status
0596     ZoomMode m_zoomMode;
0597     /// for zoom-mode
0598     QPoint m_zoomRectangleStart;
0599     /// for animating zoom; contains the rectangle (in real coordinates) to draw
0600     QRectF m_animateZoomRect;
0601     /// for translating the view via dragging
0602     QPoint m_prevDragMousePos;
0603     /// timer that is started when the mouse is pressed
0604     QElapsedTimer *m_mousePressTimer;
0605     /** Current plot viewport. */
0606     const QRectF getViewport();
0607 
0608     /**
0609      * The rectangle (in painter, and hence pixel, coordinates) that the
0610      * plots must be in. This is also the size of the image being drawn to,
0611      * since the painter remains untransformed.
0612      */
0613     QRect m_clipRect;
0614     /**
0615      * This matrix transforms from real coordinates to painter coordinates.
0616      * (Note that the painter does not have any transformation applied).
0617      */
0618     QTransform m_realToPixel;
0619     /**
0620      * The inverse matrix of m_realToPixel; it maps from pixel coordinates
0621      * to real X-Y coordinates.
0622      */
0623     QTransform m_pixelToReal;
0624 
0625     QString m_statusBarText[4];
0626 
0627     enum Cursor {
0628         CursorWait,
0629         CursorBlank,
0630         CursorArrow,
0631         CursorCross,
0632         CursorMagnify,
0633         CursorLessen,
0634         CursorMove,
0635     };
0636     Cursor m_prevCursor;
0637 
0638     static View *m_self;
0639 
0640     KTextEdit *m_textEdit; ///< Contains m_textDocument
0641     QTextDocument *m_textDocument; ///< Used for layout of axis labels
0642 
0643     /// Accumulates mouse or trackpad scrolling to enable Ctrl+mouse wheel scaling on faulty devices
0644     int m_AccumulatedDelta;
0645 
0646     /// Animation for the viewport
0647     QPropertyAnimation *m_viewportAnimation;
0648 
0649     /// Finishes animation of the viewport and get the View back to the Normal mode
0650     void finishAnimation(const QRectF &rect);
0651 
0652 private slots:
0653     void setViewport(const QRectF &rect);
0654 };
0655 
0656 #endif // View_included