<commit_before>//
// Name:	 canvas.cpp
// Purpose:	 Implements the canvas class for the wxWindows application.
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/TimeEngines.h"
#include "vtlib/core/TerrainScene.h"
#include "../Enviro.h"			// for g_App, GetTerrainScene
#include "canvas.h"
#include "frame.h"
#include "app.h"

DECLARE_APP(vtApp)

/*
 * vtGLCanvas implementation
 */
BEGIN_EVENT_TABLE(vtGLCanvas, wxGLCanvas)
	EVT_CLOSE(vtGLCanvas::OnClose)
	EVT_SIZE(vtGLCanvas::OnSize)
	EVT_PAINT(vtGLCanvas::OnPaint)
	EVT_CHAR(vtGLCanvas::OnChar)
	EVT_MOUSE_EVENTS(vtGLCanvas::OnMouseEvent)
	EVT_ERASE_BACKGROUND(vtGLCanvas::OnEraseBackground)
END_EVENT_TABLE()

static vtGLCanvas *s_canvas = NULL;

vtGLCanvas::vtGLCanvas(wxWindow *parent, wxWindowID id,
	const wxPoint& pos, const wxSize& size, long style, const wxString& name, int* gl_attrib):
  wxGLCanvas(parent, id, pos, size, style, name, gl_attrib)
{
	parent->Show(TRUE);
	SetCurrent();

	m_StatusTimer.SetFrame((wxFrame *)parent);
	m_StatusTimer.Start(1000);

	m_bPainting = false;
	m_bRunning = true;
	m_bShowFrameRateChart = false;

	s_canvas = this;
}

vtGLCanvas::~vtGLCanvas(void)
{
}

void EnableContinuousRendering(bool bTrue)
{
	if (s_canvas)
		s_canvas->m_bRunning = bTrue;
}

void vtGLCanvas::QueueRefresh(bool eraseBackground)
	// A Refresh routine we can call from inside OnPaint.
	//   (queues the events rather than dispatching them immediately).
{
	// With wxGTK, you can't do a Refresh() in OnPaint because it doesn't
	//   queue (post) a Refresh event for later.  Rather it dispatches
	//   (processes) the underlying events immediately via ProcessEvent
	//   (read, recursive call).  See the wxPostEvent docs and Refresh code
	//   for more details.
	if ( eraseBackground )
	{
		wxEraseEvent eevent( GetId() );
		eevent.SetEventObject( this );
		wxPostEvent( GetEventHandler(), eevent );
	}

	wxPaintEvent event( GetId() );
	event.SetEventObject( this );
	wxPostEvent( GetEventHandler(), event );
}

void StatusTimer::Notify()
{
	if (!m_pFrame || !m_pFrame->GetStatusBar()) return;

	vtScene *scene = vtGetScene();
	if (!scene) return;

	vtString str, str2;

	// get framerate
	float fps = scene->GetFrameRate();

	// only show 3 significant digits
	if (fps < 10)
		str.Format("fps %1.2f, ", fps);
	else if (fps < 80)
		str.Format("fps %2.1f, ", fps);
	else
		str.Format("fps %3.0f, ", fps);

	// get time of day
	TimeEngine *te = GetTerrainScene()->GetTimeEngine();
	if (te->GetEnabled())
	{
		int hr, min, sec;
		te->GetTime(hr, min, sec);

		str2.Format("time %02d:%02d:%02d, ", hr, min, sec);
		str += str2;
	}

	g_App.DescribeCoordinates(str2);
	str += str2;

	// get CLOD triangle counts, if appropriate
	g_App.DescribeCLOD(str2);
	str += str2;

	str += g_App.m_strMessage;

	m_pFrame->SetStatusText((const char *)str);
}

void vtGLCanvas::OnPaint( wxPaintEvent& event )
{
	// place the dc inside a scope, to delete it before the end of function
	if (1)
	{
		// This is a dummy, to avoid an endless succession of paint messages.
		// OnPaint handlers must always create a wxPaintDC.
		wxPaintDC dc(this);
#ifdef __WXMSW__
		if (!GetContext()) return;
#endif

		if (m_bPainting || !m_bRunning) return;

		m_bPainting = true;

		// Render the Scene Graph
		vtGetScene()->DoUpdate();

		if (m_bShowFrameRateChart)
			vtGetScene()->DrawFrameRateChart();

		SwapBuffers();

#ifdef WIN32
		// Call Refresh again for continuous rendering,
		if (m_bRunning)
			Refresh(FALSE);
#else
		// Queue another refresh for continuous rendering.
		//   (Yield first so we don't starve out keyboard & mouse events.)
		//
		// FIXME: We may want to use a frame timer instead of immediate-
		//   redraw so we don't eat so much CPU on machines that can
		//   easily handle the frame rate.
		wxYield();
		QueueRefresh(FALSE);
#endif

		// update the status bar every 1/10 of a second
		static float last_stat = 0.0f;
		float cur = vtGetTime();
		if (cur - last_stat > 0.1f)
		{
			last_stat = cur;
			m_StatusTimer.Notify();
		}

		m_bPainting = false;
	}

	// Must allow some idle processing to occur - or the toolbars will not
	// update, and the close box will not respond!
	wxGetApp().ProcessIdle();
}

void vtGLCanvas::OnClose(wxCloseEvent& event)
{
	m_bRunning = false;
}

void vtGLCanvas::OnSize(wxSizeEvent& event)
{
  // Presumably this is a wxMSWism.
  // For wxGTK & wxMotif, all canvas resize events occur before the context
  //   is set.  So ignore this context check and grab the window width/height
  //   when we get it so it (and derived values such as aspect ratio and
  //   viewport parms) are computed correctly.
#ifdef __WXMSW__
	if (!GetContext()) return;
#endif

	SetCurrent();
	int width, height;
	GetClientSize(& width, & height);

	vtGetScene()->SetWindowSize(width, height);

	wxGLCanvas::OnSize(event);
}

void vtGLCanvas::OnChar(wxKeyEvent& event)
{
	long key = event.KeyCode();

	// pass the char to the frame for it to do "accelerator" shortcuts
	vtFrame *frame = (vtFrame*) GetParent();
	frame->OnChar(event);

	int flags = 0;

	if (event.ControlDown())
		flags |= VT_CONTROL;

	if (event.ShiftDown())
		flags |= VT_SHIFT;

	if (event.AltDown())
		flags |= VT_ALT;

	// pass the char to the vtlib Scene
	vtGetScene()->OnKey(key, flags);
}

void vtGLCanvas::OnMouseEvent(wxMouseEvent& event1)
{
	// turn WX mouse event into a VT mouse event
	vtMouseEvent event;
	wxEventType  ev = event1.GetEventType();
	if (ev == wxEVT_LEFT_DOWN) {
		event.type = VT_DOWN;
		event.button = VT_LEFT;
	} else if (ev == wxEVT_LEFT_UP) {
		event.type = VT_UP;
		event.button = VT_LEFT;
	} else if (ev == wxEVT_MIDDLE_DOWN) {
		event.type = VT_DOWN;
		event.button = VT_MIDDLE;
	} else if (ev == wxEVT_MIDDLE_UP) {
		event.type = VT_UP;
		event.button = VT_MIDDLE;
	} else if (ev == wxEVT_RIGHT_DOWN) {
		event.type = VT_DOWN;
		event.button = VT_RIGHT;
	} else if (ev == wxEVT_RIGHT_UP) {
		event.type = VT_UP;
		event.button = VT_RIGHT;
	} else if (ev == wxEVT_MOTION) {
		event.type = VT_MOVE;
		event.button = VT_NONE;
	} else {
		// ignored mouse events, such as wxEVT_LEAVE_WINDOW
		return;
	}

	if (ev == wxEVT_LEFT_DOWN || ev == wxEVT_MIDDLE_DOWN || ev == wxEVT_RIGHT_DOWN)
		CaptureMouse();
	if (ev == wxEVT_LEFT_UP || ev == wxEVT_MIDDLE_UP || ev == wxEVT_RIGHT_UP)
		ReleaseMouse();

	event.flags = 0;
	wxCoord xpos, ypos;
    event1.GetPosition(&xpos, &ypos);
	event.pos.Set(xpos, ypos);

	if (event1.ControlDown())
		event.flags |= VT_CONTROL;

	if (event1.ShiftDown())
		event.flags |= VT_SHIFT;

	if (event1.AltDown())
		event.flags |= VT_ALT;

	// inform Enviro app
	g_App.OnMouse(event);

	vtGetScene()->OnMouse(event);
}

void vtGLCanvas::OnEraseBackground(wxEraseEvent& event)
{
	// Do nothing, to avoid flashing.
}

<commit_msg>fixed refresh on edit from rendering disable<commit_after>//
// Name:	 canvas.cpp
// Purpose:	 Implements the canvas class for the wxWindows application.
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/TimeEngines.h"
#include "vtlib/core/TerrainScene.h"
#include "../Enviro.h"			// for g_App, GetTerrainScene
#include "canvas.h"
#include "frame.h"
#include "app.h"

DECLARE_APP(vtApp)

/*
 * vtGLCanvas implementation
 */
BEGIN_EVENT_TABLE(vtGLCanvas, wxGLCanvas)
	EVT_CLOSE(vtGLCanvas::OnClose)
	EVT_SIZE(vtGLCanvas::OnSize)
	EVT_PAINT(vtGLCanvas::OnPaint)
	EVT_CHAR(vtGLCanvas::OnChar)
	EVT_MOUSE_EVENTS(vtGLCanvas::OnMouseEvent)
	EVT_ERASE_BACKGROUND(vtGLCanvas::OnEraseBackground)
END_EVENT_TABLE()

static vtGLCanvas *s_canvas = NULL;

vtGLCanvas::vtGLCanvas(wxWindow *parent, wxWindowID id,
	const wxPoint& pos, const wxSize& size, long style, const wxString& name, int* gl_attrib):
  wxGLCanvas(parent, id, pos, size, style, name, gl_attrib)
{
	parent->Show(TRUE);
	SetCurrent();

	m_StatusTimer.SetFrame((wxFrame *)parent);
	m_StatusTimer.Start(1000);

	m_bPainting = false;
	m_bRunning = true;
	m_bShowFrameRateChart = false;

	s_canvas = this;
}

vtGLCanvas::~vtGLCanvas(void)
{
}

void EnableContinuousRendering(bool bTrue)
{
	if (!s_canvas)
		return;

	bool bNeedRefresh = (s_canvas->m_bRunning == false && bTrue == true);
	s_canvas->m_bRunning = bTrue;
	if (bNeedRefresh)
		s_canvas->Refresh(FALSE);
}

void vtGLCanvas::QueueRefresh(bool eraseBackground)
	// A Refresh routine we can call from inside OnPaint.
	//   (queues the events rather than dispatching them immediately).
{
	// With wxGTK, you can't do a Refresh() in OnPaint because it doesn't
	//   queue (post) a Refresh event for later.  Rather it dispatches
	//   (processes) the underlying events immediately via ProcessEvent
	//   (read, recursive call).  See the wxPostEvent docs and Refresh code
	//   for more details.
	if ( eraseBackground )
	{
		wxEraseEvent eevent( GetId() );
		eevent.SetEventObject( this );
		wxPostEvent( GetEventHandler(), eevent );
	}

	wxPaintEvent event( GetId() );
	event.SetEventObject( this );
	wxPostEvent( GetEventHandler(), event );
}

void StatusTimer::Notify()
{
	if (!m_pFrame || !m_pFrame->GetStatusBar()) return;

	vtScene *scene = vtGetScene();
	if (!scene) return;

	vtString str, str2;

	// get framerate
	float fps = scene->GetFrameRate();

	// only show 3 significant digits
	if (fps < 10)
		str.Format("fps %1.2f, ", fps);
	else if (fps < 80)
		str.Format("fps %2.1f, ", fps);
	else
		str.Format("fps %3.0f, ", fps);

	// get time of day
	TimeEngine *te = GetTerrainScene()->GetTimeEngine();
	if (te->GetEnabled())
	{
		int hr, min, sec;
		te->GetTime(hr, min, sec);

		str2.Format("time %02d:%02d:%02d, ", hr, min, sec);
		str += str2;
	}

	g_App.DescribeCoordinates(str2);
	str += str2;

	// get CLOD triangle counts, if appropriate
	g_App.DescribeCLOD(str2);
	str += str2;

	str += g_App.m_strMessage;

	m_pFrame->SetStatusText((const char *)str);
}

