diff options
31 files changed, 196 insertions, 342 deletions
| diff --git a/plugin/drumgizmo_plugin.cc b/plugin/drumgizmo_plugin.cc index 091492f..3db72c1 100644 --- a/plugin/drumgizmo_plugin.cc +++ b/plugin/drumgizmo_plugin.cc @@ -185,12 +185,11 @@ public:  	{  	} -	GUI::PixelBufferAlpha& GetPixelBuffer() +	// From Canvas: +	GUI::PixelBufferAlpha& GetPixelBuffer() override  	{  		return pixbuf;  	} -	void beginPaint() {} -	void endPaint() {}  private:  	InlinePixelBufferAlpha pixbuf; diff --git a/plugingui/button.cc b/plugingui/button.cc index 29d3deb..fb25390 100644 --- a/plugingui/button.cc +++ b/plugingui/button.cc @@ -57,14 +57,14 @@ void Button::buttonEvent(ButtonEvent* buttonEvent)  		draw_state = down;  		button_state = down;  		in_button = true; -		repaintEvent(nullptr); +		redraw();  	}  	if(buttonEvent->direction == Direction::up)  	{  		draw_state = up;  		button_state = up; -		repaintEvent(nullptr); +		redraw();  		if(in_button)  		{  			clicked(); @@ -110,7 +110,7 @@ void Button::repaintEvent(RepaintEvent* repaintEvent)  void Button::setText(const std::string& text)  {  	this->text = text; -	repaintEvent(nullptr); +	redraw();  }  void Button::mouseLeaveEvent() @@ -119,7 +119,7 @@ void Button::mouseLeaveEvent()  	if(button_state == down)  	{  		draw_state = up; -		repaintEvent(nullptr); +		redraw();  	}  } @@ -129,7 +129,7 @@ void Button::mouseEnterEvent()  	if(button_state == down)  	{  		draw_state = down; -		repaintEvent(nullptr); +		redraw();  	}  } diff --git a/plugingui/canvas.h b/plugingui/canvas.h index cafe483..2326f0e 100644 --- a/plugingui/canvas.h +++ b/plugingui/canvas.h @@ -39,14 +39,6 @@ public:  	//! @returns a reference to the pixel buffer.  	virtual PixelBufferAlpha& GetPixelBuffer() = 0; - -	//! Signal the beginning of a paint operation. -	virtual void beginPaint() = 0; - -	//! Signal the ending of a paint operation -	//! This might trigger a redraw operation. -	virtual void endPaint() = 0; -  };  } // GUI:: diff --git a/plugingui/checkbox.cc b/plugingui/checkbox.cc index bada623..2a17635 100644 --- a/plugingui/checkbox.cc +++ b/plugingui/checkbox.cc @@ -62,13 +62,13 @@ void CheckBox::buttonEvent(ButtonEvent* buttonEvent)  		middle = true;  	} -	repaintEvent(nullptr); +	redraw();  }  void CheckBox::setText(std::string text)  {  	_text = text; -	repaintEvent(nullptr); +	redraw();  }  void CheckBox::keyEvent(KeyEvent* keyEvent) @@ -85,7 +85,7 @@ void CheckBox::keyEvent(KeyEvent* keyEvent)  			middle = true;  		} -		repaintEvent(nullptr); +		redraw();  	}  } @@ -129,7 +129,7 @@ void CheckBox::mouseLeaveEvent()  	if(buttonDown)  	{  		middle = false; -		repaintEvent(nullptr); +		redraw();  	}  } @@ -139,7 +139,7 @@ void CheckBox::mouseEnterEvent()  	if(buttonDown)  	{  		middle = true; -		repaintEvent(nullptr); +		redraw();  	}  } @@ -152,7 +152,7 @@ void CheckBox::internalSetChecked(bool checked)  	state = checked;  	stateChangedNotifier(state); -	repaintEvent(nullptr); +	redraw();  }  } // GUI:: diff --git a/plugingui/combobox.cc b/plugingui/combobox.cc index ffbde88..82fc6d1 100644 --- a/plugingui/combobox.cc +++ b/plugingui/combobox.cc @@ -65,13 +65,13 @@ void ComboBox::addItem(std::string name, std::string value)  void ComboBox::clear()  {  	listbox.clear(); -	repaintEvent(nullptr); +	redraw();  }  bool ComboBox::selectItem(int index)  {  	listbox.selectItem(index); -	repaintEvent(nullptr); +	redraw();  	return true;  } @@ -143,7 +143,7 @@ void ComboBox::scrollEvent(ScrollEvent* scrollEvent)  	{  		scroll_offset = (items.size() - 1);  	} -	repaintEvent(nullptr); +	redraw();  	*/  } @@ -203,7 +203,7 @@ void ComboBox::keyEvent(KeyEvent* keyEvent)  		break;  	} -	repaintEvent(nullptr); +	redraw();  	*/  } diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc index aded993..2cdb6b1 100644 --- a/plugingui/eventhandler.cc +++ b/plugingui/eventhandler.cc @@ -56,21 +56,8 @@ std::shared_ptr<Event> EventHandler::getNextEvent()  	return event;  } -std::shared_ptr<Event> EventHandler::peekNextEvent() -{ -	if(events.empty()) -	{ -		return nullptr; -	} - -	auto event = events.front(); -	return event; -} -  void EventHandler::processEvents()  { -	Painter p(window); // Make sure we only redraw buffer one time. -  	events = nativeWindow.getEvents();  	while(hasEvent()) @@ -96,26 +83,6 @@ void EventHandler::processEvents()  		case EventType::resize:  			{ -				while(true) -				{ -					if(!hasEvent()) -					{ -						break; -					} - -					auto peekEvent = peekNextEvent(); -					if(!peekEvent) -					{ -						break; -					} -					if(peekEvent->type() != EventType::resize) -					{ -						break; -					} - -					event = getNextEvent(); -				} -  				auto resizeEvent = static_cast<ResizeEvent*>(event.get());  				if((resizeEvent->width != window.width()) ||  				   (resizeEvent->height != window.height())) @@ -134,16 +101,6 @@ void EventHandler::processEvents()  						break;  					} -					auto peekEvent = peekNextEvent(); -					if(!peekEvent) -					{ -						break; -					} -					if(peekEvent->type() != EventType::mouseMove) -					{ -						break; -					} -  					event = getNextEvent();  				} @@ -171,8 +128,8 @@ void EventHandler::processEvents()  				if(window.buttonDownFocus())  				{  					auto widget = window.buttonDownFocus(); -					moveEvent->x -= widget->windowX(); -					moveEvent->y -= widget->windowY(); +					moveEvent->x -= widget->translateToWindowX(); +					moveEvent->y -= widget->translateToWindowY();  					window.buttonDownFocus()->mouseMoveEvent(moveEvent);  					break; @@ -180,8 +137,8 @@ void EventHandler::processEvents()  				if(widget)  				{ -					moveEvent->x -= widget->windowX(); -					moveEvent->y -= widget->windowY(); +					moveEvent->x -= widget->translateToWindowX(); +					moveEvent->y -= widget->translateToWindowY();  					widget->mouseMoveEvent(moveEvent);  				}  			} @@ -206,8 +163,8 @@ void EventHandler::processEvents()  					if(buttonEvent->direction == Direction::up)  					{  						auto widget = window.buttonDownFocus(); -						buttonEvent->x -= widget->windowX(); -						buttonEvent->y -= widget->windowY(); +						buttonEvent->x -= widget->translateToWindowX(); +						buttonEvent->y -= widget->translateToWindowY();  						widget->buttonEvent(buttonEvent);  						window.setButtonDownFocus(nullptr); @@ -217,8 +174,8 @@ void EventHandler::processEvents()  				if(widget)  				{ -					buttonEvent->x -= widget->windowX(); -					buttonEvent->y -= widget->windowY(); +					buttonEvent->x -= widget->translateToWindowX(); +					buttonEvent->y -= widget->translateToWindowY();  					widget->buttonEvent(buttonEvent); @@ -238,38 +195,13 @@ void EventHandler::processEvents()  		case EventType::scroll:  			{ -				int delta = 0; -				while(true) -				{ -					if(!hasEvent()) -					{ -						break; -					} - -					auto peekEvent = peekNextEvent(); -					if(!peekEvent) -					{ -						break; -					} -					if(peekEvent->type() != EventType::scroll) -					{ -						break; -					} - -					auto scrollEvent = static_cast<ScrollEvent*>(event.get()); -					delta += scrollEvent->delta; - -					event = getNextEvent(); -				} -  				auto scrollEvent = static_cast<ScrollEvent*>(event.get()); -				scrollEvent->delta += delta;  				auto widget = window.find(scrollEvent->x, scrollEvent->y);  				if(widget)  				{ -					scrollEvent->x -= widget->windowX(); -					scrollEvent->y -= widget->windowY(); +					scrollEvent->x -= widget->translateToWindowX(); +					scrollEvent->y -= widget->translateToWindowY();  					widget->scrollEvent(scrollEvent);  				} @@ -294,6 +226,10 @@ void EventHandler::processEvents()  			break;  		}  	} + +	// Probe window and children to readrw as needed. +	// NOTE: This method will invoke native->redraw() if a redraw is needed. +	window.updateBuffer();  }  } // GUI:: diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h index 2a1b657..7e9966c 100644 --- a/plugingui/eventhandler.h +++ b/plugingui/eventhandler.h @@ -53,10 +53,6 @@ public:  	//! \return A pointer to the event or nullptr if there are none.  	std::shared_ptr<Event> getNextEvent(); -	//! \brief Get a single event from the event queue without popping it. -	//! \return A pointer to the event or nullptr if there are none. -	std::shared_ptr<Event> peekNextEvent(); -  	Notifier<> closeNotifier;  private: diff --git a/plugingui/knob.cc b/plugingui/knob.cc index 87779ec..0655a68 100644 --- a/plugingui/knob.cc +++ b/plugingui/knob.cc @@ -203,7 +203,7 @@ void Knob::internalSetValue(float value)  	currentValue = value;  	valueChangedNotifier(currentValue); -	repaintEvent(nullptr); +	redraw();  }  } // GUI:: diff --git a/plugingui/label.cc b/plugingui/label.cc index 2ff4f36..781dbca 100644 --- a/plugingui/label.cc +++ b/plugingui/label.cc @@ -39,7 +39,7 @@ Label::Label(Widget *parent)  void Label::setText(const std::string& text)  {  	_text = text; -	repaintEvent(nullptr); +	redraw();  }  void Label::setAlignment(TextAlignment alignment) diff --git a/plugingui/layout.h b/plugingui/layout.h index bd64fdd..4d20eb6 100644 --- a/plugingui/layout.h +++ b/plugingui/layout.h @@ -46,10 +46,10 @@ public:  	virtual void resize(std::size_t width, std::size_t height) = 0;  	virtual void move(int x, int y) = 0; -	virtual int x() = 0; -	virtual int y() = 0; -	virtual std::size_t width() = 0; -	virtual std::size_t height() = 0; +	virtual int x() const = 0; +	virtual int y() const = 0; +	virtual std::size_t width() const = 0; +	virtual std::size_t height() const = 0;  private:  	Layout* parent; diff --git a/plugingui/led.cc b/plugingui/led.cc index 03ea661..f77e31a 100644 --- a/plugingui/led.cc +++ b/plugingui/led.cc @@ -41,7 +41,7 @@ void LED::setState(state_t state)  	if(this->state != state)  	{  		this->state = state; -		repaintEvent(nullptr); +		redraw();  	}  } diff --git a/plugingui/lineedit.cc b/plugingui/lineedit.cc index c213041..7a8bb53 100644 --- a/plugingui/lineedit.cc +++ b/plugingui/lineedit.cc @@ -61,7 +61,7 @@ void LineEdit::setText(const std::string& text)  	visibleText = _text;  	offsetPos = 0; -	repaintEvent(nullptr); +	redraw();  	textChanged();  } @@ -94,7 +94,7 @@ void LineEdit::buttonEvent(ButtonEvent *buttonEvent)  				break;  			}  		} -		repaintEvent(nullptr); +		redraw();  	}  } @@ -189,7 +189,7 @@ void LineEdit::keyEvent(KeyEvent *keyEvent)  			break;  		} -		repaintEvent(nullptr); +		redraw();  	}  	if(change) diff --git a/plugingui/listboxbasic.cc b/plugingui/listboxbasic.cc index 730880a..642d03f 100644 --- a/plugingui/listboxbasic.cc +++ b/plugingui/listboxbasic.cc @@ -88,7 +88,7 @@ void ListBoxBasic::addItems(const std::vector<ListBoxBasic::Item>& newItems)  	int numitems = height() / (font.textHeight() + padding);  	scroll.setRange(numitems);  	scroll.setMaximum(items.size()); -	repaintEvent(nullptr); +	redraw();  }  void ListBoxBasic::clear() @@ -97,7 +97,7 @@ void ListBoxBasic::clear()  	setSelection(-1);  	marked = -1;  	scroll.setValue(0); -	repaintEvent(nullptr); +	redraw();  }  bool ListBoxBasic::selectItem(int index) @@ -108,7 +108,7 @@ bool ListBoxBasic::selectItem(int index)  	}  	setSelection(index); -	repaintEvent(nullptr); +	redraw();  	return true;  } @@ -140,7 +140,7 @@ void ListBoxBasic::clearSelectedValue()  void ListBoxBasic::onScrollBarValueChange(int value)  { -	repaintEvent(nullptr); +	redraw();  }  void ListBoxBasic::repaintEvent(RepaintEvent* repaintEvent) @@ -277,7 +277,7 @@ void ListBoxBasic::keyEvent(KeyEvent* keyEvent)  		break;  	} -	repaintEvent(nullptr); +	redraw();  }  void ListBoxBasic::buttonEvent(ButtonEvent* buttonEvent) @@ -329,7 +329,7 @@ void ListBoxBasic::buttonEvent(ButtonEvent* buttonEvent)  			}  		} -		repaintEvent(nullptr); +		redraw();  	}  	if(buttonEvent->direction != Direction::up) @@ -346,7 +346,7 @@ void ListBoxBasic::buttonEvent(ButtonEvent* buttonEvent)  			}  		} -		repaintEvent(nullptr); +		redraw();  	}  	if(buttonEvent->doubleClick) diff --git a/plugingui/mainwindow.cc b/plugingui/mainwindow.cc index 3a1727f..3b951f5 100644 --- a/plugingui/mainwindow.cc +++ b/plugingui/mainwindow.cc @@ -50,13 +50,9 @@ bool MainWindow::processEvents()  //		return running;  //	} +	settings_notifier.evaluate();  	eventHandler()->processEvents(); -	{ -		Painter p(*this); -		settings_notifier.evaluate(); -	} -  	if(closing)  	{  		closeNotifier(); diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h index e041994..7b7fd39 100644 --- a/plugingui/nativewindow.h +++ b/plugingui/nativewindow.h @@ -69,10 +69,6 @@ public:  	//! Sets the window caption in the title bar (if it has one).  	virtual void setCaption(const std::string &caption) = 0; -	//! Recreate a window render buffer based on the internal buffer. -	//! This need to be called whenever the internal buffer size has changed. -	virtual void handleBuffer() = 0; -  	//! Draw the internal rendering buffer to the window buffer.  	virtual void redraw() = 0; diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc index 23c9012..669ec13 100644 --- a/plugingui/nativewindow_win32.cc +++ b/plugingui/nativewindow_win32.cc @@ -379,10 +379,6 @@ void NativeWindowWin32::show()  	ShowWindow(m_hwnd, SW_SHOW);  } -void NativeWindowWin32::handleBuffer() -{ -} -  void NativeWindowWin32::hide()  {  	ShowWindow(m_hwnd, SW_HIDE); @@ -390,6 +386,7 @@ void NativeWindowWin32::hide()  void NativeWindowWin32::redraw()  { +	// Send WM_PAINT message. Buffer transfering is handled in MessageHandler.  	if(parent_window == nullptr)  	{  		RedrawWindow(m_hwnd, nullptr, nullptr, RDW_ERASE|RDW_INVALIDATE); diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h index b8e1c89..69324e3 100644 --- a/plugingui/nativewindow_win32.h +++ b/plugingui/nativewindow_win32.h @@ -52,7 +52,6 @@ public:  	void show() override;  	void setCaption(const std::string &caption) override;  	void hide() override; -	void handleBuffer() override;  	void redraw() override;  	void grabMouse(bool grab) override;  	EventQueue getEvents() override; diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc index bf18ffa..80c0e81 100644 --- a/plugingui/nativewindow_x11.cc +++ b/plugingui/nativewindow_x11.cc @@ -223,11 +223,6 @@ void NativeWindowX11::hide()  	XUnmapWindow(display, xwindow);  } -void NativeWindowX11::handleBuffer() -{ -	updateImageFromBuffer(); -} -  void NativeWindowX11::redraw()  {  	if(display == nullptr) @@ -235,12 +230,7 @@ void NativeWindowX11::redraw()  		return;  	} -	if(!image) -	{ -		window.updateBuffer(); -		handleBuffer(); -	} - +	updateImageFromBuffer();  	XShmPutImage(display, xwindow, gc, image, 0, 0, 0, 0,  	             std::min(image->width, (int)window.width()),  	             std::min(image->height, (int)window.height()), false); @@ -286,7 +276,6 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)  		//DEBUG(x11, "MotionNotify");  		{  			auto mouseMoveEvent = std::make_shared<MouseMoveEvent>(); -			//mouseMoveEvent->window_id = xevent.xmotion.window;  			mouseMoveEvent->x = xevent.xmotion.x;  			mouseMoveEvent->y = xevent.xmotion.y;  			event_queue.push_back(mouseMoveEvent); @@ -298,7 +287,6 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)  		if(xevent.xexpose.count == 0)  		{  			auto repaintEvent = std::make_shared<RepaintEvent>(); -			//repaintEvent->window_id = xevent.xexpose.window;  			repaintEvent->x = xevent.xexpose.x;  			repaintEvent->y = xevent.xexpose.y;  			repaintEvent->width = xevent.xexpose.width; @@ -314,17 +302,15 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)  			   (window.height() != (std::size_t)xevent.xconfigure.height))  			{  				auto resizeEvent = std::make_shared<ResizeEvent>(); -				//resizeEvent->window_id = xevent.xconfigure.window;  				resizeEvent->width = xevent.xconfigure.width;  				resizeEvent->height = xevent.xconfigure.height;  				event_queue.push_back(resizeEvent);  			} -			if((window.windowX() != (std::size_t)xevent.xconfigure.x) || -			   (window.windowY() != (std::size_t)xevent.xconfigure.y)) +			if((window.x() != xevent.xconfigure.x) || +			   (window.y() != xevent.xconfigure.y))  			{  				auto moveEvent = std::make_shared<MoveEvent>(); -				//moveEvent->window_id = xevent.xconfigure.window;  				moveEvent->x = xevent.xconfigure.x;  				moveEvent->y = xevent.xconfigure.y;  				event_queue.push_back(moveEvent); @@ -340,7 +326,6 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)  			{  				int scroll = 1;  				auto scrollEvent = std::make_shared<ScrollEvent>(); -				//scrollEvent->window_id = xevent.xbutton.window;  				scrollEvent->x = xevent.xbutton.x;  				scrollEvent->y = xevent.xbutton.y;  				scrollEvent->delta = scroll * ((xevent.xbutton.button == 4) ? -1 : 1); @@ -349,7 +334,6 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)  			else  			{  				auto buttonEvent = std::make_shared<ButtonEvent>(); -				//buttonEvent->window_id = xevent.xbutton.window;  				buttonEvent->x = xevent.xbutton.x;  				buttonEvent->y = xevent.xbutton.y;  				switch(xevent.xbutton.button) { @@ -400,7 +384,6 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)  		//DEBUG(x11, "KeyPress");  		{  			auto keyEvent = std::make_shared<KeyEvent>(); -			//keyEvent->window_id = xevent.xkey.window;  			switch(xevent.xkey.keycode) {  			case 113: keyEvent->keycode = Key::left; break; diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h index a026ac8..f98f151 100644 --- a/plugingui/nativewindow_x11.h +++ b/plugingui/nativewindow_x11.h @@ -54,7 +54,6 @@ public:  	void show() override;  	void hide() override;  	void setCaption(const std::string &caption) override; -	void handleBuffer() override;  	void redraw() override;  	void grabMouse(bool grab) override;  	EventQueue getEvents() override; diff --git a/plugingui/painter.cc b/plugingui/painter.cc index 3e6fa48..4e7e8ba 100644 --- a/plugingui/painter.cc +++ b/plugingui/painter.cc @@ -29,6 +29,12 @@  #include <cmath>  #include <cassert> +#include "pixelbuffer.h" +#include "font.h" +#include "drawable.h" +#include "image.h" +#include "canvas.h" +  namespace GUI  { @@ -36,14 +42,11 @@ Painter::Painter(Canvas& canvas)  	: canvas(canvas)  	, pixbuf(canvas.GetPixelBuffer())  { -	canvas.beginPaint();  	colour = Colour(0.0f, 0.0f, 0.0f, 0.5f);  }  Painter::~Painter()  { -	canvas.endPaint(); -	flush();  }  void Painter::setColour(const Colour& colour) @@ -161,7 +164,7 @@ void Painter::drawRectangle(int x1, int y1, int x2, int y2)  void Painter::drawFilledRectangle(int x1, int y1, int x2, int y2)  { -	for(int y = y1; y < y2; ++y) +	for(int y = y1; y <= y2; ++y)  	{  		drawLine(x1, y, x2, y);  	} @@ -543,12 +546,4 @@ void Painter::drawBar(int x, int y, const Bar& bar, int width, int height)  	                   bar.right->width(), height);  } -void Painter::flush() -{ -#ifdef X11 -	// Send the "DrawLine" request to the server -	//XFlush(gctx->display); -#endif/*X11*/ -} -  } // GUI:: diff --git a/plugingui/painter.h b/plugingui/painter.h index 7e1fede..3f3c2bb 100644 --- a/plugingui/painter.h +++ b/plugingui/painter.h @@ -28,25 +28,23 @@  #include <string> -#include "widget.h"  #include "colour.h" -#include "pixelbuffer.h" -#include "font.h" -#include "drawable.h" -#include "texture.h" -#include "image.h"  namespace GUI  { +class PixelBufferAlpha; +class Font; +class Drawable; +class Image; +class Canvas; +  class Painter  {  public:  	Painter(Canvas& canvas);  	~Painter(); -	void flush(); -  	void setColour(const Colour& colour);  	void drawLine(int x1, int y1, int x2, int y2); diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc index 5d032b4..15270af 100644 --- a/plugingui/pixelbuffer.cc +++ b/plugingui/pixelbuffer.cc @@ -156,7 +156,7 @@ void PixelBufferAlpha::pixel(size_t x, size_t y,                               unsigned char* red,                               unsigned char* green,                               unsigned char* blue, -                             unsigned char* alpha) +                             unsigned char* alpha) const  {  	assert(x < width);  	assert(y < height); diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h index 762aaa6..b9096c9 100644 --- a/plugingui/pixelbuffer.h +++ b/plugingui/pixelbuffer.h @@ -76,7 +76,7 @@ public:  	           unsigned char* red,  	           unsigned char* green,  	           unsigned char* blue, -	           unsigned char* alpha); +	           unsigned char* alpha) const;  	bool managed{false};  	unsigned char* buf{nullptr}; diff --git a/plugingui/progressbar.cc b/plugingui/progressbar.cc index 25e735f..c7550c9 100644 --- a/plugingui/progressbar.cc +++ b/plugingui/progressbar.cc @@ -43,7 +43,7 @@ void ProgressBar::setState(ProgressBarState state)  	if(this->state != state)  	{  		this->state = state; -		repaintEvent(nullptr); +		redraw();  	}  } @@ -52,7 +52,7 @@ void ProgressBar::setTotal(std::size_t total)  	if(this->total != total)  	{  		this->total = total; -		repaintEvent(nullptr); +		redraw();  	}  } @@ -61,7 +61,7 @@ void ProgressBar::setValue(std::size_t value)  	if(this->value != value)  	{  		this->value = value; -		repaintEvent(nullptr); +		redraw();  	}  } diff --git a/plugingui/scrollbar.cc b/plugingui/scrollbar.cc index ac5be15..32db4a4 100644 --- a/plugingui/scrollbar.cc +++ b/plugingui/scrollbar.cc @@ -41,7 +41,7 @@ void ScrollBar::setRange(int r)  {  	rangeValue = r;  	setValue(value()); -	repaintEvent(nullptr); +	redraw();  }  int ScrollBar::range() @@ -57,7 +57,7 @@ void ScrollBar::setMaximum(int m)  		rangeValue = maxValue;  	}  	setValue(value()); -	repaintEvent(nullptr); +	redraw();  }  int ScrollBar::maximum() @@ -91,7 +91,7 @@ void ScrollBar::setValue(int value)  	valueChangeNotifier(value); -	repaintEvent(nullptr); +	redraw();  }  int ScrollBar::value() diff --git a/plugingui/slider.cc b/plugingui/slider.cc index 7405a69..039123e 100644 --- a/plugingui/slider.cc +++ b/plugingui/slider.cc @@ -46,7 +46,7 @@ Slider::Slider(Widget *parent)  void Slider::setValue(float newValue)  {  	currentValue = newValue; -	repaintEvent(nullptr); +	redraw();  	clickNotifier();  } @@ -120,7 +120,7 @@ void Slider::buttonEvent(ButtonEvent* buttonEvent)  			currentValue = 1;  		} -		repaintEvent(nullptr); +		redraw();  		clickNotifier();  	} @@ -139,7 +139,7 @@ void Slider::buttonEvent(ButtonEvent* buttonEvent)  			currentValue = 1;  		} -		repaintEvent(nullptr); +		redraw();  		clickNotifier();  	}  } @@ -160,7 +160,7 @@ void Slider::mouseMoveEvent(MouseMoveEvent* mouseMoveEvent)  			currentValue = 1;  		} -		repaintEvent(nullptr); +		redraw();  		clickNotifier();  	}  } diff --git a/plugingui/textedit.cc b/plugingui/textedit.cc index 6274d37..4e94566 100644 --- a/plugingui/textedit.cc +++ b/plugingui/textedit.cc @@ -83,7 +83,7 @@ void TextEdit::setText(const std::string& text)  	scroll.setRange(ran);  	scroll.setMaximum(preprocessedtext.size()); -	repaintEvent(nullptr); +	redraw();  	textChangedNotifier();  } @@ -190,7 +190,7 @@ void TextEdit::repaintEvent(RepaintEvent* repaintEvent)  void TextEdit::scrolled(int value)  {  	(void)value; -	repaintEvent(nullptr); +	redraw();  }  } // GUI:: diff --git a/plugingui/widget.cc b/plugingui/widget.cc index 9b8b173..239c233 100644 --- a/plugingui/widget.cc +++ b/plugingui/widget.cc @@ -31,7 +31,8 @@  #include "painter.h"  #include "window.h" -namespace GUI { +namespace GUI +{  Widget::Widget(Widget* parent)  	: parent(parent) @@ -67,15 +68,21 @@ void Widget::setVisible(bool visible)  	if(visible)  	{ -		repaintEvent(nullptr); +		redraw();  	}  } -bool Widget::visible() +bool Widget::visible() const  {  	return _visible;  } +void Widget::redraw() +{ +	dirty = true; +	window()->needsRedraw(); +} +  void Widget::addChild(Widget* widget)  {  	children.push_back(widget); @@ -124,33 +131,39 @@ void Widget::resize(std::size_t width, std::size_t height)  	_width = width;  	_height = height;  	pixbuf.realloc(width, height); -	repaintEvent(nullptr); +	redraw();  	sizeChangeNotifier(width, height);  }  void Widget::move(int x, int y)  { +	if((_x == x) && +	   (_y == y)) +	{ +		return; +	} +  	_x = x;  	_y = y;  	positionChangeNotifier(x, y);  } -int Widget::x() +int Widget::x() const  {  	return _x;  } -int Widget::y() +int Widget::y() const  {  	return _y;  } -std::size_t Widget::width() +std::size_t Widget::width() const  {  	return _width;  } -std::size_t Widget::height() +std::size_t Widget::height() const  {  	return _height;  } @@ -160,44 +173,6 @@ PixelBufferAlpha& Widget::GetPixelBuffer()  	return pixbuf;  } -void Widget::beginPaint() -{ -	if(_window) -	{ -		_window->beginPaint(); -	} -} - -void Widget::endPaint() -{ -	if(_window) -	{ -		_window->endPaint(); -	} -} - -size_t Widget::windowX() -{ -	size_t window_x = x(); -	if(parent) -	{ -		window_x += parent->windowX(); -	} - -	return window_x; -} - -size_t Widget::windowY() -{ -	size_t window_y = y(); -	if(parent) -	{ -		window_y += parent->windowY(); -	} - -	return window_y; -} -  ImageCache& Widget::getImageCache()  {  	assert(parent); @@ -231,8 +206,14 @@ std::vector<PixelBufferAlpha*> Widget::getPixelBuffers()  {  	std::vector<PixelBufferAlpha*> pixelBuffers; -	pixbuf.x = windowX(); -	pixbuf.y = windowY(); +	pixbuf.x = translateToWindowX(); +	pixbuf.y = translateToWindowY(); + +	if(dirty) +	{ +		repaintEvent(nullptr); +		dirty = false; +	}  	pixelBuffers.push_back(&pixbuf); @@ -254,16 +235,26 @@ bool Widget::hasKeyboardFocus()  	return window()->keyboardFocus() == this;  } -void Widget::repaintChildren(RepaintEvent* repaintEvent) +std::size_t Widget::translateToWindowX()  { -	Painter p(*this); // make sure pixbuf refcount is incremented. +	size_t window_x = x(); +	if(parent) +	{ +		window_x += parent->translateToWindowX(); +	} -	this->repaintEvent(repaintEvent); +	return window_x; +} -	for(auto child : children) +std::size_t Widget::translateToWindowY() +{ +	size_t window_y = y(); +	if(parent)  	{ -		child->repaintChildren(repaintEvent); +		window_y += parent->translateToWindowY();  	} + +	return window_y;  }  } // GUI:: diff --git a/plugingui/widget.h b/plugingui/widget.h index 4ea79e9..0485c32 100644 --- a/plugingui/widget.h +++ b/plugingui/widget.h @@ -52,25 +52,22 @@ public:  	virtual void show();  	virtual void hide(); +	void setVisible(bool visible); +	bool visible() const; + +	//! Mark widget dirty and shedule redraw on next window redraw. +	void redraw();  	// From LayoutItem  	virtual void resize(std::size_t width, std::size_t height) override;  	virtual void move(int x, int y) override; -	virtual int x() override; -	virtual int y() override; -	virtual std::size_t width() override; -	virtual std::size_t height() override; +	virtual int x() const override; +	virtual int y() const override; +	virtual std::size_t width() const override; +	virtual std::size_t height() const override;  	// From Canvas  	PixelBufferAlpha& GetPixelBuffer() override; -	void beginPaint() override; -	void endPaint() override; - -	//! Translate x-coordinate from parent-space to window-space. -	virtual size_t windowX(); - -	//! Translate y-coordinate from parent-space to window-space. -	virtual size_t windowY();  	virtual bool isFocusable() { return false; }  	virtual bool catchMouse() { return false; } @@ -97,14 +94,17 @@ public:  	bool hasKeyboardFocus(); -	bool visible(); -	void setVisible(bool visible); -  	Notifier<std::size_t, std::size_t> sizeChangeNotifier; // (width, height)  	Notifier<int, int> positionChangeNotifier; // (x, y)  protected: -	void repaintChildren(RepaintEvent* repaintEvent); +	friend class EventHandler; + +	//! Translate x-coordinate from parent-space to window-space. +	virtual std::size_t translateToWindowX(); + +	//! Translate y-coordinate from parent-space to window-space. +	virtual std::size_t translateToWindowY();  	PixelBufferAlpha pixbuf{0,0}; @@ -119,6 +119,8 @@ protected:  	std::size_t _height{0};  	bool _visible{true}; + +	bool dirty{true};  };  } // GUI:: diff --git a/plugingui/window.cc b/plugingui/window.cc index 98c0c80..44c8e12 100644 --- a/plugingui/window.cc +++ b/plugingui/window.cc @@ -42,7 +42,8 @@  #include "nativewindow_pugl.h"  #endif -namespace GUI { +namespace GUI +{  Window::Window(void* native_window)  	: Widget(nullptr) @@ -101,40 +102,10 @@ void Window::move(int x, int y)  	native->move(x, y);  } -int Window::x() -{ -	return native->getPosition().first; -} - -int Window::y() -{ -	return native->getPosition().second; -} - -size_t Window::width() -{ -	return native->getSize().first; -} - -size_t Window::height() -{ -	return native->getSize().second; -} - -size_t Window::windowX() -{ -	return 0; -} - -size_t Window::windowY() -{ -	return 0; -} -  void Window::show()  {  	Widget::show(); -	repaintChildren(nullptr); +	redraw();  	native->show();  } @@ -171,12 +142,12 @@ void Window::setKeyboardFocus(Widget* widget)  	if(oldFocusWidget)  	{ -		oldFocusWidget->repaintEvent(nullptr); +		oldFocusWidget->redraw();  	}  	if(_keyboardFocus)  	{ -		_keyboardFocus->repaintEvent(nullptr); +		_keyboardFocus->redraw();  	}  } @@ -202,18 +173,34 @@ void Window::setMouseFocus(Widget* widget)  } -void Window::redraw() +void Window::needsRedraw()  { -	native->redraw(); +	needs_redraw = true; +} + +std::size_t Window::translateToWindowX() +{ +	return 0; +} + +std::size_t Window::translateToWindowY() +{ +	return 0;  }  //! Called by event handler when an windowmanager/OS window resize event has  //! been received. Do not call this directly.  void Window::resized(std::size_t width, std::size_t height)  { -	wpixbuf.realloc(this->width(), this->height()); -	Widget::resize(this->width(), this->height()); -	updateBuffer(); +	auto size = native->getSize(); +	if((wpixbuf.width == size.first) && +	   (wpixbuf.height == size.second)) +	{ +		return; +	} +	wpixbuf.realloc(size.first, size.second); +	Widget::resize(size.first, size.second); +	//updateBuffer();  }  //! Called by event handler when an windowmanager/OS window move event has @@ -224,9 +211,20 @@ void Window::moved(int x, int y)  	Widget::move(x, y);  } -void Window::updateBuffer() +bool Window::updateBuffer()  { -	for(auto pixelBuffer : getPixelBuffers()) +	if(!native) +	{ +		return false; +	} + +	if(!needs_redraw) +	{ +		// Nothing changed, don't update anything. +		return false; +	} + +	for(const auto& pixelBuffer : getPixelBuffers())  	{  		size_t updateWidth = pixelBuffer->width;  		size_t updateHeight = pixelBuffer->height; @@ -258,35 +256,10 @@ void Window::updateBuffer()  		}  	} -	native->handleBuffer(); -} - -void Window::beginPaint() -{ -	++refcount; -	if(refcount > maxRefcount) -	{ -		maxRefcount = refcount; -	} -} - -void Window::endPaint() -{ -	if(refcount) -	{ -		--refcount; -	} +	native->redraw(); +	needs_redraw = false; -	if(!refcount) -	{ -		// Did we go deep enough for a buffer update? -		if(maxRefcount > 1) -		{ -			updateBuffer(); -			redraw(); -		} -		maxRefcount = 0; -	} +	return true;  }  } // GUI:: diff --git a/plugingui/window.h b/plugingui/window.h index 0a10b3e..cfb004d 100644 --- a/plugingui/window.h +++ b/plugingui/window.h @@ -50,12 +50,6 @@ public:  	// From Widget:  	void resize(std::size_t width, std::size_t height) override;  	void move(int x, int y) override; -	int x() override; -	int y() override; -	size_t width() override; -	size_t height() override; -	size_t windowX() override; -	size_t windowY() override;  	void show() override;  	void hide() override;  	Window* window() override; @@ -73,18 +67,25 @@ public:  	Widget* mouseFocus();  	void setMouseFocus(Widget* widget); +	//! Tag the window buffer dirty to be rendered. +	void needsRedraw(); +  protected:  	// For the EventHandler  	friend class EventHandler; -	void redraw(); + +	// From Widget: +	std::size_t translateToWindowX() override; +	std::size_t translateToWindowY() override;  	void resized(std::size_t width, std::size_t height);  	void moved(int x, int y); -	void updateBuffer(); + +	//! Returns true if window pixel buffer changed and needs to be copied to +	//! native window. +	bool updateBuffer();  	// For the Painter  	friend class Widget; -	void beginPaint() override; -	void endPaint() override;  	// For the NativeWindow  	friend class NativeWindowX11; @@ -103,6 +104,7 @@ protected:  	size_t maxRefcount{0}; +	bool needs_redraw{false};  	ImageCache image_cache;  }; | 
