Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing UI functions for X11 Window class #580

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
60 changes: 55 additions & 5 deletions src/ui/x11/x11_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,42 @@ void UiWindowX11::_display()
XPutImage( _uiDisplay, _window, defaultGC, _image, 0, 0, 0, 0, _width, _height );

for ( size_t i = 0u; i < _point.size(); ++i ) {
const Point2d & point = _point[i].first;
XSetForeground( _uiDisplay, defaultGC, _point[i].second );
XDrawLine( _uiDisplay, _window, defaultGC, static_cast<int>(point.x - 1), static_cast<int>(point.y - 1),
static_cast<int>(point.x + 1), static_cast<int>(point.y + 1) );
const Point2d & point = _point[i].point;
XSetForeground( _uiDisplay, defaultGC, _point[i].color );
XDrawLine( _uiDisplay, _window, defaultGC, static_cast<int>( point.x - 1 ), static_cast<int>( point.y - 1 ), static_cast<int>( point.x + 1 ),
ihhub marked this conversation as resolved.
Show resolved Hide resolved
static_cast<int>( point.y + 1 ) );
}

for ( size_t i = 0u; i < _lines.size(); ++i ) {
const Point2d & start = _lines[i].start;
const Point2d & end = _lines[i].end;
const uint32_t & foreground = _lines[i].color;

XSetForeground( _uiDisplay, defaultGC, foreground );
XDrawLine( _uiDisplay, _window, defaultGC, static_cast<int>( start.x ), static_cast<int>( start.y ), static_cast<int>( end.x ),
static_cast<int>( end.y ) );
}

for ( size_t i = 0u; i < _ellipses.size(); ++i ) {
const Point2d & position = _ellipses[i].topLeft;
const double & width = _ellipses[i].width;
const double & height = _ellipses[i].height;
const uint32_t & foreground = _ellipses[i].color;

XSetForeground( _uiDisplay, defaultGC, foreground );
XDrawArc( _uiDisplay, _window, defaultGC, static_cast<int>( position.x ), static_cast<int>( position.y ), static_cast<int>( width ),
static_cast<int>( height ), 0, 360 * 64 );
}

for ( size_t i = 0u; i < _rectangles.size(); ++i ) {
const Point2d & topLeft = _rectangles[i].topLeft;
const double & width = _rectangles[i].width;
const double & height = _rectangles[i].height;
const uint32_t & foreground = _rectangles[i].color;

XSetForeground( _uiDisplay, defaultGC, foreground );
XDrawRectangle( _uiDisplay, _window, defaultGC, static_cast<int>( topLeft.x ), static_cast<int>( topLeft.y ), static_cast<int>( width ),
static_cast<int>( height ) );
}
}
else if ( (e.type == ClientMessage) && (static_cast<unsigned int>(e.xclient.data.l[0]) == _deleteWindowEvent) )
Expand Down Expand Up @@ -109,7 +141,25 @@ void UiWindowX11::_setupImage( const penguinV::Image & image )

void UiWindowX11::drawPoint( const Point2d & point, const PaintColor & color )
{
_point.push_back( std::make_pair( point, (color.red << 16) + (color.green << 8) + color.blue ) );
_point.push_back( PointToDraw( point, ( color.red << 16 ) + ( color.green << 8 ) + color.blue ) );
}

void UiWindowX11::drawLine( const Point2d & start, const Point2d & end, const PaintColor & color )
{
_lines.push_back( LineToDraw( start, end, ( color.red << 16 ) + ( color.green << 8 ) + color.blue ) );
}

void UiWindowX11::drawEllipse( const Point2d & center, double xRadius, double yRadius, const PaintColor & color )
{
// XDrawArc needs x and y coordinates of the upper-left corner of the bounding rectangle but not the center of the ellipse.
const Point2d position( center.x - xRadius, center.y - yRadius );

_ellipses.push_back( EllipseToDraw( position, xRadius * 2, yRadius * 2, ( color.red << 16 ) + ( color.green << 8 ) + color.blue ) );
}

void UiWindowX11::drawRectangle( const Point2d & topLeftCorner, double width, double height, const PaintColor & color )
{
_rectangles.push_back( RectangleToDraw( topLeftCorner, width, height, ( color.red << 16 ) + ( color.green << 8 ) + color.blue ) );
}

#endif
63 changes: 62 additions & 1 deletion src/ui/x11/x11_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class UiWindowX11 : public UiWindow
virtual ~UiWindowX11();

virtual void drawPoint( const Point2d & point, const PaintColor & color );
virtual void drawLine( const Point2d & start, const Point2d & end, const PaintColor & color );
virtual void drawEllipse( const Point2d & center, double xRadius, double yRadius, const PaintColor & color );
virtual void drawRectangle( const Point2d & topLeftCorner, double width, double height, const PaintColor & color );

protected:
virtual void _display();
private:
Expand All @@ -26,7 +30,64 @@ class UiWindowX11 : public UiWindow
uint32_t _width;
uint32_t _height;

std::vector< std::pair<Point2d, uint32_t> > _point;
struct PointToDraw
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @fullset could we move these identical structures in a common location as src/ui/ui.h file to avoid code duplication?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I see, there are 2 structures PointToDraw and LineToDraw which are almost identical in x11 and win_ui. And there are no problem to combine them.

But EllipseToDraw structures in x11 and win_ui have different semantics. In win_ui we specify top, left, right and bottom coordinates but it x11 we specify top, left coordinates and width and height. I could make common constructor of 4 doubles but I'm not sure that it's right decision. What do you think?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick to one design which should have top-left coordinate and width with height. For Windows during drawing we could easily find right and bottom values by adding width and height.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, @ihhub.

It looks like I've broken windows building by my last changes but I can't find the reason because I haven't windows PC.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me check...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you put structures back in ui/ui.h but don't declare these variables:

    std::vector<PointToDraw> _point;
    std::vector<LineToDraw> _lines;
    std::vector<EllipseToDraw> _ellipses;

?

{
PointToDraw( const Point2d & point_ = Point2d(), uint32_t color_ = 0 )
: point( point_ )
, color( color_ )
{}

Point2d point;
uint32_t color;
};

struct LineToDraw
{
LineToDraw( const Point2d & start_ = Point2d(), const Point2d & end_ = Point2d(), uint32_t color_ = 0 )
: start( start_ )
, end( end_ )
, color( color_ )
{}

Point2d start;
Point2d end;
uint32_t color;
};

struct EllipseToDraw
{
EllipseToDraw( const Point2d & topLeft_ = Point2d(), double width_ = 0.0, double height_ = 0.0, uint32_t color_ = 0 )
: topLeft( topLeft_ )
, width( width_ )
, height( height_ )
, color( color_ )
{}

Point2d topLeft;
double width;
double height;
uint32_t color;
};

struct RectangleToDraw
{
RectangleToDraw( const Point2d & topLeft_ = Point2d(), double width_ = 0.0, double height_ = 0.0, uint32_t color_ = 0 )
: topLeft( topLeft_ )
, width( width_ )
, height( height_ )
, color( color_ )
{}

Point2d topLeft;
double width;
double height;
uint32_t color;
};

std::vector<PointToDraw> _point;
std::vector<LineToDraw> _lines;
std::vector<EllipseToDraw> _ellipses;
std::vector<RectangleToDraw> _rectangles;

void _setupImage( const penguinV::Image & image );
};
Expand Down