void vtGLCanvas::OnPaint( wxPaintEvent& event )
{
	// place the dc inside a scope, to delete it before the end of function
	if (1)
	{
		// This is a dummy, to avoid an endless succession of paint messages.
		// OnPaint handlers must always create a wxPaintDC.
		wxPaintDC dc(this);
#ifdef __WXMSW__
		if (!GetContext()) return;
#endif

		if (m_bPainting || !m_bRunning) return;

		m_bPainting = true;

		// Render the Scene Graph
		vtGetScene()->DoUpdate();

		if (m_bShowFrameRateChart)
			vtGetScene()->DrawFrameRateChart();

		SwapBuffers();

#ifdef WIN32
		// Call Refresh again for continuous rendering,
		if (m_bRunning)
			Refresh(FALSE);
#else
		// Queue another refresh for continuous rendering.
		//   (Yield first so we don't starve out keyboard & mouse events.)
		//
		// FIXME: We may want to use a frame timer instead of immediate-
		//   redraw so we don't eat so much CPU on machines that can
		//   easily handle the frame rate.
		wxYield();
		QueueRefresh(FALSE);
#endif

		// update the status bar every 1/10 of a second
		static float last_stat = 0.0f;
		float cur = vtGetTime();
		if (cur - last_stat > 0.1f)
		{
			last_stat = cur;
			m_StatusTimer.Notify();
		}

		m_bPainting = false;
	}

	// Must allow some idle processing to occur - or the toolbars will not
	// update, and the close box will not respond!
	wxGetApp().ProcessIdle();
}

void vtGLCanvas::OnClose(wxCloseEvent& event)
{
	m_bRunning = false;
}

void vtGLCanvas::OnSize(wxSizeEvent& event)
{
  // Presumably this is a wxMSWism.
  // For wxGTK & wxMotif, all canvas resize events occur before the context
  //   is set.  So ignore this context check and grab the window width/height
  //   when we get it so it (and derived values such as aspect ratio and
  //   viewport parms) are computed correctly.
#ifdef __WXMSW__
	if (!GetContext()) return;
#endif

	SetCurrent();
	int width, height;
	GetClientSize(& width, & height);

	vtGetScene()->SetWindowSize(width, height);

	wxGLCanvas::OnSize(event);
}

void vtGLCanvas::OnChar(wxKeyEvent& event)
{
	long key = event.KeyCode();

	// pass the char to the frame for it to do "accelerator" shortcuts
	vtFrame *frame = (vtFrame*) GetParent();
	frame->OnChar(event);

	int flags = 0;

	if (event.ControlDown())
		flags |= VT_CONTROL;

	if (event.ShiftDown())
		flags |= VT_SHIFT;

	if (event.AltDown())
		flags |= VT_ALT;

	// pass the char to the vtlib Scene
	vtGetScene()->OnKey(key, flags);
}

void vtGLCanvas::OnMouseEvent(wxMouseEvent& event1)
{
	// turn WX mouse event into a VT mouse event
	vtMouseEvent event;
	wxEventType  ev = event1.GetEventType();
	if (ev == wxEVT_LEFT_DOWN) {
		event.type = VT_DOWN;
		event.button = VT_LEFT;
	} else if (ev == wxEVT_LEFT_UP) {
		event.type = VT_UP;
		event.button = VT_LEFT;
	} else if (ev == wxEVT_MIDDLE_DOWN) {
		event.type = VT_DOWN;
		event.button = VT_MIDDLE;
	} else if (ev == wxEVT_MIDDLE_UP) {
		event.type = VT_UP;
		event.button = VT_MIDDLE;
	} else if (ev == wxEVT_RIGHT_DOWN) {
		event.type = VT_DOWN;
		event.button = VT_RIGHT;
	} else if (ev == wxEVT_RIGHT_UP) {
		event.type = VT_UP;
		event.button = VT_RIGHT;
	} else if (ev == wxEVT_MOTION) {
		event.type = VT_MOVE;
		event.button = VT_NONE;
	} else {
		// ignored mouse events, such as wxEVT_LEAVE_WINDOW
		return;
	}

	if (ev == wxEVT_LEFT_DOWN || ev == wxEVT_MIDDLE_DOWN || ev == wxEVT_RIGHT_DOWN)
		CaptureMouse();
	if (ev == wxEVT_LEFT_UP || ev == wxEVT_MIDDLE_UP || ev == wxEVT_RIGHT_UP)
		ReleaseMouse();

	event.flags = 0;
	wxCoord xpos, ypos;
    event1.GetPosition(&xpos, &ypos);
	event.pos.Set(xpos, ypos);

	if (event1.ControlDown())
		event.flags |= VT_CONTROL;

	if (event1.ShiftDown())
		event.flags |= VT_SHIFT;

	if (event1.AltDown())
		event.flags |= VT_ALT;

	// inform Enviro app
	g_App.OnMouse(event);

	vtGetScene()->OnMouse(event);
}

void vtGLCanvas::OnEraseBackground(wxEraseEvent& event)
{
	// Do nothing, to avoid flashing.
}

<|endoftext|>


<commit_before>#include "contextpanetextwidget.h"
#include "contextpanewidget.h"
#include "ui_contextpanetext.h"
#include <qmljs/qmljspropertyreader.h>
#include <QTimerEvent>

namespace QmlDesigner {

ContextPaneTextWidget::ContextPaneTextWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ContextPaneTextWidget),
    m_fontSizeTimer(-1)
{
    ui->setupUi(this);
    ui->boldButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/bold-h-icon.png")));
    ui->italicButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/italic-h-icon.png")));
    ui->underlineButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/underline-h-icon.png")));
    ui->strikeoutButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/strikeout-h-icon.png")));

    ui->leftAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentleft-h-icon.png")));
    ui->centerHAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentcenterh-h-icon.png")));
    ui->rightAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentright-h-icon.png")));

    ui->centerVAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentmiddle-h-icon.png")));

    ui->bottomAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentbottom-h-icon.png")));
    ui->topAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmenttop-h-icon.png")));

    ui->colorButton->setShowArrow(false);
    ui->textColorButton->setShowArrow(false);

    connect(ui->colorButton, SIGNAL(toggled(bool)), this, SLOT(onColorButtonToggled(bool)));
    connect(ui->textColorButton, SIGNAL(toggled(bool)), this, SLOT(onTextColorButtonToggled(bool)));

    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    connect(parentContextWidget->colorDialog(), SIGNAL(accepted(QColor)), this, SLOT(onColorDialogApplied(QColor)));
    connect(parentContextWidget->colorDialog(), SIGNAL(rejected()), this, SLOT(onColorDialogCancled()));

    connect(ui->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(onFontSizeChanged(int)));
    connect(ui->fontSizeSpinBox, SIGNAL(formatChanged()), this, SLOT(onFontFormatChanged()));

    connect(ui->boldButton, SIGNAL(toggled(bool)), this, SLOT(onBoldCheckedChanged(bool)));
    connect(ui->italicButton, SIGNAL(toggled(bool)), this, SLOT(onItalicCheckedChanged(bool)));
    connect(ui->underlineButton, SIGNAL(toggled(bool)), this, SLOT(onUnderlineCheckedChanged(bool)));
    connect(ui->strikeoutButton, SIGNAL(toggled(bool)), this, SLOT(onStrikeoutCheckedChanged(bool)));
    connect(ui->fontComboBox, SIGNAL(currentFontChanged(QFont)), this, SLOT(onCurrentFontChanged(QFont)));

    connect(ui->centerHAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalAlignmentChanged()));
    connect(ui->leftAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalAlignmentChanged()));
    connect(ui->rightAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalAlignmentChanged()));

    connect(ui->centerVAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalAlignmentChanged()));
    connect(ui->topAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalAlignmentChanged()));
    connect(ui->bottomAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalAlignmentChanged()));

    connect(ui->styleComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(onStyleComboBoxChanged(QString)));
}

void ContextPaneTextWidget::setProperties(QmlJS::PropertyReader *propertyReader)
{
    if (propertyReader->hasProperty(QLatin1String("font.pointSize"))) {
        ui->fontSizeSpinBox->setValue(propertyReader->readProperty(QLatin1String("font.pointSize")).toInt());
        ui->fontSizeSpinBox->setIsPointSize(true);
    } else if (!propertyReader->hasProperty(QLatin1String("font.pixelSize"))) {
        ui->fontSizeSpinBox->setValue(8);
        ui->fontSizeSpinBox->setIsPointSize(true);
    }

    if (m_fontSizeTimer > 0) {
        killTimer(m_fontSizeTimer);
        m_fontSizeTimer = -1;
    }

    if (propertyReader->hasProperty(QLatin1String("font.pixelSize"))) {
        ui->fontSizeSpinBox->setValue(propertyReader->readProperty(QLatin1String("font.pixelSize")).toInt());
        ui->fontSizeSpinBox->setIsPixelSize(true);
    }

    if (propertyReader->hasProperty(QLatin1String("font.bold"))) {
        ui->boldButton->setChecked(propertyReader->readProperty(QLatin1String("font.bold")).toBool());
    } else {
        ui->boldButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("font.italic"))) {
        ui->italicButton->setChecked(propertyReader->readProperty(QLatin1String("font.italic")).toBool());
    } else {
        ui->italicButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("font.underline"))) {
        ui->underlineButton->setChecked(propertyReader->readProperty(QLatin1String("font.underline")).toBool());
    } else {
        ui->underlineButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("font.strikeout"))) {
        ui->strikeoutButton->setChecked(propertyReader->readProperty(QLatin1String("font.strikeout")).toBool());
    } else {
        ui->strikeoutButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("color"))) {
        ui->colorButton->setColor(propertyReader->readProperty("color").toString());
    } else {
        ui->colorButton->setColor(QLatin1String("black"));
    }

    if (propertyReader->hasProperty(QLatin1String("styleColor"))) {
        ui->textColorButton->setColor(propertyReader->readProperty("styleColor").toString());
    } else {
        ui->textColorButton->setColor(QLatin1String("black"));
    }

    if (propertyReader->hasProperty(QLatin1String("font.family"))) {
        QString familyName = propertyReader->readProperty(QLatin1String("font.family")).toString();
        QFont font;
        font.setFamily(familyName);
        ui->fontComboBox->setCurrentFont(font);
    }

    if (propertyReader->hasProperty(QLatin1String("horizontalAlignment"))) {
        QString alignment = propertyReader->readProperty(QLatin1String("horizontalAlignment")).toString();
        ui->leftAlignmentButton->setChecked(true);
        if (alignment == QLatin1String("Text.AlignHCenter") || alignment == "AlignHCenter")
            ui->centerHAlignmentButton->setChecked(true);
        else if (alignment == QLatin1String("Text.AlignRight") || alignment == QLatin1String("AlignRight"))
            ui->rightAlignmentButton->setChecked(true);
    } else {
        ui->leftAlignmentButton->setChecked(true);
    }

    if (propertyReader->hasProperty(QLatin1String("verticalAlignment"))) {
        QString alignment = propertyReader->readProperty(QLatin1String("verticalAlignment")).toString();
        ui->topAlignmentButton->setChecked(true);
        if (alignment == QLatin1String("Text.AlignVCenter") || alignment == QLatin1String("AlignVCenter"))
            ui->centerVAlignmentButton->setChecked(true);
        else if (alignment == QLatin1String("Text.AlignBottom") || alignment == QLatin1String("AlignBottom"))
            ui->bottomAlignmentButton->setChecked(true);
    } else {
        ui->topAlignmentButton->setChecked(true);
    }

    if (propertyReader->hasProperty(QLatin1String("style"))) {
        QString style = propertyReader->readProperty(QLatin1String("style")).toString();
        ui->styleComboBox->setCurrentIndex(0);
        if (style == QLatin1String("Text.Outline") || style == QLatin1String("Outline"))
            ui->styleComboBox->setCurrentIndex(1);
        if (style == QLatin1String("Text.Raised") || style == QLatin1String("Raised"))
            ui->styleComboBox->setCurrentIndex(2);
        else if (style == QLatin1String("Text.Sunken") || style == QLatin1String("Sunken"))
            ui->styleComboBox->setCurrentIndex(3);
    } else {
        ui->styleComboBox->setCurrentIndex(0);
    }
}

