mirror of https://github.com/KLayout/klayout.git
Added line style selection widget
This commit is contained in:
parent
f8268746e3
commit
67d934194f
|
|
@ -175,31 +175,38 @@ LineStyleInfo::is_bit_set (unsigned int n) const
|
|||
|
||||
#if defined(HAVE_QT)
|
||||
QBitmap
|
||||
LineStyleInfo::get_bitmap (int width, int height) const
|
||||
LineStyleInfo::get_bitmap (int w, int h, int fw) const
|
||||
{
|
||||
if (height < 0) {
|
||||
height = 5;
|
||||
}
|
||||
if (width < 0) {
|
||||
width = 34;
|
||||
}
|
||||
|
||||
unsigned int height = h < 0 ? 5 : (unsigned int) h;
|
||||
unsigned int width = w < 0 ? 34 : (unsigned int) w;
|
||||
unsigned int frame_width = fw <= 0 ? 1 : (unsigned int) fw;
|
||||
unsigned int stride = (width + 7) / 8;
|
||||
|
||||
unsigned char *data = new unsigned char[stride * height];
|
||||
memset (data, 0x00, size_t (stride * height));
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)(height - 2); ++i) {
|
||||
if (is_bit_set (i)) {
|
||||
data [(height - 2 - i) * stride] |= 0x01;
|
||||
data [(height - 2 - i) * stride + (width - 1) / 8] |= (1 << ((width - 1) % 8));
|
||||
unsigned int hv = height - 2 * frame_width;
|
||||
|
||||
for (unsigned int i = 0; i < hv; ++i) {
|
||||
if (is_bit_set (i / frame_width + 1)) {
|
||||
unsigned int y = height - 1 - frame_width - i;
|
||||
for (unsigned int x = 0; x < frame_width; ++x) {
|
||||
data [y * stride + x / 8] |= (1 << (x % 8));
|
||||
}
|
||||
for (unsigned int x = width - frame_width; x < width; ++x) {
|
||||
data [y * stride + x / 8] |= (1 << (x % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 1; i < (unsigned int)(width - 1); ++i) {
|
||||
if (is_bit_set (i)) {
|
||||
data [stride + i / 8] |= (1 << (i % 8));
|
||||
data [(height - 2) * stride + i / 8] |= (1 << (i % 8));
|
||||
for (unsigned int i = 0; i < width; ++i) {
|
||||
if (is_bit_set (i / frame_width)) {
|
||||
for (unsigned int y = 0; y < frame_width; ++y) {
|
||||
data [y * stride + i / 8] |= (1 << (i % 8));
|
||||
}
|
||||
for (unsigned int y = height - frame_width; y < height; ++y) {
|
||||
data [y * stride + i / 8] |= (1 << (i % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,8 +150,9 @@ public:
|
|||
*
|
||||
* @param width The desired width (-1 for default)
|
||||
* @param height The desired height (-1 for default)
|
||||
* @param The intended frame width in pixels
|
||||
*/
|
||||
QBitmap get_bitmap (int width = -1, int height = -1) const;
|
||||
QBitmap get_bitmap (int width = -1, int height = -1, int frame_width = 1) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "tlInternational.h"
|
||||
|
||||
#include "laySelectStippleForm.h"
|
||||
#include "laySelectLineStyleForm.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -246,6 +247,199 @@ DitherPatternSelectionButton::update_menu ()
|
|||
} catch (...) { }
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// LineStyleSelectionButton implementation
|
||||
|
||||
LineStyleSelectionButton::LineStyleSelectionButton (QWidget *parent)
|
||||
: QPushButton (parent), mp_view (0), m_line_style (-1)
|
||||
{
|
||||
setMenu (new QMenu (this));
|
||||
update_pattern ();
|
||||
connect (menu (), SIGNAL (aboutToShow ()), this, SLOT (menu_about_to_show ()));
|
||||
}
|
||||
|
||||
LineStyleSelectionButton::~LineStyleSelectionButton ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::set_view (lay::LayoutViewBase *view)
|
||||
{
|
||||
if (view != mp_view) {
|
||||
mp_view = view;
|
||||
update_menu ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::set_line_style (int ls)
|
||||
{
|
||||
if (ls != m_line_style) {
|
||||
m_line_style = ls;
|
||||
update_pattern ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
LineStyleSelectionButton::line_style () const
|
||||
{
|
||||
return m_line_style;
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::menu_selected ()
|
||||
{
|
||||
QAction *action = dynamic_cast <QAction *> (sender ());
|
||||
if (action) {
|
||||
|
||||
m_line_style = action->data ().toInt ();
|
||||
update_pattern ();
|
||||
emit (line_style_changed (m_line_style));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::browse_selected ()
|
||||
{
|
||||
if (mp_view) {
|
||||
|
||||
SelectLineStyleForm styles_form (0, mp_view->line_styles (), true);
|
||||
styles_form.set_selected (m_line_style);
|
||||
|
||||
if (styles_form.exec ()) {
|
||||
|
||||
m_line_style = styles_form.selected ();
|
||||
update_pattern ();
|
||||
emit (line_style_changed (m_line_style));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Use the default (non-custom) pattern if no view is set.
|
||||
lay::LineStyles default_pattern;
|
||||
|
||||
SelectLineStyleForm styles_form (0, default_pattern, true);
|
||||
styles_form.set_selected (m_line_style);
|
||||
|
||||
if (styles_form.exec ()) {
|
||||
|
||||
m_line_style = styles_form.selected ();
|
||||
update_pattern ();
|
||||
emit (line_style_changed (m_line_style));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::update_pattern ()
|
||||
{
|
||||
QPushButton::setText (QString::fromUtf8 (" "));
|
||||
|
||||
QString text = QString::fromUtf8 ("XXXXXXX");
|
||||
QFontMetrics fm (font (), this);
|
||||
QRect rt (fm.boundingRect (text)); // dummy text to be compliant with the other color button
|
||||
|
||||
QPushButton::setIconSize (QSize (rt.width (), rt.height ()));
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
double dpr = devicePixelRatio ();
|
||||
#else
|
||||
double dpr = 1.0;
|
||||
#endif
|
||||
|
||||
if (m_line_style < 0) {
|
||||
|
||||
QPixmap pixmap (rt.width () * dpr, rt.height () * dpr);
|
||||
#if QT_VERSION >= 0x050000
|
||||
pixmap.setDevicePixelRatio (dpr);
|
||||
#endif
|
||||
pixmap.fill (QColor (0, 0, 0, 0));
|
||||
|
||||
QPainter pxpainter (&pixmap);
|
||||
pxpainter.setFont (font ());
|
||||
QColor text_color = palette ().color (QPalette::Active, QPalette::Text);
|
||||
pxpainter.setPen (QPen (text_color));
|
||||
|
||||
QRectF r (0, 0, rt.width () - pxpainter.pen ().widthF (), rt.height () - pxpainter.pen ().widthF ());
|
||||
pxpainter.drawText (r, Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextSingleLine, QObject::tr ("None"));
|
||||
|
||||
QPushButton::setIcon (QIcon (pixmap));
|
||||
|
||||
} else {
|
||||
|
||||
const lay::LineStyleInfo *dp_info;
|
||||
if (mp_view) {
|
||||
dp_info = & mp_view->line_styles ().style ((unsigned int) m_line_style);
|
||||
} else {
|
||||
static lay::LineStyles default_pattern;
|
||||
dp_info = & default_pattern.style ((unsigned int) m_line_style);
|
||||
}
|
||||
|
||||
QPushButton::setIcon (dp_info->get_bitmap (rt.width () * dpr, rt.height () * dpr, dpr));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::menu_about_to_show ()
|
||||
{
|
||||
update_menu ();
|
||||
}
|
||||
|
||||
void
|
||||
LineStyleSelectionButton::update_menu ()
|
||||
{
|
||||
menu ()->clear ();
|
||||
menu ()->addAction (QObject::tr ("None"), this, SLOT (menu_selected ()))->setData (-1);
|
||||
menu ()->addAction (QObject::tr ("Choose ..."), this, SLOT (browse_selected ()));
|
||||
menu ()->addSeparator ();
|
||||
|
||||
// from_string might throw an exception ...
|
||||
try {
|
||||
|
||||
lay::LineStyles patterns;
|
||||
|
||||
std::string s;
|
||||
if (lay::Dispatcher::instance ()) {
|
||||
lay::Dispatcher::instance ()->config_get (cfg_line_style_palette, s);
|
||||
}
|
||||
lay::LineStylePalette palette = lay::LineStylePalette::default_palette ();
|
||||
if (! s.empty ()) {
|
||||
palette.from_string (s);
|
||||
}
|
||||
|
||||
// fill the list of stipple palette items
|
||||
for (unsigned int i = 0; i < palette.styles (); ++i) {
|
||||
|
||||
unsigned int n = palette.style_by_index (i);
|
||||
if (int (n) < std::distance (patterns.begin (), patterns.end ())) {
|
||||
|
||||
#if QT_VERSION > 0x050000
|
||||
double dpr = devicePixelRatio ();
|
||||
#else
|
||||
double dpr = 1.0;
|
||||
#endif
|
||||
|
||||
lay::LineStyleInfo info = patterns.begin () [n];
|
||||
|
||||
std::string name (info.name ());
|
||||
if (name.empty ()) {
|
||||
name = tl::sprintf ("#%d", n);
|
||||
}
|
||||
|
||||
menu ()->addAction (QIcon (info.get_bitmap (16, 8)), tl::to_qstring (name), this, SLOT (menu_selected ()))->setData (n);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (...) { }
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// CellViewSelectionComboBox implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,68 @@ private:
|
|||
void update_menu ();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A selection button for dither pattern
|
||||
*/
|
||||
class LAYUI_PUBLIC LineStyleSelectionButton
|
||||
: public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
LineStyleSelectionButton (QWidget *parent);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~LineStyleSelectionButton ();
|
||||
|
||||
/**
|
||||
* @brief Associate with a view
|
||||
*
|
||||
* This method is required to select the proper dither pattern
|
||||
*/
|
||||
void set_view (lay::LayoutViewBase *view);
|
||||
|
||||
/**
|
||||
* @brief Set the line style index
|
||||
*/
|
||||
void set_line_style (int ls);
|
||||
|
||||
/**
|
||||
* @brief Get the line style index
|
||||
*/
|
||||
int line_style () const;
|
||||
|
||||
/**
|
||||
* @brief Override setText
|
||||
*/
|
||||
void setText (const QString &) { }
|
||||
|
||||
/**
|
||||
* @brief Override setPixmap
|
||||
*/
|
||||
void setPixmap (const QPixmap &) { }
|
||||
|
||||
signals:
|
||||
void line_style_changed (int);
|
||||
|
||||
private slots:
|
||||
void browse_selected ();
|
||||
void menu_selected ();
|
||||
void menu_about_to_show ();
|
||||
|
||||
private:
|
||||
lay::LayoutViewBase *mp_view;
|
||||
int m_line_style;
|
||||
|
||||
void update_pattern ();
|
||||
void update_menu ();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A library selection combo box
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue