182 lines
5.9 KiB
C++
182 lines
5.9 KiB
C++
#ifndef __DW_IMAGE_HH__
|
|
#define __DW_IMAGE_HH__
|
|
|
|
#include "core.hh"
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
namespace dw {
|
|
|
|
/**
|
|
* \brief Represents a list of client-side image maps.
|
|
*
|
|
* All image maps of a HTML page (in the future, also image maps from
|
|
* different HTML pages) are stored in a list, which is passed to the
|
|
* image, so that it is possible to deal with maps, which are defined
|
|
* after the image within the HTML page.
|
|
*
|
|
* Maps are referred by instances of object::Object. These keys are
|
|
* typically URLs, so the type representing URLS should be derived from
|
|
* object::Object.
|
|
*
|
|
* \todo Some methods within the key class have to be implemented, this
|
|
* is not clear at this time.
|
|
*/
|
|
class ImageMapsList
|
|
{
|
|
private:
|
|
class ImageMap: public lout::object::Object {
|
|
private:
|
|
class ShapeAndLink: public lout::object::Object {
|
|
public:
|
|
std::unique_ptr< core::Shape > shape;
|
|
int link;
|
|
};
|
|
|
|
std::list< std::unique_ptr< ShapeAndLink > > shapesAndLinks;
|
|
int defaultLink= -1;
|
|
|
|
public:
|
|
void draw (core::View *view, core::style::Style *style, int x, int y);
|
|
void add (std::unique_ptr< core::Shape > shape, int link);
|
|
void setDefaultLink (int link) { defaultLink = link; };
|
|
int link (int x, int y);
|
|
};
|
|
|
|
lout::container::typed::HashTable <lout::object::Object, ImageMap>
|
|
*imageMaps;
|
|
ImageMap *currentMap;
|
|
|
|
public:
|
|
ImageMapsList ();
|
|
~ImageMapsList ();
|
|
|
|
void startNewMap (lout::object::Object *key);
|
|
void addShapeToCurrentMap( std::unique_ptr< core::Shape > shape, int link );
|
|
void setCurrentMapDefaultLink (int link);
|
|
void drawMap(lout::object::Object *key, core::View *view,
|
|
core::style::Style *style, int x, int y);
|
|
int link (lout::object::Object *key, int x, int y);
|
|
};
|
|
|
|
/**
|
|
* \brief Displays an instance of dw::core::Imgbuf.
|
|
*
|
|
* The dw::core::Imgbuf is automatically scaled, when needed, but dw::Image
|
|
* does not keep a reference on the root buffer.
|
|
*
|
|
*
|
|
* <h3>Signals</h3>
|
|
*
|
|
* For image maps, dw::Image uses the signals defined in
|
|
* dw::core::Layout::LinkReceiver. For client side image maps, -1 is
|
|
* passed for the coordinates, for server side image maps, the respective
|
|
* coordinates are used. See section "Image Maps" below.
|
|
*
|
|
*
|
|
* <h3>%Image Maps</h3>
|
|
*
|
|
* <h4>Client Side %Image Maps</h4>
|
|
*
|
|
* You must first create a list of image maps (dw::ImageMapList), which can
|
|
* be used for multiple images. The caller is responsible for freeing the
|
|
* dw::ImageMapList.
|
|
*
|
|
* Adding a map is done by dw::ImageMapsList::startNewMap. The key is an
|
|
* instance of a sub class of object::Object. In the context of HTML, this is
|
|
* a URL, which defines this map globally, by combining the URL of the
|
|
* document, this map is defined in, with the value of the attribute "name" of
|
|
* the \<MAP\> element, as a fragment.
|
|
*
|
|
* dw::ImageMapsList::addShapeToCurrentMap adds a shape to the current
|
|
* map. The \em link argument is a number, which is later passed to
|
|
* the dw::core::Layout::LinkReceiver.
|
|
*
|
|
* This map list is then, together with the key for the image, passed to
|
|
* dw::Image::setUseMap. For HTML, a URL with the value of the "ismap"
|
|
* attribute of \<IMG\> should be used.
|
|
*
|
|
* dw::Image will search the correct map, when needed. If it is not found
|
|
* at this time, but later defined, it will be found and used later. This is
|
|
* the case, when an HTML \<MAP\> is defined below the \<IMG\> in the
|
|
* document.
|
|
*
|
|
* Currently, only maps defined in the same document as the image may be
|
|
* used, since the dw::ImageMapsList is stored in the HTML link block, and
|
|
* contains only the image maps defined in the document.
|
|
*
|
|
* <h4>Server Side %Image Maps</h4>
|
|
*
|
|
* To use images for server side image maps, you must call
|
|
* dw::Image::setIsMap, and the dw::Image::style must contain a valid link
|
|
* (dw::core::style::Style::x_link). After this, motions and clicks are
|
|
* delegated to dw::core::Layout::LinkReceiver.
|
|
*
|
|
* \sa\ref dw-images-and-backgrounds
|
|
*/
|
|
class Image: public core::Widget, public core::ImgRenderer
|
|
{
|
|
private:
|
|
std::optional< std::string > altText;
|
|
core::Imgbuf *buffer;
|
|
int bufWidth, bufHeight;
|
|
int altTextWidth;
|
|
bool clicking;
|
|
int currLink;
|
|
ImageMapsList *mapList;
|
|
Object *mapKey;
|
|
bool isMap;
|
|
|
|
protected:
|
|
void sizeRequestSimpl (core::Requisition *requisition);
|
|
void getExtremesSimpl (core::Extremes *extremes);
|
|
void sizeAllocateImpl (core::Allocation *allocation);
|
|
void containerSizeChangedForChildren ();
|
|
|
|
void draw (core::View *view, core::Rectangle *area,
|
|
core::DrawingContext *context);
|
|
|
|
bool buttonPressImpl (core::EventButton *event);
|
|
bool buttonReleaseImpl (core::EventButton *event);
|
|
void enterNotifyImpl (core::EventCrossing *event);
|
|
void leaveNotifyImpl (core::EventCrossing *event);
|
|
bool motionNotifyImpl (core::EventMotion *event);
|
|
int contentX (core::MousePositionEvent *event);
|
|
int contentY (core::MousePositionEvent *event);
|
|
|
|
//core::Iterator *iterator (Content::Type mask, bool atEnd);
|
|
|
|
public:
|
|
Image(std::optional< std::string_view > altText);
|
|
~Image();
|
|
|
|
// For images, the minimal width is not well defined, and
|
|
// correction of the size makes not much sense.
|
|
virtual bool getAdjustMinWidth () { return false; }
|
|
|
|
core::Iterator *iterator (core::Content::Type mask, bool atEnd);
|
|
|
|
inline core::Imgbuf *getBuffer () { return buffer; }
|
|
void setBuffer (core::Imgbuf *buffer, bool resize = false);
|
|
|
|
void drawRow (int row);
|
|
|
|
void finish ();
|
|
void fatal ();
|
|
|
|
void setIsMap ();
|
|
void setUseMap (ImageMapsList *list, Object *key);
|
|
|
|
/* This is a hack for the perhaps frivolous feature of drawing image map
|
|
* shapes when there is no image to display. If the map is defined after
|
|
* an image using an image map, and the actual image data has not been
|
|
* loaded, tell the image to redraw.
|
|
*/
|
|
void forceMapRedraw () { if (mapKey && ! buffer) queueDraw (); };
|
|
};
|
|
|
|
} // namespace dw
|
|
|
|
#endif // __DW_IMAGE_HH__
|