void ContextPaneTextWidget::setVerticalAlignmentVisible(bool b)
{
    ui->centerVAlignmentButton->setEnabled(b);
    ui->topAlignmentButton->setEnabled(b);
    ui->bottomAlignmentButton->setEnabled(b);
}

void ContextPaneTextWidget::setStyleVisible(bool b)
{
    ui->styleComboBox->setEnabled(b);
    ui->styleLabel->setEnabled(b);
    ui->textColorButton->setEnabled(b);
}

void ContextPaneTextWidget::onTextColorButtonToggled(bool flag)
{
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    if (flag)
        ui->colorButton->setChecked(false);
    QPoint p = mapToGlobal(ui->textColorButton->pos());
    parentContextWidget->colorDialog()->setupColor(ui->textColorButton->color());
    p = parentContextWidget->colorDialog()->parentWidget()->mapFromGlobal(p);
    parentContextWidget->onShowColorDialog(flag, p);
}

void ContextPaneTextWidget::onColorButtonToggled(bool flag)
{
    if (flag)
        ui->textColorButton->setChecked(false);
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    QPoint p = mapToGlobal(ui->colorButton->pos());
    parentContextWidget->colorDialog()->setupColor(ui->colorButton->color());
    p = parentContextWidget->colorDialog()->parentWidget()->mapFromGlobal(p);
    parentContextWidget->onShowColorDialog(flag, p);
}

void ContextPaneTextWidget::onColorDialogApplied(const QColor &)
{
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    parentContextWidget->onShowColorDialog(false, QPoint());
    if (ui->textColorButton->isChecked())
        emit  propertyChanged(QLatin1String("styleColor"),parentContextWidget->colorDialog()->color());; //write back color
    if (ui->colorButton->isChecked())
        emit  propertyChanged(QLatin1String("color"),parentContextWidget->colorDialog()->color());; //write back color
    ui->textColorButton->setChecked(false);
    ui->colorButton->setChecked(false);
}

void ContextPaneTextWidget::onColorDialogCancled()
{
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    parentContextWidget->onShowColorDialog(false, QPoint());
    ui->colorButton->setChecked(false);
    ui->colorButton->setChecked(false);
}

void ContextPaneTextWidget::onFontSizeChanged(int)
{
    if (m_fontSizeTimer > 0)
        killTimer(m_fontSizeTimer);
    m_fontSizeTimer = startTimer(200);
}

void ContextPaneTextWidget::onFontFormatChanged()
{
    int size = ui->fontSizeSpinBox->value();
    if (ui->fontSizeSpinBox->isPointSize()) {
        emit removeAndChangeProperty(QLatin1String("font.pixelSize"), QLatin1String("font.pointSize"), size);
    } else {
        emit removeAndChangeProperty(QLatin1String("font.pointSize"), QLatin1String("font.pixelSize"), size);
    }

}

void ContextPaneTextWidget::onBoldCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.bold"), value);
    else
        emit removeProperty(QLatin1String("font.bold"));

}

void ContextPaneTextWidget::onItalicCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.italic"), value);
    else
        emit removeProperty(QLatin1String("font.italic"));
}

void ContextPaneTextWidget::onUnderlineCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.underline"), value);
    else
        emit removeProperty(QLatin1String("font.underline"));
}

void ContextPaneTextWidget::onStrikeoutCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.strikeout"), value);
    else
        emit removeProperty(QLatin1String("font.strikeout"));
}

void ContextPaneTextWidget::onCurrentFontChanged(const QFont &font)
{
    font.family();
    emit propertyChanged(QLatin1String("font.family"), QVariant(QString('\"') + font.family() + QString('\"')));
}

void ContextPaneTextWidget::onHorizontalAlignmentChanged()
{
    QString alignment;
    if (ui->centerHAlignmentButton->isChecked())
        alignment = QLatin1String("Text.AlignHCenter");
    else if (ui->leftAlignmentButton->isChecked())
        alignment = QLatin1String("Text.AlignLeft");
    else if (ui->rightAlignmentButton->isChecked())
        alignment = QLatin1String("Text.AlignRight");
    if (m_horizontalAlignment != alignment) {
        m_horizontalAlignment = alignment;
        if (alignment == QLatin1String("Text.AlignLeft"))
            emit removeProperty(QLatin1String("horizontalAlignment"));
        else
            emit propertyChanged(QLatin1String("horizontalAlignment"), alignment);
    }
}

void ContextPaneTextWidget::onStyleComboBoxChanged(const QString &style)
{
    if (style == QLatin1String("Normal"))
        emit removeProperty(QLatin1String("style"));
    else
        emit propertyChanged(QLatin1String("style"), QVariant(QLatin1String("Text.") + style));
}

void ContextPaneTextWidget::onVerticalAlignmentChanged()
{
    QString alignment;
    if (ui->centerVAlignmentButton->isChecked())
        alignment = QLatin1String("Text.AlignVCenter");
    else if (ui->topAlignmentButton->isChecked())
        alignment = QLatin1String("Text.AlignTop");
    else if (ui->bottomAlignmentButton->isChecked())
        alignment = QLatin1String("Text.AlignBottom");
    if (m_verticalAlignment != alignment) {
        m_verticalAlignment = alignment;
        if (alignment == QLatin1String("Text.AlignTop"))
            emit removeProperty(QLatin1String("verticalAlignment"));
        else
            emit propertyChanged(QLatin1String("verticalAlignment"), alignment);
    }
}

ContextPaneTextWidget::~ContextPaneTextWidget()
{
    delete ui;
}

void ContextPaneTextWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void ContextPaneTextWidget::timerEvent(QTimerEvent *event)
{
    if (event->timerId() == m_fontSizeTimer) {
        killTimer(m_fontSizeTimer);
        m_fontSizeTimer = -1;
        int value = ui->fontSizeSpinBox->value();
        if (ui->fontSizeSpinBox->isPointSize())
            emit propertyChanged(QLatin1String("font.pointSize"), value);
        else
            emit propertyChanged(QLatin1String("font.pixelSize"), value);
    }
}

} //QmlDesigner
<commit_msg>QmlDesigner.contextPane: AlignRight instead of Text.AlignRight<commit_after>#include "contextpanetextwidget.h"
#include "contextpanewidget.h"
#include "ui_contextpanetext.h"
#include <qmljs/qmljspropertyreader.h>
#include <QTimerEvent>

namespace QmlDesigner {

ContextPaneTextWidget::ContextPaneTextWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ContextPaneTextWidget),
    m_fontSizeTimer(-1)
{
    ui->setupUi(this);
    ui->boldButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/bold-h-icon.png")));
    ui->italicButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/italic-h-icon.png")));
    ui->underlineButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/underline-h-icon.png")));
    ui->strikeoutButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/strikeout-h-icon.png")));

    ui->leftAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentleft-h-icon.png")));
    ui->centerHAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentcenterh-h-icon.png")));
    ui->rightAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentright-h-icon.png")));

    ui->centerVAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentmiddle-h-icon.png")));

    ui->bottomAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmentbottom-h-icon.png")));
    ui->topAlignmentButton->setIcon(QIcon(QLatin1String(":/qmldesigner/images/alignmenttop-h-icon.png")));

    ui->colorButton->setShowArrow(false);
    ui->textColorButton->setShowArrow(false);

    connect(ui->colorButton, SIGNAL(toggled(bool)), this, SLOT(onColorButtonToggled(bool)));
    connect(ui->textColorButton, SIGNAL(toggled(bool)), this, SLOT(onTextColorButtonToggled(bool)));

    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    connect(parentContextWidget->colorDialog(), SIGNAL(accepted(QColor)), this, SLOT(onColorDialogApplied(QColor)));
    connect(parentContextWidget->colorDialog(), SIGNAL(rejected()), this, SLOT(onColorDialogCancled()));

    connect(ui->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(onFontSizeChanged(int)));
    connect(ui->fontSizeSpinBox, SIGNAL(formatChanged()), this, SLOT(onFontFormatChanged()));

    connect(ui->boldButton, SIGNAL(toggled(bool)), this, SLOT(onBoldCheckedChanged(bool)));
    connect(ui->italicButton, SIGNAL(toggled(bool)), this, SLOT(onItalicCheckedChanged(bool)));
    connect(ui->underlineButton, SIGNAL(toggled(bool)), this, SLOT(onUnderlineCheckedChanged(bool)));
    connect(ui->strikeoutButton, SIGNAL(toggled(bool)), this, SLOT(onStrikeoutCheckedChanged(bool)));
    connect(ui->fontComboBox, SIGNAL(currentFontChanged(QFont)), this, SLOT(onCurrentFontChanged(QFont)));

    connect(ui->centerHAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalAlignmentChanged()));
    connect(ui->leftAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalAlignmentChanged()));
    connect(ui->rightAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalAlignmentChanged()));

    connect(ui->centerVAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalAlignmentChanged()));
    connect(ui->topAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalAlignmentChanged()));
    connect(ui->bottomAlignmentButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalAlignmentChanged()));

    connect(ui->styleComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(onStyleComboBoxChanged(QString)));
}

void ContextPaneTextWidget::setProperties(QmlJS::PropertyReader *propertyReader)
{
    if (propertyReader->hasProperty(QLatin1String("font.pointSize"))) {
        ui->fontSizeSpinBox->setValue(propertyReader->readProperty(QLatin1String("font.pointSize")).toInt());
        ui->fontSizeSpinBox->setIsPointSize(true);
    } else if (!propertyReader->hasProperty(QLatin1String("font.pixelSize"))) {
        ui->fontSizeSpinBox->setValue(8);
        ui->fontSizeSpinBox->setIsPointSize(true);
    }

    if (m_fontSizeTimer > 0) {
        killTimer(m_fontSizeTimer);
        m_fontSizeTimer = -1;
    }

    if (propertyReader->hasProperty(QLatin1String("font.pixelSize"))) {
        ui->fontSizeSpinBox->setValue(propertyReader->readProperty(QLatin1String("font.pixelSize")).toInt());
        ui->fontSizeSpinBox->setIsPixelSize(true);
    }

    if (propertyReader->hasProperty(QLatin1String("font.bold"))) {
        ui->boldButton->setChecked(propertyReader->readProperty(QLatin1String("font.bold")).toBool());
    } else {
        ui->boldButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("font.italic"))) {
        ui->italicButton->setChecked(propertyReader->readProperty(QLatin1String("font.italic")).toBool());
    } else {
        ui->italicButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("font.underline"))) {
        ui->underlineButton->setChecked(propertyReader->readProperty(QLatin1String("font.underline")).toBool());
    } else {
        ui->underlineButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("font.strikeout"))) {
        ui->strikeoutButton->setChecked(propertyReader->readProperty(QLatin1String("font.strikeout")).toBool());
    } else {
        ui->strikeoutButton->setChecked(false);
    }

    if (propertyReader->hasProperty(QLatin1String("color"))) {
        ui->colorButton->setColor(propertyReader->readProperty("color").toString());
    } else {
        ui->colorButton->setColor(QLatin1String("black"));
    }

    if (propertyReader->hasProperty(QLatin1String("styleColor"))) {
        ui->textColorButton->setColor(propertyReader->readProperty("styleColor").toString());
    } else {
        ui->textColorButton->setColor(QLatin1String("black"));
    }

    if (propertyReader->hasProperty(QLatin1String("font.family"))) {
        QString familyName = propertyReader->readProperty(QLatin1String("font.family")).toString();
        QFont font;
        font.setFamily(familyName);
        ui->fontComboBox->setCurrentFont(font);
    }

    if (propertyReader->hasProperty(QLatin1String("horizontalAlignment"))) {
        QString alignment = propertyReader->readProperty(QLatin1String("horizontalAlignment")).toString();
        ui->leftAlignmentButton->setChecked(true);
        if (alignment == QLatin1String("Text.AlignHCenter") || alignment == "AlignHCenter")
            ui->centerHAlignmentButton->setChecked(true);
        else if (alignment == QLatin1String("Text.AlignRight") || alignment == QLatin1String("AlignRight"))
            ui->rightAlignmentButton->setChecked(true);
    } else {
        ui->leftAlignmentButton->setChecked(true);
    }

    if (propertyReader->hasProperty(QLatin1String("verticalAlignment"))) {
        QString alignment = propertyReader->readProperty(QLatin1String("verticalAlignment")).toString();
        ui->topAlignmentButton->setChecked(true);
        if (alignment == QLatin1String("Text.AlignVCenter") || alignment == QLatin1String("AlignVCenter"))
            ui->centerVAlignmentButton->setChecked(true);
        else if (alignment == QLatin1String("Text.AlignBottom") || alignment == QLatin1String("AlignBottom"))
            ui->bottomAlignmentButton->setChecked(true);
    } else {
        ui->topAlignmentButton->setChecked(true);
    }

    if (propertyReader->hasProperty(QLatin1String("style"))) {
        QString style = propertyReader->readProperty(QLatin1String("style")).toString();
        ui->styleComboBox->setCurrentIndex(0);
        if (style == QLatin1String("Text.Outline") || style == QLatin1String("Outline"))
            ui->styleComboBox->setCurrentIndex(1);
        if (style == QLatin1String("Text.Raised") || style == QLatin1String("Raised"))
            ui->styleComboBox->setCurrentIndex(2);
        else if (style == QLatin1String("Text.Sunken") || style == QLatin1String("Sunken"))
            ui->styleComboBox->setCurrentIndex(3);
    } else {
        ui->styleComboBox->setCurrentIndex(0);
    }
}

void ContextPaneTextWidget::setVerticalAlignmentVisible(bool b)
{
    ui->centerVAlignmentButton->setEnabled(b);
    ui->topAlignmentButton->setEnabled(b);
    ui->bottomAlignmentButton->setEnabled(b);
}

void ContextPaneTextWidget::setStyleVisible(bool b)
{
    ui->styleComboBox->setEnabled(b);
    ui->styleLabel->setEnabled(b);
    ui->textColorButton->setEnabled(b);
}

void ContextPaneTextWidget::onTextColorButtonToggled(bool flag)
{
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    if (flag)
        ui->colorButton->setChecked(false);
    QPoint p = mapToGlobal(ui->textColorButton->pos());
    parentContextWidget->colorDialog()->setupColor(ui->textColorButton->color());
    p = parentContextWidget->colorDialog()->parentWidget()->mapFromGlobal(p);
    parentContextWidget->onShowColorDialog(flag, p);
}

void ContextPaneTextWidget::onColorButtonToggled(bool flag)
{
    if (flag)
        ui->textColorButton->setChecked(false);
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    QPoint p = mapToGlobal(ui->colorButton->pos());
    parentContextWidget->colorDialog()->setupColor(ui->colorButton->color());
    p = parentContextWidget->colorDialog()->parentWidget()->mapFromGlobal(p);
    parentContextWidget->onShowColorDialog(flag, p);
}

void ContextPaneTextWidget::onColorDialogApplied(const QColor &)
{
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    parentContextWidget->onShowColorDialog(false, QPoint());
    if (ui->textColorButton->isChecked())
        emit  propertyChanged(QLatin1String("styleColor"),parentContextWidget->colorDialog()->color());; //write back color
    if (ui->colorButton->isChecked())
        emit  propertyChanged(QLatin1String("color"),parentContextWidget->colorDialog()->color());; //write back color
    ui->textColorButton->setChecked(false);
    ui->colorButton->setChecked(false);
}

void ContextPaneTextWidget::onColorDialogCancled()
{
    ContextPaneWidget *parentContextWidget = qobject_cast<ContextPaneWidget*>(parentWidget());
    parentContextWidget->onShowColorDialog(false, QPoint());
    ui->colorButton->setChecked(false);
    ui->colorButton->setChecked(false);
}

void ContextPaneTextWidget::onFontSizeChanged(int)
{
    if (m_fontSizeTimer > 0)
        killTimer(m_fontSizeTimer);
    m_fontSizeTimer = startTimer(200);
}

void ContextPaneTextWidget::onFontFormatChanged()
{
    int size = ui->fontSizeSpinBox->value();
    if (ui->fontSizeSpinBox->isPointSize()) {
        emit removeAndChangeProperty(QLatin1String("font.pixelSize"), QLatin1String("font.pointSize"), size);
    } else {
        emit removeAndChangeProperty(QLatin1String("font.pointSize"), QLatin1String("font.pixelSize"), size);
    }

}

void ContextPaneTextWidget::onBoldCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.bold"), value);
    else
        emit removeProperty(QLatin1String("font.bold"));

}

void ContextPaneTextWidget::onItalicCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.italic"), value);
    else
        emit removeProperty(QLatin1String("font.italic"));
}

void ContextPaneTextWidget::onUnderlineCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.underline"), value);
    else
        emit removeProperty(QLatin1String("font.underline"));
}

void ContextPaneTextWidget::onStrikeoutCheckedChanged(bool value)
{
    if (value)
        emit propertyChanged(QLatin1String("font.strikeout"), value);
    else
        emit removeProperty(QLatin1String("font.strikeout"));
}

void ContextPaneTextWidget::onCurrentFontChanged(const QFont &font)
{
    font.family();
    emit propertyChanged(QLatin1String("font.family"), QVariant(QString('\"') + font.family() + QString('\"')));
}

void ContextPaneTextWidget::onHorizontalAlignmentChanged()
{
    QString alignment;
    if (ui->centerHAlignmentButton->isChecked())
        alignment = QLatin1String("AlignHCenter");
    else if (ui->leftAlignmentButton->isChecked())
        alignment = QLatin1String("AlignLeft");
    else if (ui->rightAlignmentButton->isChecked())
        alignment = QLatin1String("AlignRight");
    if (m_horizontalAlignment != alignment) {
        m_horizontalAlignment = alignment;
        if (alignment == QLatin1String("AlignLeft"))
            emit removeProperty(QLatin1String("horizontalAlignment"));
        else
            emit propertyChanged(QLatin1String("horizontalAlignment"), alignment);
    }
}

void ContextPaneTextWidget::onStyleComboBoxChanged(const QString &style)
{
    if (style == QLatin1String("Normal"))
        emit removeProperty(QLatin1String("style"));
    else
        emit propertyChanged(QLatin1String("style"), QVariant(QLatin1String("Text.") + style));
}

void ContextPaneTextWidget::onVerticalAlignmentChanged()
{
    QString alignment;
    if (ui->centerVAlignmentButton->isChecked())
        alignment = QLatin1String("AlignVCenter");
    else if (ui->topAlignmentButton->isChecked())
        alignment = QLatin1String("AlignTop");
    else if (ui->bottomAlignmentButton->isChecked())
        alignment = QLatin1String("AlignBottom");
    if (m_verticalAlignment != alignment) {
        m_verticalAlignment = alignment;
        if (alignment == QLatin1String("AlignTop"))
            emit removeProperty(QLatin1String("verticalAlignment"));
        else
            emit propertyChanged(QLatin1String("verticalAlignment"), alignment);
    }
}

ContextPaneTextWidget::~ContextPaneTextWidget()
{
    delete ui;
}

void ContextPaneTextWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void ContextPaneTextWidget::timerEvent(QTimerEvent *event)
{
    if (event->timerId() == m_fontSizeTimer) {
        killTimer(m_fontSizeTimer);
        m_fontSizeTimer = -1;
        int value = ui->fontSizeSpinBox->value();
        if (ui->fontSizeSpinBox->isPointSize())
            emit propertyChanged(QLatin1String("font.pointSize"), value);
        else
            emit propertyChanged(QLatin1String("font.pixelSize"), value);
    }
}

} //QmlDesigner
<|endoftext|>


<commit_before>/* $Id$ */

#include <fe/fe.h>
#include <fe/quadrature.h>
#include <grid/tria_iterator.h>
#include <grid/tria_accessor.h>

template <int dim>
FEValues<dim>::UpdateStruct::UpdateStruct () :
		q_points(false),
		gradients(false),
		jacobians(false),
		JxW_values(false),
		ansatz_points(false) {};

/*------------------------------- FEValues -------------------------------*/

template <int dim>
FEValues<dim>::FEValues (const FiniteElement<dim> &fe,
			 const Quadrature<dim>    &quadrature,
			 const UpdateStruct       &update_flags) :
		n_quadrature_points(quadrature.n_quadrature_points),
		total_dofs(fe.total_dofs),
		shape_values(fe.total_dofs, quadrature.n_quadrature_points),
		shape_gradients(fe.total_dofs,
				vector<Point<dim> >(quadrature.n_quadrature_points)),
		unit_shape_gradients(fe.total_dofs,
				     vector<Point<dim> >(quadrature.n_quadrature_points)),
		weights(quadrature.n_quadrature_points, 0),
		JxW_values(quadrature.n_quadrature_points, 0),
		quadrature_points(quadrature.n_quadrature_points, Point<dim>()),
		unit_quadrature_points(quadrature.n_quadrature_points, Point<dim>()),
		ansatz_points (fe.total_dofs, Point<dim>()),
		jacobi_matrices (quadrature.n_quadrature_points,
				 dFMatrix(dim,dim)),
		update_flags (update_flags)
{
  for (unsigned int i=0; i<fe.total_dofs; ++i)
    for (unsigned int j=0; j<n_quadrature_points; ++j)
      {
	shape_values(i,j) = fe.shape_value(i, quadrature.quad_point(j));
	unit_shape_gradients[i][j]
	  = fe.shape_grad(i, quadrature.quad_point(j));
      };

  for (unsigned int i=0; i<n_quadrature_points; ++i)
    {
      weights[i] = quadrature.weight(i);
      unit_quadrature_points[i] = quadrature.quad_point(i);
    };
};

template <int dim>
double FEValues<dim>::shape_value (const unsigned int i,
				   const unsigned int j) const {
  Assert (i<(unsigned int)shape_values.m(), ExcInvalidIndex (i, shape_values.m()));
  Assert (j<(unsigned int)shape_values.n(), ExcInvalidIndex (j, shape_values.n()));

  return shape_values(i,j);
};

template <int dim>
const Point<dim> &
FEValues<dim>::shape_grad (const unsigned int i,
			   const unsigned int j) const {
  Assert (i<(unsigned int)shape_values.m(), ExcInvalidIndex (i, shape_values.m()));
  Assert (j<(unsigned int)shape_values.n(), ExcInvalidIndex (j, shape_values.n()));
  Assert (update_flags.gradients, ExcAccessToUninitializedField());

  return shape_gradients[i][j];
};

template <int dim>
const Point<dim> & FEValues<dim>::quadrature_point (const unsigned int i) const {
  Assert (i<n_quadrature_points, ExcInvalidIndex(i, n_quadrature_points));
  Assert (update_flags.q_points, ExcAccessToUninitializedField());

  return quadrature_points[i];
};

template <int dim>
const Point<dim> & FEValues<dim>::ansatz_point (const unsigned int i) const {
  Assert (i<ansatz_points.size(), ExcInvalidIndex(i, ansatz_points.size()));
  Assert (update_flags.ansatz_points, ExcAccessToUninitializedField());

  return ansatz_points[i];
};

template <int dim>
double FEValues<dim>::JxW (const unsigned int i) const {
  Assert (i<n_quadrature_points, ExcInvalidIndex(i, n_quadrature_points));
  Assert (update_flags.JxW_values, ExcAccessToUninitializedField());

  return JxW_values[i];
};

template <int dim>
void FEValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &cell,
			    const FiniteElement<dim>                         &fe) {
				   // fill jacobi matrices and real
				   // quadrature points
  if (update_flags.jacobians || update_flags.q_points)
    fe.fill_fe_values (cell,
		       unit_quadrature_points,
		       jacobi_matrices,
		       update_flags.jacobians,
		       ansatz_points,
		       update_flags.ansatz_points,
		       quadrature_points,
		       update_flags.q_points);

				   // compute gradients on real element if
				   // requested
  if (update_flags.gradients)
    {
      Assert (update_flags.jacobians, ExcCannotInitializeField());

      for (unsigned int i=0; i<fe.total_dofs; ++i)
	for (unsigned int j=0; j<n_quadrature_points; ++j)
	  for (unsigned int s=0; s<dim; ++s)
	    {
	      shape_gradients[i][j](s) = 0;

					       // (grad psi)_s =
					       // (grad_{\xi\eta})_b J_{bs}
					       // with J_{bs}=(d\xi_b)/(dx_s)
	      for (unsigned int b=0; b<dim; ++b)
		shape_gradients[i][j](s)
		  +=
		  unit_shape_gradients[i][j](b) * jacobi_matrices[j](b,s);
	    };
    };

				   // compute Jacobi determinants in
				   // quadrature points.
				   // refer to the general doc for
				   // why we take the inverse of the
				   // determinant
  if (update_flags.JxW_values)
    {
      Assert (update_flags.jacobians,
	      ExcCannotInitializeField());
      for (unsigned int i=0; i<n_quadrature_points; ++i)
	JxW_values[i] = weights[i] / jacobi_matrices[i].determinant();
    };
};

/*------------------------------- FiniteElementBase ----------------------*/

template <int dim>
FiniteElementBase<dim>::FiniteElementBase (const FiniteElementBase<dim> &f) :
		total_dofs(f.total_dofs),
		interface_constraints (f.interface_constraints)
{
  for (unsigned int i=0; i<(1<<dim); ++i)
    {
      restriction[i] = f.restriction[i];
      prolongation[i] = f.prolongation[i];
    };
}

template <int dim>
const dFMatrix &
FiniteElementBase<dim>::restrict (const unsigned int child) const {
  Assert (child<(1<<dim), ExcInvalidIndex(child));
  return restriction[child];
};

template <int dim>
const dFMatrix &
FiniteElementBase<dim>::prolongate (const unsigned int child) const {
  Assert (child<(1<<dim), ExcInvalidIndex(child));
  return prolongation[child];
};

template <int dim>
const dFMatrix &
FiniteElementBase<dim>::constraints () const {
  return interface_constraints;
};

template <int dim>
bool FiniteElementBase<dim>::operator == (const FiniteElementBase<dim> &f) const {
  return ((total_dofs == f.total_dofs) &&
	  (interface_constraints == f.interface_constraints));
};

template <int dim>
double FiniteElementBase<dim>::shape_value (const unsigned int,
					    const Point<dim> &) const {
  Assert (false, ExcPureFunctionCalled());
  return 0;
};

template <int dim>
Point<dim> FiniteElementBase<dim>::shape_grad (const unsigned int,
					       const Point<dim> &) const {
  Assert (false, ExcPureFunctionCalled());
  return Point<dim>();
};

template <int dim>
void FiniteElementBase<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator &,
					     const vector<Point<dim> > &,
					     vector<dFMatrix> &,
					     const bool,
					     vector<Point<dim> > &,
					     const bool,
					     vector<Point<dim> > &,
					     const bool) const {
  Assert (false, ExcPureFunctionCalled());
};

template <int dim>
void FiniteElementBase<dim>::face_ansatz_points (const typename Triangulation<dim>::face_iterator &,
						 vector<Point<dim> > &) const {
  Assert (false, ExcPureFunctionCalled());
};

/*------------------------------- FiniteElement ----------------------*/

bool FiniteElement<1>::operator == (const FiniteElement<1> &f) const {
  return ((dofs_per_vertex == f.dofs_per_vertex) &&
	  (dofs_per_line == f.dofs_per_line) &&
	  (FiniteElementBase<1>::operator == (f)));
};

void FiniteElement<1>::fill_fe_values (const Triangulation<1>::cell_iterator &cell,
				       const vector<Point<1> > &unit_points,
				       vector<dFMatrix>  &jacobians,
				       const bool         compute_jacobians,
				       vector<Point<1> > &ansatz_points,
				       const bool         compute_ansatz_points,
				       vector<Point<1> > &q_points,
				       const bool         compute_q_points) const {
  Assert (jacobians.size() == unit_points.size(),
	  ExcWrongFieldDimension(jacobians.size(), unit_points.size()));
  Assert (q_points.size() == unit_points.size(),
	  ExcWrongFieldDimension(q_points.size(), unit_points.size()));
  Assert (ansatz_points.size() == total_dofs,
	  ExcWrongFieldDimension(ansatz_points.size(), total_dofs));

				   // local mesh width
  const double h=(cell->vertex(1)(0) - cell->vertex(0)(0));

  for (unsigned int i=0; i<q_points.size(); ++i)
    {
      if (compute_jacobians)
	jacobians[i](0,0) = 1./h;
      if (compute_q_points)
	q_points[i] = cell->vertex(0) + h*unit_points[i];
    };

				   // compute ansatz points. The first ones
				   // belong to vertex one, the second ones
				   // to vertex two, all following are
				   // equally spaced along the line
  if (compute_ansatz_points)
    {
      ansatz_points.erase (ansatz_points.begin(), ansatz_points.end());
      ansatz_points.reserve (total_dofs);

				       // first the dofs in the vertices
      for (unsigned int vertex=0; vertex<2; vertex++)
	for (unsigned int i=0; i<dofs_per_vertex; ++i)
	  ansatz_points.push_back (cell->vertex(vertex));

				       // now dofs on line
      for (unsigned int i=0; i<dofs_per_line; ++i)
	ansatz_points.push_back (cell->vertex(0) +
				 Point<1>((i+1.0)/(total_dofs+1.0)*h));
    };
};

void FiniteElement<1>::face_ansatz_points (const typename Triangulation<1>::face_iterator &,
					   vector<Point<1> > &) const {
				   // is this function useful in 1D?
  Assert (false, ExcPureFunctionCalled());
};

bool FiniteElement<2>::operator == (const FiniteElement<2> &f) const {
  return ((dofs_per_vertex == f.dofs_per_vertex) &&
	  (dofs_per_line == f.dofs_per_line) &&
	  (dofs_per_quad == f.dofs_per_quad) &&
	  (FiniteElementBase<2>::operator == (f)));
};

void FiniteElement<2>::fill_fe_values (const Triangulation<2>::cell_iterator &,
				       const vector<Point<2> > &,
				       vector<dFMatrix> &,
				       const bool,
				       vector<Point<2> > &,
				       const bool,
				       vector<Point<2> > &,
				       const bool) const {
  Assert (false, ExcPureFunctionCalled());
};

void FiniteElement<2>::face_ansatz_points (const typename Triangulation<2>::face_iterator &,
					   vector<Point<2> > &) const {
				   // is this function useful in 1D?
  Assert (false, ExcPureFunctionCalled());
};

/*------------------------------- Explicit Instantiations -------------*/

template struct FEValues<1>::UpdateStruct;
template struct FEValues<2>::UpdateStruct;

template class FEValues<1>;
template class FEValues<2>;

template class FiniteElementBase<1>;
template class FiniteElementBase<2>;

template class FiniteElement<1>;
template class FiniteElement<2>;
<commit_msg>Add slight performance enhancement.<commit_after>/* $Id$ */

#include <fe/fe.h>
#include <fe/quadrature.h>
#include <grid/tria_iterator.h>
#include <grid/tria_accessor.h>

template <int dim>
FEValues<dim>::UpdateStruct::UpdateStruct () :
		q_points(false),
		gradients(false),
		jacobians(false),
		JxW_values(false),
		ansatz_points(false) {};

/*------------------------------- FEValues -------------------------------*/

template <int dim>
FEValues<dim>::FEValues (const FiniteElement<dim> &fe,
			 const Quadrature<dim>    &quadrature,
			 const UpdateStruct       &update_flags) :
		n_quadrature_points(quadrature.n_quadrature_points),
		total_dofs(fe.total_dofs),
		shape_values(fe.total_dofs, quadrature.n_quadrature_points),
		shape_gradients(fe.total_dofs,
				vector<Point<dim> >(quadrature.n_quadrature_points)),
		unit_shape_gradients(fe.total_dofs,
				     vector<Point<dim> >(quadrature.n_quadrature_points)),
		weights(quadrature.n_quadrature_points, 0),
		JxW_values(quadrature.n_quadrature_points, 0),
		quadrature_points(quadrature.n_quadrature_points, Point<dim>()),
		unit_quadrature_points(quadrature.n_quadrature_points, Point<dim>()),
		ansatz_points (fe.total_dofs, Point<dim>()),
		jacobi_matrices (quadrature.n_quadrature_points,
				 dFMatrix(dim,dim)),
		update_flags (update_flags)
{
  for (unsigned int i=0; i<fe.total_dofs; ++i)
    for (unsigned int j=0; j<n_quadrature_points; ++j)
      {
	shape_values(i,j) = fe.shape_value(i, quadrature.quad_point(j));
	unit_shape_gradients[i][j]
	  = fe.shape_grad(i, quadrature.quad_point(j));
      };

  for (unsigned int i=0; i<n_quadrature_points; ++i)
    {
      weights[i] = quadrature.weight(i);
      unit_quadrature_points[i] = quadrature.quad_point(i);
    };
};

template <int dim>
double FEValues<dim>::shape_value (const unsigned int i,
				   const unsigned int j) const {
  Assert (i<(unsigned int)shape_values.m(), ExcInvalidIndex (i, shape_values.m()));
  Assert (j<(unsigned int)shape_values.n(), ExcInvalidIndex (j, shape_values.n()));

  return shape_values(i,j);
};

template <int dim>
const Point<dim> &
FEValues<dim>::shape_grad (const unsigned int i,
			   const unsigned int j) const {
  Assert (i<(unsigned int)shape_values.m(), ExcInvalidIndex (i, shape_values.m()));
  Assert (j<(unsigned int)shape_values.n(), ExcInvalidIndex (j, shape_values.n()));
  Assert (update_flags.gradients, ExcAccessToUninitializedField());

  return shape_gradients[i][j];
};

template <int dim>
const Point<dim> & FEValues<dim>::quadrature_point (const unsigned int i) const {
  Assert (i<n_quadrature_points, ExcInvalidIndex(i, n_quadrature_points));
  Assert (update_flags.q_points, ExcAccessToUninitializedField());

  return quadrature_points[i];
};

template <int dim>
const Point<dim> & FEValues<dim>::ansatz_point (const unsigned int i) const {
  Assert (i<ansatz_points.size(), ExcInvalidIndex(i, ansatz_points.size()));
  Assert (update_flags.ansatz_points, ExcAccessToUninitializedField());

  return ansatz_points[i];
};

template <int dim>
double FEValues<dim>::JxW (const unsigned int i) const {
  Assert (i<n_quadrature_points, ExcInvalidIndex(i, n_quadrature_points));
  Assert (update_flags.JxW_values, ExcAccessToUninitializedField());

  return JxW_values[i];
};

template <int dim>
void FEValues<dim>::reinit (const typename Triangulation<dim>::cell_iterator &cell,
			    const FiniteElement<dim>                         &fe) {
				   // fill jacobi matrices and real
				   // quadrature points
  if (update_flags.jacobians || update_flags.q_points)
    fe.fill_fe_values (cell,
		       unit_quadrature_points,
		       jacobi_matrices,
		       update_flags.jacobians,
		       ansatz_points,
		       update_flags.ansatz_points,
		       quadrature_points,
		       update_flags.q_points);

				   // compute gradients on real element if
				   // requested
  if (update_flags.gradients)
    {
      Assert (update_flags.jacobians, ExcCannotInitializeField());

      for (unsigned int i=0; i<fe.total_dofs; ++i)
	for (unsigned int j=0; j<n_quadrature_points; ++j)
	  for (unsigned int s=0; s<dim; ++s)
	    {
	      shape_gradients[i][j](s) = 0;

					       // (grad psi)_s =
					       // (grad_{\xi\eta})_b J_{bs}
					       // with J_{bs}=(d\xi_b)/(dx_s)
	      for (unsigned int b=0; b<dim; ++b)
		shape_gradients[i][j](s)
		  +=
		  unit_shape_gradients[i][j](b) * jacobi_matrices[j](b,s);
	    };
    };

				   // compute Jacobi determinants in
				   // quadrature points.
				   // refer to the general doc for
				   // why we take the inverse of the
				   // determinant
  if (update_flags.JxW_values)
    {
      Assert (update_flags.jacobians,
	      ExcCannotInitializeField());
      for (unsigned int i=0; i<n_quadrature_points; ++i)
	JxW_values[i] = weights[i] / jacobi_matrices[i].determinant();
    };
};

/*------------------------------- FiniteElementBase ----------------------*/

template <int dim>
FiniteElementBase<dim>::FiniteElementBase (const FiniteElementBase<dim> &f) :
		total_dofs(f.total_dofs),
		interface_constraints (f.interface_constraints)
{
  for (unsigned int i=0; i<(1<<dim); ++i)
    {
      restriction[i] = f.restriction[i];
      prolongation[i] = f.prolongation[i];
    };
}

template <int dim>
const dFMatrix &
FiniteElementBase<dim>::restrict (const unsigned int child) const {
  Assert (child<(1<<dim), ExcInvalidIndex(child));
  return restriction[child];
};

template <int dim>
const dFMatrix &
FiniteElementBase<dim>::prolongate (const unsigned int child) const {
  Assert (child<(1<<dim), ExcInvalidIndex(child));
  return prolongation[child];
};

template <int dim>
const dFMatrix &
FiniteElementBase<dim>::constraints () const {
  return interface_constraints;
};

template <int dim>
bool FiniteElementBase<dim>::operator == (const FiniteElementBase<dim> &f) const {
  return ((total_dofs == f.total_dofs) &&
	  (interface_constraints == f.interface_constraints));
};

template <int dim>
double FiniteElementBase<dim>::shape_value (const unsigned int,
					    const Point<dim> &) const {
  Assert (false, ExcPureFunctionCalled());
  return 0;
};

template <int dim>
Point<dim> FiniteElementBase<dim>::shape_grad (const unsigned int,
					       const Point<dim> &) const {
  Assert (false, ExcPureFunctionCalled());
  return Point<dim>();
};

template <int dim>
void FiniteElementBase<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator &,
					     const vector<Point<dim> > &,
					     vector<dFMatrix> &,
					     const bool,
					     vector<Point<dim> > &,
					     const bool,
					     vector<Point<dim> > &,
					     const bool) const {
  Assert (false, ExcPureFunctionCalled());
};

template <int dim>
void FiniteElementBase<dim>::face_ansatz_points (const typename Triangulation<dim>::face_iterator &,
						 vector<Point<dim> > &) const {
  Assert (false, ExcPureFunctionCalled());
};

/*------------------------------- FiniteElement ----------------------*/

bool FiniteElement<1>::operator == (const FiniteElement<1> &f) const {
  return ((dofs_per_vertex == f.dofs_per_vertex) &&
	  (dofs_per_line == f.dofs_per_line) &&
	  (FiniteElementBase<1>::operator == (f)));
};

void FiniteElement<1>::fill_fe_values (const Triangulation<1>::cell_iterator &cell,
				       const vector<Point<1> > &unit_points,
				       vector<dFMatrix>  &jacobians,
				       const bool         compute_jacobians,
				       vector<Point<1> > &ansatz_points,
				       const bool         compute_ansatz_points,
				       vector<Point<1> > &q_points,
				       const bool         compute_q_points) const {
  Assert (jacobians.size() == unit_points.size(),
	  ExcWrongFieldDimension(jacobians.size(), unit_points.size()));
  Assert (q_points.size() == unit_points.size(),
	  ExcWrongFieldDimension(q_points.size(), unit_points.size()));
  Assert (ansatz_points.size() == total_dofs,
	  ExcWrongFieldDimension(ansatz_points.size(), total_dofs));

				   // local mesh width
  const double h=(cell->vertex(1)(0) - cell->vertex(0)(0));

  for (unsigned int i=0; i<q_points.size(); ++i)
    {
      if (compute_jacobians)
	jacobians[i](0,0) = 1./h;
      if (compute_q_points)
	q_points[i] = cell->vertex(0) + h*unit_points[i];
    };

				   // compute ansatz points. The first ones
				   // belong to vertex one, the second ones
				   // to vertex two, all following are
				   // equally spaced along the line
  if (compute_ansatz_points)
    {
      unsigned int next = 0;
				       // first the dofs in the vertices
      for (unsigned int vertex=0; vertex<2; vertex++)
	for (unsigned int i=0; i<dofs_per_vertex; ++i)
	  ansatz_points[next++] = cell->vertex(vertex);

				       // now dofs on line
      for (unsigned int i=0; i<dofs_per_line; ++i)
	ansatz_points[next++] = cell->vertex(0) +
				Point<1>((i+1.0)/(total_dofs+1.0)*h);
    };
};

void FiniteElement<1>::face_ansatz_points (const typename Triangulation<1>::face_iterator &,
					   vector<Point<1> > &) const {
				   // is this function useful in 1D?
  Assert (false, ExcPureFunctionCalled());
};

bool FiniteElement<2>::operator == (const FiniteElement<2> &f) const {
  return ((dofs_per_vertex == f.dofs_per_vertex) &&
	  (dofs_per_line == f.dofs_per_line) &&
	  (dofs_per_quad == f.dofs_per_quad) &&
	  (FiniteElementBase<2>::operator == (f)));
};

void FiniteElement<2>::fill_fe_values (const Triangulation<2>::cell_iterator &,
				       const vector<Point<2> > &,
				       vector<dFMatrix> &,
				       const bool,
				       vector<Point<2> > &,
				       const bool,
				       vector<Point<2> > &,
				       const bool) const {
  Assert (false, ExcPureFunctionCalled());
};

void FiniteElement<2>::face_ansatz_points (const typename Triangulation<2>::face_iterator &,
					   vector<Point<2> > &) const {
				   // is this function useful in 1D?
  Assert (false, ExcPureFunctionCalled());
};

/*------------------------------- Explicit Instantiations -------------*/

template struct FEValues<1>::UpdateStruct;
template struct FEValues<2>::UpdateStruct;

template class FEValues<1>;
template class FEValues<2>;

template class FiniteElementBase<1>;
template class FiniteElementBase<2>;

template class FiniteElement<1>;
template class FiniteElement<2>;
<|endoftext|>


<commit_before>#ifndef GNR_STRING_HPP
# define GNR_STRING_HPP
# pragma once

#include <cstring>

#include <algorithm>

#include <iterator>

#include <limits>

#include <sstream>

#include <string>

#include <optional>

#include <type_traits>

#include <utility>

#include <vector>

namespace gnr
{

// cstrlen
//////////////////////////////////////////////////////////////////////////////
template <std::size_t N>
inline constexpr std::size_t cstrlen(char const (&)[N]) noexcept
{
  return N - 1;
}

//////////////////////////////////////////////////////////////////////////////
inline constexpr std::size_t cstrlen(char const* const p) noexcept
{
  return *p ? 1 + cstrlen(p + 1) : 0;
}

// stoi
//////////////////////////////////////////////////////////////////////////////
template <typename T,
  typename S,
  typename = std::enable_if_t<
    std::is_same_v<char, std::decay_t<decltype(std::declval<S>()[0])>>
  >
>
inline auto stoi(S const& s) noexcept ->
  decltype(std::begin(s), std::end(s), std::size(s), std::optional<T>())
{
  auto i(std::begin(s)), end(std::end(s));

  if (i == end)
  {
    return {};
  }
  else
  {
    bool positive;

    switch (*i)
    {
      case '+':
        positive = true;
        i = std::next(i);
        break;

      case '-':
        positive = false;
        i = std::next(i);
        break;

      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        positive = true;
        break;

      default:
        return {};
    }

    auto const max(std::numeric_limits<T>::max());
    auto const min(std::numeric_limits<T>::min());

    T r{};

    for (; i != end; i = std::next(i))
    {
      switch (*i)
      {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
        {
          unsigned char const d(*i - '0');

          if (positive && (r <= max / 10))
          {
            auto const t(10 * r);

            if (t <= max - d)
            {
              r = t + d;
            }
            else
            {
              return {};
            }
          }
          else if (!positive && (r >= min / 10))
          {
            auto const t(10 * r);

            if (t >= min + d)
            {
              r = t - d;
            }
            else
            {
              return {};
            }
          }
          else
          {
            return {};
          }
          break;
        }

        default:
          return {};
      }
    }

    return r;
  }
}

template <typename T>
inline std::optional<T> stoi(char const* s) noexcept
{
  bool positive;

  switch (*s)
  {
    case '+':
      positive = true;
      ++s;
      break;

    case '-':
      positive = false;
      ++s;
      break;

    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      positive = true;
      break;

    default:
      return {};
  }

  auto const max(std::numeric_limits<T>::max());
  auto const min(std::numeric_limits<T>::min());

  T r{};

  for (; *s; ++s)
  {
    switch (*s)
    {
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        {
          unsigned char const d(*s - '0');

          if (positive && (r <= max / 10))
          {
            auto const t(10 * r);

            if (t <= max - d)
            {
              r = t + d;
            }
            else
            {
              return {};
            }
          }
          else if (!positive && (r >= min / 10))
          {
            auto const t(10 * r);

            if (t >= min + d)
            {
              r = t - d;
            }
            else
            {
              return {};
            }
          }
          else
          {
            return {};
          }
        }
        break;

      default:
        return {};
    }
  }

  return r;
}

// join
//////////////////////////////////////////////////////////////////////////////
template <typename C>
inline typename C::value_type join(C const& container,
  typename C::value_type const sep) noexcept
{
  if (container.size())
  {
    typename C::value_type r(*container.begin());

    auto const end(container.end());

    for (auto i(std::next(container.begin())); i != end; ++i)
    {
      r += sep + *i;
    }

    return r;
  }
  else
  {
    return typename C::value_type();
  }
}

//////////////////////////////////////////////////////////////////////////////
template <typename C>
inline typename C::value_type join(C const& container,
  typename C::value_type::value_type const sep) noexcept
{
  if (container.size())
  {
    typename C::value_type r(container.front());

    auto const end(container.end());

    for (typename C::const_iterator i(container.begin() + 1); i != end; ++i)
    {
      r += sep + *i;
    }

    return r;
  }
  else
  {
    return typename C::value_type();
  }
}

// split
//////////////////////////////////////////////////////////////////////////////
template<class CharT, class Traits, class Allocator>
inline std::vector<std::basic_string<CharT, Traits, Allocator> >
split(std::basic_string<CharT, Traits, Allocator> const& s,
  CharT const delim) noexcept
{
  std::stringstream ss(s);

  std::string item;

  std::vector<typename std::decay<decltype(s)>::type> r;

  while (std::getline(ss, item, delim))
  {
    r.push_back(item);
  }

  return r;
}

//////////////////////////////////////////////////////////////////////////////
inline std::vector<std::string>
split(std::string const& s,
  char const* const delims = "\f\n\r\t\v") noexcept
{
  std::vector<typename std::decay<decltype(s)>::type> r;

  auto const S(s.size());
  decltype(s.size()) i{};

  while (i < S)
  {
    while ((i < S) && std::strchr(delims, s[i]))
    {
      ++i;
    }

    if (i == S)
    {
      break;
    }
    // else do nothing

    auto j(i + 1);

    while ((j < S) && !std::strchr(delims, s[j]))
    {
      ++j;
    }

    r.push_back(s.substr(i, j - i));

    i = j + 1;
  }

  return r;
}

// trim
//////////////////////////////////////////////////////////////////////////////
template<class CharT, class Traits, class Allocator>
inline std::basic_string<CharT, Traits, Allocator>&
ltrim(std::basic_string<CharT, Traits, Allocator>& s,
  CharT const* cs = " ") noexcept
{
  s.erase(s.begin(),
    std::find_if(s.begin(), s.end(),
      [cs](char const c) noexcept {
        return !std::strrchr(cs, c);
      }
    )
  );

  return s;
}

template<class CharT, class Traits, class Allocator>
inline std::basic_string<CharT, Traits, Allocator>&
rtrim(std::basic_string<CharT, Traits, Allocator>& s,
  CharT const* cs = " ") noexcept
{
  s.erase(std::find_if(s.rbegin(), s.rend(),
      [cs](char const c) noexcept {
        return !std::strrchr(cs, c);
      }
    ).base(),
    s.end()
  );

  return s;
}

template<class CharT, class Traits, class Allocator>
inline std::basic_string<CharT, Traits, Allocator>&
trim(std::basic_string<CharT, Traits, Allocator>& s,
  CharT const* cs = " ") noexcept
{
  return ltrim(rtrim(s, cs), cs);
}

}

#endif // GNR_STRING_HPP
<commit_msg>some fixes<commit_after>#ifndef GNR_STRING_HPP
# define GNR_STRING_HPP
# pragma once

#include <cstring>

#include <algorithm>

#include <iterator>

#include <limits>

#include <sstream>

#include <string>

#include <optional>

#include <type_traits>

#include <utility>

#include <vector>

namespace gnr
{

// cstrlen
//////////////////////////////////////////////////////////////////////////////
template <std::size_t N>
inline constexpr std::size_t cstrlen(char const (&)[N]) noexcept
{
  return N - 1;
}

//////////////////////////////////////////////////////////////////////////////
inline constexpr std::size_t cstrlen(char const* const p) noexcept
{
  return *p ? 1 + cstrlen(p + 1) : 0;
}

// stoi
//////////////////////////////////////////////////////////////////////////////
template <typename T,
  typename S,
  typename = std::enable_if_t<
    std::is_same_v<char, std::decay_t<decltype(std::declval<S>()[0])>>
  >
>
inline auto stoi(S const& s) noexcept ->
  decltype(std::begin(s), std::end(s), std::size(s), std::optional<T>())
{
  auto i(std::begin(s)), end(std::end(s));

  if (i == end)
  {
    return {};
  }
  else
  {
    bool positive;

    switch (*i)
    {
      case '+':
        positive = true;
        i = std::next(i);
        break;

      case '-':
        positive = false;
        i = std::next(i);
        break;

      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        positive = true;
        break;

      default:
        return {};
    }

    auto const max(std::numeric_limits<T>::max());
    auto const min(std::numeric_limits<T>::min());

    T r{};

    for (; i != end; i = std::next(i))
    {
      switch (*i)
      {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
        {
          unsigned char const d(*i - '0');

          if (positive && (r <= max / 10))
          {
            T const t(10 * r);

            if (t <= max - d)
            {
              r = t + d;
            }
            else
            {
              return {};
            }
          }
          else if (!positive && (r >= min / 10))
          {
            T const t(10 * r);

            if (t >= min + d)
            {
              r = t - d;
            }
            else
            {
              return {};
            }
          }
          else
          {
            return {};
          }
          break;
        }

        default:
          return {};
      }
    }

    return r;
  }
}

template <typename T>
inline std::optional<T> stoi(char const* s) noexcept
{
  bool positive;

  switch (*s)
  {
    case '+':
      positive = true;
      ++s;
      break;

    case '-':
      positive = false;
      ++s;
      break;

    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      positive = true;
      break;

    default:
      return {};
  }

  auto const max(std::numeric_limits<T>::max());
  auto const min(std::numeric_limits<T>::min());

  T r{};

  for (; *s; ++s)
  {
    switch (*s)
    {
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        {
          unsigned char const d(*s - '0');

          if (positive && (r <= max / 10))
          {
            T const t(10 * r);

            if (t <= max - d)
            {
              r = t + d;
            }
            else
            {
              return {};
            }
          }
          else if (!positive && (r >= min / 10))
          {
            T const t(10 * r);

            if (t >= min + d)
            {
              r = t - d;
            }
            else
            {
              return {};
            }
          }
          else
          {
            return {};
          }
        }
        break;

      default:
        return {};
    }
  }

  return r;
}

// join
//////////////////////////////////////////////////////////////////////////////
template <typename C>
inline typename C::value_type join(C const& container,
  typename C::value_type const sep) noexcept
{
  if (container.size())
  {
    typename C::value_type r(*container.begin());

    auto const end(container.end());

    for (auto i(std::next(container.begin())); i != end; ++i)
    {
      r += sep + *i;
    }

    return r;
  }
  else
  {
    return typename C::value_type();
  }
}

//////////////////////////////////////////////////////////////////////////////
template <typename C>
inline typename C::value_type join(C const& container,
  typename C::value_type::value_type const sep) noexcept
{
  if (container.size())
  {
    typename C::value_type r(container.front());

    auto const end(container.end());

    for (typename C::const_iterator i(container.begin() + 1); i != end; ++i)
    {
      r += sep + *i;
    }

    return r;
  }
  else
  {
    return typename C::value_type();
  }
}

// split
//////////////////////////////////////////////////////////////////////////////
template<class CharT, class Traits, class Allocator>
inline std::vector<std::basic_string<CharT, Traits, Allocator> >
split(std::basic_string<CharT, Traits, Allocator> const& s,
  CharT const delim) noexcept
{
  std::stringstream ss(s);

  std::string item;

  std::vector<typename std::decay<decltype(s)>::type> r;

  while (std::getline(ss, item, delim))
  {
    r.push_back(item);
  }

  return r;
}

//////////////////////////////////////////////////////////////////////////////
inline std::vector<std::string>
split(std::string const& s,
  char const* const delims = "\f\n\r\t\v") noexcept
{
  std::vector<typename std::decay<decltype(s)>::type> r;

  auto const S(s.size());
  decltype(s.size()) i{};

  while (i < S)
  {
    while ((i < S) && std::strchr(delims, s[i]))
    {
      ++i;
    }

    if (i == S)
    {
      break;
    }
    // else do nothing

    auto j(i + 1);

    while ((j < S) && !std::strchr(delims, s[j]))
    {
      ++j;
    }

    r.push_back(s.substr(i, j - i));

    i = j + 1;
  }

  return r;
}

// trim
//////////////////////////////////////////////////////////////////////////////
template<class CharT, class Traits, class Allocator>
inline std::basic_string<CharT, Traits, Allocator>&
ltrim(std::basic_string<CharT, Traits, Allocator>& s,
  CharT const* cs = " ") noexcept
{
  s.erase(s.begin(),
    std::find_if(s.begin(), s.end(),
      [cs](char const c) noexcept {
        return !std::strrchr(cs, c);
      }
    )
  );

  return s;
}

template<class CharT, class Traits, class Allocator>
inline std::basic_string<CharT, Traits, Allocator>&
rtrim(std::basic_string<CharT, Traits, Allocator>& s,
  CharT const* cs = " ") noexcept
{
  s.erase(std::find_if(s.rbegin(), s.rend(),
      [cs](char const c) noexcept {
        return !std::strrchr(cs, c);
      }
    ).base(),
    s.end()
  );

  return s;
}

template<class CharT, class Traits, class Allocator>
inline std::basic_string<CharT, Traits, Allocator>&
trim(std::basic_string<CharT, Traits, Allocator>& s,
  CharT const* cs = " ") noexcept
{
  return ltrim(rtrim(s, cs), cs);
}

}

#endif // GNR_STRING_HPP
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include <boost/test/unit_test.hpp>

#include <OISKeyboard.h>

#include "CoreStdIncludes.h"
#include "Core.h"
#include "Foundation.h"
#include "ServiceInterfaces.h"
#include "StaticModuleDefinitions.h"

#include "ConsoleModuleApi.h"
#include "ConsoleModule.h"
#include "ConsoleManager.h"
#include "OgreOverlay.h"

#include "InputEvents.h"

//! Unit test for framework
BOOST_AUTO_TEST_SUITE(test_suite_support_modules)

Foundation::Framework &CreateFramework()
{
    static Foundation::Framework fw;
    return fw;
}

struct TestA
{
    Console::CommandResult TestCallbackSuccess(const Core::StringVector &params)
    {
        BOOST_CHECK_EQUAL(params[0], "paramA");
        BOOST_CHECK_EQUAL(params[1], "paramB");

        return Console::ResultSuccess("Success");
    }
    Console::CommandResult TestCallbackFailure(const Core::StringVector &params)
    {
        BOOST_CHECK_EQUAL(params.size(), 0);

        return Console::ResultFailure();
    }
};

struct TestB
{
    Console::CommandResult TestCallbackThreaded(const Core::StringVector &params)
    {
        test_var_ = 1;
        return Console::ResultSuccess();
    }

    void operator()()
    {
        test_var_ = 0;
        Console::CommandService *console = fw_->GetService<Console::CommandService>
            (Foundation::Service::ST_ConsoleCommand);

        console->RegisterCommand(Console::CreateCommand("Test CommandC", "Test command threaded", Console::Bind(this, &TestB::TestCallbackThreaded), true));

        console->Update();
        boost::optional<Console::CommandResult> result;
        while ( !(result = console->Poll("Test CommandC")) )
            console->Update();

        BOOST_CHECK_EQUAL (result->success_, true);
    }
    Foundation::Framework *fw_;
    int test_var_;
};

BOOST_AUTO_TEST_CASE( support_modules_console_commands )
{
    Foundation::Framework &fw = CreateFramework();

    fw.GetModuleManager()->ExcludeModule("StaticModuleTest");

    //! \todo Gtk seems to cause problems with unit tests, so excluded for now
    //! \bug Re-creating Gtk::Main when running unit tests in debug mode causes a crash.
    //!      It should have been destroyed properly though, and unloading/loading GtkmmUI
    //!      module at runtime works just fine.
    fw.GetModuleManager()->ExcludeModule("GtkmmUI");

    Test::StaticModuleDefinitions static_test;
    static_test(&fw);
    fw.GetModuleManager()->PreInitializeModule(fw.GetModuleManager()->GetModule(Foundation::Module::MT_Scene).lock().get());
    fw.GetModuleManager()->InitializeModule(fw.GetModuleManager()->GetModule(Foundation::Module::MT_Scene).lock().get());
    fw.GetModuleManager()->PostInitializeModule(fw.GetModuleManager()->GetModule(Foundation::Module::MT_Scene).lock().get());

    fw.GetModuleManager()->LoadModuleByName("SupportModules", "ConsoleModule");
    BOOST_CHECK (fw.GetModuleManager()->HasModule(Foundation::Module::MT_Console));

    Console::CommandService *console = fw.GetService<Console::CommandService>
        (Foundation::Service::ST_ConsoleCommand);

    TestA test_class;
    console->RegisterCommand(Console::CreateCommand("Test_CommandA", "Test command Success", Console::Bind(&test_class, &TestA::TestCallbackSuccess)));
    console->RegisterCommand(Console::CreateCommand("Test_CommandB", "Test command Failure", Console::Bind(&test_class, &TestA::TestCallbackFailure)));

    Console::CommandResult result = console->ExecuteCommand("Test_CommandA (paramA, paramB )");
    BOOST_CHECK_EQUAL (result.success_, true);
    BOOST_CHECK_EQUAL (result.why_, "Success");

    result = console->ExecuteCommand("Test_CommandB");
    BOOST_CHECK_EQUAL (result.success_, false);
    BOOST_CHECK_EQUAL (result.why_.size(), 0);

    TestB testb;
    testb.fw_ = &fw;

    Core::Thread thread(boost::ref(testb));
    console->QueueCommand("Test CommandC");
    thread.join();

    BOOST_CHECK_EQUAL (testb.test_var_, 1);
}

BOOST_AUTO_TEST_CASE( support_modules_console_ogre )
{
    Foundation::Framework &fw = CreateFramework();

    Console::ConsoleManager *console_manager = checked_static_cast<Console::ConsoleManager*>(fw.GetService<Console::ConsoleServiceInterface>
        (Foundation::Service::ST_Console));

    Console::ConsolePtr ogre_console = console_manager->GetOgre();
    Console::OgreOverlay *overlay = checked_static_cast<Console::OgreOverlay*>(ogre_console.get());

    overlay->SetVisible(true);
    BOOST_CHECK_EQUAL(overlay->IsVisible(), true);
    overlay->Update(60); // fast-forward one minute
    BOOST_CHECK_EQUAL(overlay->IsVisible(), true);
    BOOST_CHECK_EQUAL(overlay->IsActive(), true);

    overlay->Scroll(30000);
    overlay->Scroll(-30000);
    overlay->Scroll(300000);
    overlay->Scroll(-2);
    overlay->Scroll(1);
    overlay->Clear();
    overlay->Scroll(5);
    overlay->Scroll(-5);
    overlay->Print("Test message A");
    overlay->Print("Test message B");
    overlay->Print("Test message C");
    BOOST_CHECK_EQUAL(overlay->GetLine(0), std::string("Test message C"));
    BOOST_CHECK_EQUAL(overlay->GetLine(1), std::string("Test message B"));
    BOOST_CHECK_EQUAL(overlay->GetLine(2), std::string("Test message A"));

    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string(""));

    overlay->HandleKeyDown(OIS::KC_A, 65);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("A"));
    overlay->HandleKeyDown(OIS::KC_B, 66);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("AB"));
    overlay->HandleKeyDown(OIS::KC_BACK, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("A"));
    overlay->HandleKeyDown(OIS::KC_C, 67);
    overlay->HandleKeyDown(OIS::KC_RIGHT, 0);
    overlay->HandleKeyDown(OIS::KC_LEFT, 0);
    overlay->HandleKeyDown(OIS::KC_BACK, 0);
    overlay->HandleKeyDown(OIS::KC_DELETE, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string(""));

    overlay->HandleKeyDown(OIS::KC_A, 65);
    overlay->HandleKeyDown(OIS::KC_RETURN, 0);
    overlay->HandleKeyDown(OIS::KC_B, 66);
    overlay->HandleKeyDown(OIS::KC_RETURN, 0);
    overlay->HandleKeyDown(OIS::KC_C, 67);
    overlay->HandleKeyDown(OIS::KC_RETURN, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string(""));

    overlay->HandleKeyDown(OIS::KC_DOWN, 0);
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("C"));
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("A"));
    overlay->HandleKeyDown(OIS::KC_DOWN, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("B"));

    overlay->SetVisible(false);
    BOOST_CHECK_EQUAL(overlay->IsActive(), false);

    ogre_console.reset();
    fw.GetModuleManager()->UninitializeModules();
    fw.GetModuleManager()->UnloadModules();
}

BOOST_AUTO_TEST_SUITE_END()

<commit_msg>Fixed comment.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include <boost/test/unit_test.hpp>

#include <OISKeyboard.h>

#include "CoreStdIncludes.h"
#include "Core.h"
#include "Foundation.h"
#include "ServiceInterfaces.h"
#include "StaticModuleDefinitions.h"

#include "ConsoleModuleApi.h"
#include "ConsoleModule.h"
#include "ConsoleManager.h"
#include "OgreOverlay.h"

#include "InputEvents.h"

//! Unit test for framework
BOOST_AUTO_TEST_SUITE(test_suite_support_modules)

Foundation::Framework &CreateFramework()
{
    static Foundation::Framework fw;
    return fw;
}

struct TestA
{
    Console::CommandResult TestCallbackSuccess(const Core::StringVector &params)
    {
        BOOST_CHECK_EQUAL(params[0], "paramA");
        BOOST_CHECK_EQUAL(params[1], "paramB");

        return Console::ResultSuccess("Success");
    }
    Console::CommandResult TestCallbackFailure(const Core::StringVector &params)
    {
        BOOST_CHECK_EQUAL(params.size(), 0);

        return Console::ResultFailure();
    }
};

struct TestB
{
    Console::CommandResult TestCallbackThreaded(const Core::StringVector &params)
    {
        test_var_ = 1;
        return Console::ResultSuccess();
    }

    void operator()()
    {
        test_var_ = 0;
        Console::CommandService *console = fw_->GetService<Console::CommandService>
            (Foundation::Service::ST_ConsoleCommand);

        console->RegisterCommand(Console::CreateCommand("Test CommandC", "Test command threaded", Console::Bind(this, &TestB::TestCallbackThreaded), true));

        console->Update();
        boost::optional<Console::CommandResult> result;
        while ( !(result = console->Poll("Test CommandC")) )
            console->Update();

        BOOST_CHECK_EQUAL (result->success_, true);
    }
    Foundation::Framework *fw_;
    int test_var_;
};

BOOST_AUTO_TEST_CASE( support_modules_console_commands )
{
    Foundation::Framework &fw = CreateFramework();

    fw.GetModuleManager()->ExcludeModule("StaticModuleTest");

    //! \todo Gtk seems to cause problems with unit tests, so excluded for now
    //! \bug Re-creating Gtk::Main when running unit tests in debug mode causes a crash.
    //!      It should have been destroyed properly though, and unloading/loading GtkmmUI
    //!      module at runtime works just fine. The problem seems to be confined to
    //!      unit tests in debug mode (run outside of the debugger).
    fw.GetModuleManager()->ExcludeModule("GtkmmUI");

    Test::StaticModuleDefinitions static_test;
    static_test(&fw);
    fw.GetModuleManager()->PreInitializeModule(fw.GetModuleManager()->GetModule(Foundation::Module::MT_Scene).lock().get());
    fw.GetModuleManager()->InitializeModule(fw.GetModuleManager()->GetModule(Foundation::Module::MT_Scene).lock().get());
    fw.GetModuleManager()->PostInitializeModule(fw.GetModuleManager()->GetModule(Foundation::Module::MT_Scene).lock().get());

    fw.GetModuleManager()->LoadModuleByName("SupportModules", "ConsoleModule");
    BOOST_CHECK (fw.GetModuleManager()->HasModule(Foundation::Module::MT_Console));

    Console::CommandService *console = fw.GetService<Console::CommandService>
        (Foundation::Service::ST_ConsoleCommand);

    TestA test_class;
    console->RegisterCommand(Console::CreateCommand("Test_CommandA", "Test command Success", Console::Bind(&test_class, &TestA::TestCallbackSuccess)));
    console->RegisterCommand(Console::CreateCommand("Test_CommandB", "Test command Failure", Console::Bind(&test_class, &TestA::TestCallbackFailure)));

    Console::CommandResult result = console->ExecuteCommand("Test_CommandA (paramA, paramB )");
    BOOST_CHECK_EQUAL (result.success_, true);
    BOOST_CHECK_EQUAL (result.why_, "Success");

    result = console->ExecuteCommand("Test_CommandB");
    BOOST_CHECK_EQUAL (result.success_, false);
    BOOST_CHECK_EQUAL (result.why_.size(), 0);

    TestB testb;
    testb.fw_ = &fw;

    Core::Thread thread(boost::ref(testb));
    console->QueueCommand("Test CommandC");
    thread.join();

    BOOST_CHECK_EQUAL (testb.test_var_, 1);
}

BOOST_AUTO_TEST_CASE( support_modules_console_ogre )
{
    Foundation::Framework &fw = CreateFramework();

    Console::ConsoleManager *console_manager = checked_static_cast<Console::ConsoleManager*>(fw.GetService<Console::ConsoleServiceInterface>
        (Foundation::Service::ST_Console));

    Console::ConsolePtr ogre_console = console_manager->GetOgre();
    Console::OgreOverlay *overlay = checked_static_cast<Console::OgreOverlay*>(ogre_console.get());

    overlay->SetVisible(true);
    BOOST_CHECK_EQUAL(overlay->IsVisible(), true);
    overlay->Update(60); // fast-forward one minute
    BOOST_CHECK_EQUAL(overlay->IsVisible(), true);
    BOOST_CHECK_EQUAL(overlay->IsActive(), true);

    overlay->Scroll(30000);
    overlay->Scroll(-30000);
    overlay->Scroll(300000);
    overlay->Scroll(-2);
    overlay->Scroll(1);
    overlay->Clear();
    overlay->Scroll(5);
    overlay->Scroll(-5);
    overlay->Print("Test message A");
    overlay->Print("Test message B");
    overlay->Print("Test message C");
    BOOST_CHECK_EQUAL(overlay->GetLine(0), std::string("Test message C"));
    BOOST_CHECK_EQUAL(overlay->GetLine(1), std::string("Test message B"));
    BOOST_CHECK_EQUAL(overlay->GetLine(2), std::string("Test message A"));

    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string(""));

    overlay->HandleKeyDown(OIS::KC_A, 65);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("A"));
    overlay->HandleKeyDown(OIS::KC_B, 66);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("AB"));
    overlay->HandleKeyDown(OIS::KC_BACK, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("A"));
    overlay->HandleKeyDown(OIS::KC_C, 67);
    overlay->HandleKeyDown(OIS::KC_RIGHT, 0);
    overlay->HandleKeyDown(OIS::KC_LEFT, 0);
    overlay->HandleKeyDown(OIS::KC_BACK, 0);
    overlay->HandleKeyDown(OIS::KC_DELETE, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string(""));

    overlay->HandleKeyDown(OIS::KC_A, 65);
    overlay->HandleKeyDown(OIS::KC_RETURN, 0);
    overlay->HandleKeyDown(OIS::KC_B, 66);
    overlay->HandleKeyDown(OIS::KC_RETURN, 0);
    overlay->HandleKeyDown(OIS::KC_C, 67);
    overlay->HandleKeyDown(OIS::KC_RETURN, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string(""));

    overlay->HandleKeyDown(OIS::KC_DOWN, 0);
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("C"));
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    overlay->HandleKeyDown(OIS::KC_UP, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("A"));
    overlay->HandleKeyDown(OIS::KC_DOWN, 0);
    BOOST_CHECK_EQUAL(overlay->GetCommandLine(), std::string("B"));

    overlay->SetVisible(false);
    BOOST_CHECK_EQUAL(overlay->IsActive(), false);

    ogre_console.reset();
    fw.GetModuleManager()->UninitializeModules();
    fw.GetModuleManager()->UnloadModules();
}

BOOST_AUTO_TEST_SUITE_END()

<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  _____         _             _
// |_   _|_ _  __| |_ __   ___ | | ___
//   | |/ _` |/ _` | '_ \ / _ \| |/ _ \
//   | | (_| | (_| | |_) | (_) | |  __/
//   |_|\__,_|\__,_| .__/ \___/|_|\___|
//                 |_|
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include <functional>
#include "../common/common.hh"

namespace tadpole {

enum class ObjType : u8_t {
  STRING,
  NATIVE,
  FUNCTION,
  UPVALUE,
  CLOSURE,
};

class GC;

class BaseObject;
class StringObject;
class NativeObject;
class FunctionObject;
class UpvalueObject;
class ClosureObject;

using ObjectVisitor = std::function<void (BaseObject*)>;

class ObjectTraverser : private UnCopyable {
public:
  virtual ~ObjectTraverser() noexcept {}

  virtual void iter_objects(ObjectVisitor&& visitor) {}
  virtual void iter_children(ObjectVisitor&& visitor) {}
};

class BaseObject : public ObjectTraverser {
  ObjType type_;
  bool marked_{};
public:
  BaseObject(ObjType type) noexcept : type_(type) {}
  virtual ~BaseObject() {}

  inline ObjType type() const noexcept { return type_; }
  inline bool is_marked() const noexcept { return marked_; }
  inline void set_marked(bool marked = true) noexcept { marked_ = marked; }

  virtual bool is_truthy() const { return true; }
  virtual str_t stringify() const { return "<object>"; }
  virtual void gc_blacken() {}

  StringObject* as_string();
  const char* as_cstring();
  NativeObject* as_native();
  FunctionObject* as_function();
  UpvalueObject* as_upvalue();
  ClosureObject* as_closure();
};

}
<commit_msg>:recycle: refactor(object): refactoring the declaration of base object<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  _____         _             _
// |_   _|_ _  __| |_ __   ___ | | ___
//   | |/ _` |/ _` | '_ \ / _ \| |/ _ \
//   | | (_| | (_| | |_) | (_) | |  __/
//   |_|\__,_|\__,_| .__/ \___/|_|\___|
//                 |_|
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include <functional>
#include "../common/common.hh"

namespace tadpole {

enum class ObjType : u8_t {
  STRING,
  NATIVE,
  FUNCTION,
  UPVALUE,
  CLOSURE,
};

class BaseObject;
class StringObject;
class NativeObject;
class FunctionObject;
class UpvalueObject;
class ClosureObject;

using ObjectVisitor = std::function<void (BaseObject*)>;

class ObjectTraverser : private UnCopyable {
public:
  virtual ~ObjectTraverser() noexcept {}
  virtual void iter_objects(ObjectVisitor&& visitor) = 0;
};

class ChildrenTraverser : private UnCopyable {
public:
  virtual ~ChildrenTraverser() noexcept {}
  virtual void iter_children(ObjectVisitor&& visitor) = 0;
};

class BaseObject : public ChildrenTraverser {
  ObjType type_;
  bool marked_{};
public:
  BaseObject(ObjType type) noexcept : type_(type) {}
  virtual ~BaseObject() {}

  inline ObjType type() const noexcept { return type_; }
  inline bool is_marked() const noexcept { return marked_; }
  inline void set_marked(bool marked = true) noexcept { marked_ = marked; }

  virtual bool is_truthy() const { return true; }
  virtual str_t stringify() const { return "<object>"; }
  virtual void iter_children(ObjectVisitor&& visitor) override {}

  StringObject* as_string();
  const char* as_cstring();
  NativeObject* as_native();
  FunctionObject* as_function();
  UpvalueObject* as_upvalue();
  ClosureObject* as_closure();
};

}
<|endoftext|>