improve inputbox
This commit is contained in:
parent
50f4bd79ce
commit
fc76758197
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Message Box Class
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -94,22 +94,133 @@ namespace nana
|
||||
|
||||
class inputbox
|
||||
{
|
||||
public:
|
||||
inputbox(window, ::nana::string description, ::nana::string title = ::nana::string(), ::nana::string label = ::nana::string());
|
||||
struct abstract_content
|
||||
{
|
||||
virtual ~abstract_content() = default;
|
||||
|
||||
void set_modal();
|
||||
bool valid() const;
|
||||
int get_int(int value, int begin, int last, int step);
|
||||
double get_double(double value, double begin, double last, double step);
|
||||
::nana::string get_string();
|
||||
virtual const ::nana::string& label() const = 0;
|
||||
virtual window create(window, unsigned label_px) = 0;
|
||||
virtual unsigned fixed_pixels() const = 0;
|
||||
};
|
||||
public:
|
||||
class integer
|
||||
: public abstract_content
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
integer(::nana::string label, int init_value, int begin, int last, int step);
|
||||
~integer();
|
||||
|
||||
int value() const;
|
||||
private:
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& label() const override;
|
||||
window create(window, unsigned label_px) override;
|
||||
unsigned fixed_pixels() const override;
|
||||
private:
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
class real
|
||||
: public abstract_content
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
real(::nana::string label, double init_value, double begin, double last, double step);
|
||||
~real();
|
||||
|
||||
double value() const;
|
||||
private:
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& label() const override;
|
||||
window create(window, unsigned label_px) override;
|
||||
unsigned fixed_pixels() const override;
|
||||
private:
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
class text
|
||||
: public abstract_content
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
text(::nana::string label);
|
||||
text(::nana::string label, std::vector<::nana::string>);
|
||||
|
||||
~text();
|
||||
|
||||
::nana::string value() const;
|
||||
private:
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& label() const override;
|
||||
window create(window, unsigned label_px) override;
|
||||
unsigned fixed_pixels() const override;
|
||||
private:
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
class date
|
||||
: public abstract_content
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
date(::nana::string label);
|
||||
|
||||
~date();
|
||||
|
||||
::nana::string value() const;
|
||||
int year() const;
|
||||
int month() const; //[1, 12]
|
||||
int day() const; //[1, 31]
|
||||
unsigned fixed_pixels() const override;
|
||||
private:
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& label() const override;
|
||||
window create(window, unsigned label_px) override;
|
||||
private:
|
||||
std::unique_ptr<implement> impl_;
|
||||
};
|
||||
|
||||
inputbox(window, ::nana::string description, ::nana::string title = ::nana::string());
|
||||
|
||||
template<typename ...Args>
|
||||
bool show(Args&& ... args)
|
||||
{
|
||||
std::vector<abstract_content*> contents;
|
||||
_m_fetch_args(contents, std::forward<Args>(args)...);
|
||||
|
||||
if (contents.empty())
|
||||
return false;
|
||||
|
||||
return _m_open(contents, false);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
bool show_modal(Args&& ... args)
|
||||
{
|
||||
std::vector<abstract_content*> contents;
|
||||
_m_fetch_args(contents, std::forward<Args>(args)...);
|
||||
|
||||
if (contents.empty())
|
||||
return false;
|
||||
|
||||
return _m_open(contents, true);
|
||||
}
|
||||
private:
|
||||
void _m_fetch_args(std::vector<abstract_content*>&);
|
||||
|
||||
template<typename ...Args>
|
||||
void _m_fetch_args(std::vector<abstract_content*>& contents, abstract_content& content, Args&&... args)
|
||||
{
|
||||
contents.push_back(&content);
|
||||
_m_fetch_args(contents, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
bool _m_open(std::vector<abstract_content*>&, bool modal);
|
||||
private:
|
||||
window owner_;
|
||||
bool valid_input_;
|
||||
bool modal_mode_;
|
||||
|
||||
::nana::string description_;
|
||||
::nana::string title_;
|
||||
::nana::string label_;
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A date chooser Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -43,7 +43,6 @@ namespace nana
|
||||
bool chose() const;
|
||||
nana::date read() const;
|
||||
void week_name(unsigned index, const nana::string&);
|
||||
void month_name(unsigned index, const nana::string&);
|
||||
private:
|
||||
where _m_pos_where(graph_reference, const ::nana::point& pos);
|
||||
void _m_draw(graph_reference);
|
||||
@ -64,7 +63,6 @@ namespace nana
|
||||
void mouse_up(graph_reference, const arg_mouse&) override;
|
||||
private:
|
||||
nana::string weekstr_[7];
|
||||
nana::string monthstr_[12];
|
||||
|
||||
widget * widget_;
|
||||
|
||||
@ -115,7 +113,6 @@ namespace nana
|
||||
bool chose() const;
|
||||
nana::date read() const;
|
||||
void weekstr(unsigned index, const nana::string&);///<Set the week strings which will be displayed for day, index is in range of [0, 6]
|
||||
void monthstr(unsigned index, const nana::string&);///<Set the month strings which will be displayed for month. index is in range of [0, 11]
|
||||
};
|
||||
}//end namespace nana
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Message Box Class
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -10,13 +10,15 @@
|
||||
* @file: nana/gui/msgbox.hpp
|
||||
*/
|
||||
|
||||
//#include <nana/gui/msgbox.hpp> //deprecated
|
||||
//#include <nana/gui/programming_interface.hpp> //deprecated
|
||||
#include <nana/gui.hpp>
|
||||
#include <nana/gui/widgets/label.hpp>
|
||||
#include <nana/gui/widgets/button.hpp>
|
||||
#include <nana/gui/widgets/spinbox.hpp>
|
||||
#include <nana/gui/widgets/combox.hpp>
|
||||
#include <nana/gui/widgets/textbox.hpp>
|
||||
#include <nana/gui/widgets/panel.hpp>
|
||||
#include <nana/gui/place.hpp>
|
||||
#include <nana/datetime.hpp>
|
||||
#include <nana/internationalization.hpp>
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
@ -471,53 +473,62 @@ namespace nana
|
||||
: public ::nana::form
|
||||
{
|
||||
public:
|
||||
inputbox_window(window owner, const ::nana::string & desc, const ::nana::string& title, const ::nana::string& label, unsigned input_widget_size)
|
||||
inputbox_window(window owner, const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels)
|
||||
: form(owner, API::make_center(owner, 500, 300), appear::decorate<>())
|
||||
{
|
||||
desc_.create(*this);
|
||||
desc_.format(true).caption(desc);
|
||||
auto desc_extent = desc_.measure(470);
|
||||
desc_extent.height += 8;
|
||||
|
||||
label_.create(*this);
|
||||
label_.format(true).caption(label);
|
||||
label_.text_align(::nana::align::left, ::nana::align_v::center);
|
||||
auto label_extent = label_.measure(230);
|
||||
label_extent.height += 8;
|
||||
|
||||
btn_ok_.create(*this);
|
||||
btn_ok_.i18n(i18n_eval("Nana.OK"));
|
||||
btn_ok_.i18n(i18n_eval("OK"));
|
||||
btn_ok_.events().click([this]{
|
||||
close();
|
||||
valid_input_ = true;
|
||||
});
|
||||
|
||||
btn_cancel_.create(*this);
|
||||
btn_cancel_.i18n(i18n_eval("Nana.Cancel"));
|
||||
btn_cancel_.i18n(i18n_eval("Cancel"));
|
||||
btn_cancel_.events().click([this]{
|
||||
close();
|
||||
});
|
||||
|
||||
unsigned height = 20 + desc_extent.height + 10 + 38;
|
||||
|
||||
place_.bind(*this);
|
||||
std::stringstream ss;
|
||||
ss << "margin=10 vert <desc weight=" << desc_extent.height << "><weight=" << label_extent.height << "<label weight=" << label_extent.width << "><margin=[0,0,0,10] input";
|
||||
if (input_widget_size)
|
||||
ss << " weight=" << input_widget_size;
|
||||
ss << ">><margin=[10,0,0,0] buttons arrange=100 gap=10 weight=23>";
|
||||
ss << "margin=10 vert <desc weight=" << desc_extent.height << "><vert margin=[10]";
|
||||
|
||||
for (std::size_t i = 0; i < contents; ++i)
|
||||
ss << "<weight=27 margin=[3] input_"<<i<<">";
|
||||
height += 28 * contents;
|
||||
|
||||
ss << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>";
|
||||
|
||||
place_.div(ss.str().data());
|
||||
place_["desc"] << desc_;
|
||||
place_["label"] << label_;
|
||||
place_["buttons"] << btn_ok_ << btn_cancel_;
|
||||
|
||||
unsigned height = 20 + desc_extent.height + label_extent.height + 10 + 23;
|
||||
size({ 500, height });
|
||||
if (desc_extent.width < 170)
|
||||
desc_extent.width = 170;
|
||||
|
||||
//Make sure the complete display of input extent
|
||||
if (desc_extent.width < fixed_pixels)
|
||||
desc_extent.width = fixed_pixels;
|
||||
|
||||
size({ desc_extent.width + 20, height });
|
||||
caption(title);
|
||||
}
|
||||
|
||||
void set_input(window handle)
|
||||
void set_input(const std::vector<window>& inputs)
|
||||
{
|
||||
place_["input"] << handle;
|
||||
std::size_t index = 0;
|
||||
for (auto wd : inputs)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "input_" << index++;
|
||||
place_[ss.str().data()] << wd;
|
||||
}
|
||||
place_.collocate();
|
||||
show();
|
||||
}
|
||||
@ -528,88 +539,478 @@ namespace nana
|
||||
}
|
||||
private:
|
||||
::nana::label desc_;
|
||||
::nana::label label_;
|
||||
::nana::button btn_ok_;
|
||||
::nana::button btn_cancel_;
|
||||
bool valid_input_{ false };
|
||||
::nana::place place_;
|
||||
};
|
||||
|
||||
inputbox::inputbox(window owner, ::nana::string desc, ::nana::string title, ::nana::string label)
|
||||
: owner_{ owner }, valid_input_{ false }, modal_mode_{false},
|
||||
description_(std::move(desc)),
|
||||
title_(std::move(title)),
|
||||
label_(std::move(label))
|
||||
{}
|
||||
|
||||
void inputbox::set_modal()
|
||||
//class integer
|
||||
struct inputbox::integer::implement
|
||||
{
|
||||
modal_mode_ = true;
|
||||
int value;
|
||||
int begin;
|
||||
int last;
|
||||
int step;
|
||||
|
||||
::nana::string label_text;
|
||||
::nana::panel<false> dock;
|
||||
::nana::label label;
|
||||
::nana::spinbox spinbox;
|
||||
};
|
||||
|
||||
inputbox::integer::integer(::nana::string label, int init_value, int begin, int last, int step)
|
||||
: impl_(new implement)
|
||||
{
|
||||
auto impl = impl_.get();
|
||||
impl->value = init_value;
|
||||
impl->begin = begin;
|
||||
impl->last = last;
|
||||
impl->step = step;
|
||||
impl->label_text = std::move(label);
|
||||
}
|
||||
|
||||
bool inputbox::valid() const
|
||||
//Instance for impl_ because implmenet is incomplete type at the point of declaration
|
||||
inputbox::integer::~integer(){}
|
||||
|
||||
int inputbox::integer::value() const
|
||||
{
|
||||
return valid_input_;
|
||||
return impl_->value;
|
||||
}
|
||||
|
||||
int inputbox::get_int(int value, int begin, int last, int step)
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& inputbox::integer::label() const
|
||||
{
|
||||
int longest = (std::abs((begin < 0 ? begin * 10 : begin)) < std::abs(last < 0 ? last * 10 : last) ? last : begin);
|
||||
return impl_->label_text;
|
||||
}
|
||||
|
||||
window inputbox::integer::create(window parent, unsigned label_px)
|
||||
{
|
||||
auto impl = impl_.get();
|
||||
impl->dock.create(parent);
|
||||
|
||||
impl->label.create(impl->dock, rectangle{ 0, 0, label_px, 0 });
|
||||
impl->label.text_align(::nana::align::right, ::nana::align_v::center);
|
||||
impl->label.caption(impl->label_text);
|
||||
impl->label.format(true);
|
||||
|
||||
//get the longest value
|
||||
int longest = (std::abs((impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(impl->last < 0 ? impl->last * 10 : impl->last) ? impl->last : impl->begin);
|
||||
std::wstringstream ss;
|
||||
ss << longest;
|
||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||
auto input_widget_size = graph.text_extent_size(ss.str()).width + 34;
|
||||
auto t1 = graph.typeface();
|
||||
auto value_px = graph.text_extent_size(ss.str()).width + 34;
|
||||
|
||||
inputbox_window inp_window(owner_, description_, title_, label_, input_widget_size);
|
||||
::nana::spinbox spinbox(inp_window);
|
||||
spinbox.range(begin, last, step);
|
||||
spinbox.set_accept_integer();
|
||||
inp_window.set_input(spinbox);
|
||||
auto t2 = spinbox.typeface();
|
||||
if (modal_mode_)
|
||||
inp_window.modality();
|
||||
else
|
||||
API::wait_for(inp_window);
|
||||
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
||||
impl->spinbox.set_accept_integer();
|
||||
|
||||
valid_input_ = inp_window.valid_input();
|
||||
return spinbox.to_int();
|
||||
//Workaround for no implementation of std::to_wstring by MinGW.
|
||||
ss.str(L"");
|
||||
ss.clear();
|
||||
ss << impl->value;
|
||||
impl->spinbox.value(ss.str());
|
||||
|
||||
impl->dock.events().resized([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||
{
|
||||
impl->label.size({ label_px, arg.height });
|
||||
impl->spinbox.size({ value_px, arg.height });
|
||||
});
|
||||
|
||||
impl->spinbox.events().destroy([impl]
|
||||
{
|
||||
impl->value = impl->spinbox.to_int();
|
||||
});
|
||||
|
||||
return impl->dock;
|
||||
}
|
||||
|
||||
double inputbox::get_double(double value, double begin, double last, double step)
|
||||
unsigned inputbox::integer::fixed_pixels() const
|
||||
{
|
||||
std::wstring longest;
|
||||
for (auto i = begin; i < last; i += step)
|
||||
return 0;
|
||||
}
|
||||
//end class integer
|
||||
|
||||
|
||||
//class real
|
||||
struct inputbox::real::implement
|
||||
{
|
||||
double value;
|
||||
double begin;
|
||||
double last;
|
||||
double step;
|
||||
|
||||
::nana::string label_text;
|
||||
::nana::panel<false> dock;
|
||||
::nana::label label;
|
||||
::nana::spinbox spinbox;
|
||||
};
|
||||
|
||||
inputbox::real::real(::nana::string label, double init_value, double begin, double last, double step)
|
||||
: impl_(new implement)
|
||||
{
|
||||
auto impl = impl_.get();
|
||||
impl->value = init_value;
|
||||
impl->begin = begin;
|
||||
impl->last = last;
|
||||
impl->step = step;
|
||||
impl->label_text = std::move(label);
|
||||
}
|
||||
|
||||
//Instance for impl_ because implmenet is incomplete type at the point of declaration
|
||||
inputbox::real::~real(){}
|
||||
|
||||
double inputbox::real::value() const
|
||||
{
|
||||
return impl_->value;
|
||||
}
|
||||
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& inputbox::real::label() const
|
||||
{
|
||||
return impl_->label_text;
|
||||
}
|
||||
|
||||
window inputbox::real::create(window parent, unsigned label_px)
|
||||
{
|
||||
auto impl = impl_.get();
|
||||
impl->dock.create(parent);
|
||||
|
||||
impl->label.create(impl->dock, rectangle{ 0, 0, label_px, 0 });
|
||||
impl->label.text_align(::nana::align::right, ::nana::align_v::center);
|
||||
impl->label.caption(impl->label_text);
|
||||
impl->label.format(true);
|
||||
|
||||
//get the longest value
|
||||
auto longest = (std::abs((impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(impl->last < 0 ? impl->last * 10 : impl->last) ? impl->last : impl->begin);
|
||||
std::wstringstream ss;
|
||||
ss << longest;
|
||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||
auto value_px = graph.text_extent_size(ss.str()).width + 34;
|
||||
|
||||
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
||||
impl->spinbox.set_accept_real();
|
||||
|
||||
//Workaround for no implementation of std::to_wstring by MinGW.
|
||||
ss.str(L"");
|
||||
ss.clear();
|
||||
ss << impl->value;
|
||||
impl->spinbox.value(ss.str());
|
||||
|
||||
impl->dock.events().resized([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << i;
|
||||
auto str = ss.str();
|
||||
if (str.size() > longest.size())
|
||||
longest = str;
|
||||
impl->label.size({ label_px, arg.height });
|
||||
impl->spinbox.size({ value_px, arg.height });
|
||||
});
|
||||
|
||||
impl->spinbox.events().destroy([impl]
|
||||
{
|
||||
impl->value = impl->spinbox.to_int();
|
||||
});
|
||||
|
||||
return impl->dock;
|
||||
}
|
||||
|
||||
unsigned inputbox::real::fixed_pixels() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//end class real
|
||||
|
||||
|
||||
//class text
|
||||
struct inputbox::text::implement
|
||||
{
|
||||
::nana::string value;
|
||||
std::vector< ::nana::string> options;
|
||||
|
||||
::nana::string label_text;
|
||||
::nana::panel<false> dock;
|
||||
::nana::label label;
|
||||
::nana::combox combox;
|
||||
::nana::textbox textbox;
|
||||
};
|
||||
|
||||
inputbox::text::text(::nana::string label)
|
||||
: impl_(new implement)
|
||||
{
|
||||
impl_->label_text = std::move(label);
|
||||
}
|
||||
|
||||
inputbox::text::text(::nana::string label, std::vector<::nana::string> options)
|
||||
: impl_(new implement)
|
||||
{
|
||||
impl_->options.swap(options);
|
||||
impl_->label_text = std::move(label);
|
||||
}
|
||||
|
||||
//Instance for impl_ because implmenet is incomplete type at the point of declaration
|
||||
inputbox::text::~text(){}
|
||||
|
||||
::nana::string inputbox::text::value() const
|
||||
{
|
||||
return impl_->value;
|
||||
}
|
||||
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& inputbox::text::label() const
|
||||
{
|
||||
return impl_->label_text;
|
||||
}
|
||||
|
||||
window inputbox::text::create(window parent, unsigned label_px)
|
||||
{
|
||||
auto impl = impl_.get();
|
||||
impl->dock.create(parent);
|
||||
|
||||
impl->label.create(impl->dock, rectangle{ 0, 0, label_px, 0 });
|
||||
impl->label.text_align(::nana::align::right, ::nana::align_v::center);
|
||||
impl->label.caption(impl->label_text);
|
||||
impl->label.format(true);
|
||||
|
||||
unsigned value_px = 0;
|
||||
if (impl->options.empty())
|
||||
{
|
||||
impl->textbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, 0, 0 });
|
||||
}
|
||||
else
|
||||
{
|
||||
//get the longest value
|
||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||
for (auto & s : impl->options)
|
||||
{
|
||||
auto px = graph.text_extent_size(s).width;
|
||||
if (px > value_px)
|
||||
value_px = px;
|
||||
}
|
||||
value_px += 34;
|
||||
|
||||
impl->combox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||
|
||||
for (auto & s : impl->options)
|
||||
impl->combox.push_back(s);
|
||||
}
|
||||
|
||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||
auto input_widget_size = graph.text_extent_size(longest).width + 34;
|
||||
impl->dock.events().resized([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||
{
|
||||
impl->label.size({ label_px, arg.height });
|
||||
if (value_px)
|
||||
impl->combox.size({ value_px, arg.height });
|
||||
else
|
||||
impl->textbox.size({arg.width - label_px - 10, arg.height});
|
||||
});
|
||||
|
||||
inputbox_window inp_window(owner_, description_, title_, label_, input_widget_size);
|
||||
::nana::spinbox spinbox(inp_window);
|
||||
spinbox.range(begin, last, step);
|
||||
spinbox.set_accept_real();
|
||||
inp_window.set_input(spinbox);
|
||||
|
||||
if (modal_mode_)
|
||||
inp_window.modality();
|
||||
else
|
||||
API::wait_for(inp_window);
|
||||
|
||||
valid_input_ = inp_window.valid_input();
|
||||
return spinbox.to_double();
|
||||
auto & wdg = (value_px ? static_cast<widget&>(impl->combox) : static_cast<widget&>(impl->textbox));
|
||||
wdg.events().destroy([&wdg, impl]
|
||||
{
|
||||
impl->value = wdg.caption();
|
||||
});
|
||||
return impl->dock;
|
||||
}
|
||||
|
||||
::nana::string inputbox::get_string()
|
||||
unsigned inputbox::text::fixed_pixels() const
|
||||
{
|
||||
return{};
|
||||
return 0;
|
||||
}
|
||||
//end class text
|
||||
|
||||
|
||||
//class date
|
||||
struct inputbox::date::implement
|
||||
{
|
||||
int year;
|
||||
int month;
|
||||
int day;
|
||||
|
||||
::nana::string label_text;
|
||||
::nana::panel<false> dock;
|
||||
::nana::label label;
|
||||
::nana::combox wdg_month;
|
||||
::nana::spinbox wdg_day;
|
||||
::nana::spinbox wdg_year;
|
||||
};
|
||||
|
||||
inputbox::date::date(::nana::string label)
|
||||
: impl_(new implement)
|
||||
{
|
||||
impl_->label_text = std::move(label);
|
||||
}
|
||||
|
||||
//Instance for impl_ because implmenet is incomplete type at the point of declaration
|
||||
inputbox::date::~date(){}
|
||||
|
||||
::nana::string inputbox::date::value() const
|
||||
{
|
||||
std::wstringstream ss;
|
||||
ss << impl_->month << L'-' << impl_->day << L", " << impl_->year;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int inputbox::date::year() const
|
||||
{
|
||||
return impl_->year;
|
||||
}
|
||||
|
||||
int inputbox::date::month() const
|
||||
{
|
||||
return impl_->month;
|
||||
}
|
||||
int inputbox::date::day() const
|
||||
{
|
||||
return impl_->day;
|
||||
}
|
||||
|
||||
//Implementation of abstract_content
|
||||
const ::nana::string& inputbox::date::label() const
|
||||
{
|
||||
return impl_->label_text;
|
||||
}
|
||||
|
||||
window inputbox::date::create(window parent, unsigned label_px)
|
||||
{
|
||||
auto impl = impl_.get();
|
||||
impl->dock.create(parent);
|
||||
|
||||
impl->label.create(impl->dock, rectangle{ 0, 0, label_px, 0 });
|
||||
impl->label.text_align(::nana::align::right, ::nana::align_v::center);
|
||||
impl->label.caption(impl->label_text);
|
||||
impl->label.format(true);
|
||||
|
||||
int left = static_cast<int>(label_px + 10);
|
||||
impl->wdg_month.create(impl->dock, rectangle{left, 0, 94, 0});
|
||||
|
||||
::nana::internationalization i18n;
|
||||
const char * monthstr[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
|
||||
for (auto i = std::begin(monthstr), end = std::end(monthstr); i != end; ++i)
|
||||
impl->wdg_month.push_back(i18n(*i));
|
||||
|
||||
left += 104;
|
||||
impl->wdg_day.create(impl->dock, rectangle{ left, 0, 38, 0 });
|
||||
impl->wdg_day.range(1, 31, 1);
|
||||
impl->wdg_day.set_accept_integer();
|
||||
|
||||
left += 48;
|
||||
impl->wdg_year.create(impl->dock, rectangle{left, 0, 50, 0});
|
||||
impl->wdg_year.range(1601, 9999, 1);
|
||||
impl->wdg_year.set_accept_integer();
|
||||
|
||||
auto date = ::nana::date().read();
|
||||
impl->wdg_month.option(date.month - 1);
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << date.day;
|
||||
impl->wdg_day.value(ss.str());
|
||||
ss.str(L"");
|
||||
ss.clear();
|
||||
ss << date.year;
|
||||
impl->wdg_year.value(ss.str());
|
||||
|
||||
impl->dock.events().resized([impl, label_px](const ::nana::arg_resized& arg)
|
||||
{
|
||||
impl->label.size({ label_px, arg.height });
|
||||
auto sz = impl->wdg_month.size();
|
||||
sz.height = arg.height;
|
||||
impl->wdg_month.size(sz);
|
||||
|
||||
sz = impl->wdg_day.size();
|
||||
sz.height = arg.height;
|
||||
impl->wdg_day.size(sz);
|
||||
|
||||
sz = impl->wdg_year.size();
|
||||
sz.height = arg.height;
|
||||
impl->wdg_year.size(sz);
|
||||
});
|
||||
|
||||
impl->wdg_day.events().destroy([impl]
|
||||
{
|
||||
impl->day = impl->wdg_day.to_int();
|
||||
impl->month = impl->wdg_month.option() + 1;
|
||||
});
|
||||
|
||||
impl->wdg_year.events().destroy([impl]
|
||||
{
|
||||
impl->year = impl->wdg_year.to_int();
|
||||
});
|
||||
|
||||
auto make_days = [impl]
|
||||
{
|
||||
int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
auto month = impl->wdg_month.option() + 1;
|
||||
|
||||
if (2 == month)
|
||||
{
|
||||
auto year = impl->wdg_year.to_int();
|
||||
if (((0 == year % 4) && (year % 100)) || (0 == (year % 400)))
|
||||
days[1] = 29;
|
||||
}
|
||||
|
||||
auto day = impl->wdg_day.to_int();
|
||||
impl->wdg_day.range(1, days[month - 1], 1); //It resets the current value of wdg_day
|
||||
|
||||
if (day > days[month - 1])
|
||||
day = days[month - 1];
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << day;
|
||||
impl->wdg_day.value(ss.str());
|
||||
};
|
||||
|
||||
impl->wdg_year.events().text_changed(make_days);
|
||||
impl->wdg_month.events().selected(make_days);
|
||||
|
||||
return impl->dock;
|
||||
}
|
||||
|
||||
unsigned inputbox::date::fixed_pixels() const
|
||||
{
|
||||
return 202;
|
||||
}
|
||||
//end class date
|
||||
|
||||
|
||||
inputbox::inputbox(window owner, ::nana::string desc, ::nana::string title)
|
||||
: owner_{ owner },
|
||||
description_(std::move(desc)),
|
||||
title_(std::move(title))
|
||||
{}
|
||||
|
||||
void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
|
||||
{}
|
||||
|
||||
|
||||
bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
|
||||
{
|
||||
unsigned label_px = 0, fixed_px = 0;
|
||||
paint::graphics graph({ 5, 5 });
|
||||
for (auto p : contents)
|
||||
{
|
||||
auto px = graph.text_extent_size(p->label()).width;
|
||||
if (px > label_px)
|
||||
label_px = px;
|
||||
|
||||
px = p->fixed_pixels();
|
||||
if (px > fixed_px)
|
||||
fixed_px = px;
|
||||
}
|
||||
|
||||
if (label_px > 120)
|
||||
label_px = 120;
|
||||
|
||||
inputbox_window input_wd(owner_, description_, title_, contents.size(), label_px + 10 + fixed_px);
|
||||
|
||||
std::vector<window> inputs;
|
||||
for (auto p : contents)
|
||||
inputs.push_back(p->create(input_wd, label_px));
|
||||
|
||||
input_wd.set_input(inputs);
|
||||
|
||||
if (modal)
|
||||
input_wd.modality();
|
||||
else
|
||||
API::wait_for(input_wd);
|
||||
|
||||
return input_wd.valid_input();
|
||||
}
|
||||
//end class inputbox
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A date chooser Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -28,10 +28,7 @@ namespace nana
|
||||
: widget_(nullptr), chose_(false), page_(page::date), pos_(where::none)
|
||||
{
|
||||
const nana::string ws[] = {STR("S"), STR("M"), STR("T"), STR("W"), STR("T"), STR("F"), STR("S")};
|
||||
const nana::string ms[] = {STR("January"), STR("February"), STR("March"), STR("April"), STR("May"), STR("June"), STR("July"), STR("August"), STR("September"), STR("October"), STR("November"), STR("December")};
|
||||
|
||||
for(int i = 0; i < 7; ++i) weekstr_[i] = ws[i];
|
||||
for(int i = 0; i < 12; ++i) monthstr_[i] = ms[i];
|
||||
|
||||
nana::date d;
|
||||
chdate_.year = chmonth_.year = d.read().year;
|
||||
@ -60,12 +57,6 @@ namespace nana
|
||||
this->weekstr_[index] = str;
|
||||
}
|
||||
|
||||
void trigger::month_name(unsigned index, const nana::string& str)
|
||||
{
|
||||
if(0 <= index && index < 12)
|
||||
this->monthstr_[index] = str;
|
||||
}
|
||||
|
||||
trigger::where trigger::_m_pos_where(graph_reference graph, const ::nana::point& pos)
|
||||
{
|
||||
int xend = static_cast<int>(graph.width()) - 1;
|
||||
@ -132,6 +123,8 @@ namespace nana
|
||||
arrow.direction(::nana::direction::east);
|
||||
arrow.draw(graph, arrow_bgcolor, (pos_ == where::right_button ? color_.highlight : color_.normal), arrow_r, element_state::normal);
|
||||
|
||||
const char * monthstr[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
|
||||
|
||||
if(graph.width() > 32 + border_size * 2)
|
||||
{
|
||||
std::stringstream ss;
|
||||
@ -139,7 +132,7 @@ namespace nana
|
||||
nana::string str;
|
||||
if(page_ == page::date)
|
||||
{
|
||||
str += monthstr_[chmonth_.month - 1];
|
||||
str += ::nana::internationalization()(monthstr[chmonth_.month - 1]);
|
||||
str += STR(" ");
|
||||
}
|
||||
str += nana::charset(ss.str());
|
||||
@ -313,11 +306,13 @@ namespace nana
|
||||
drawing_basis dbasis;
|
||||
_m_make_drawing_basis(dbasis, graph, refpos);
|
||||
|
||||
const char * monthstr[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
|
||||
::nana::internationalization i18n;
|
||||
for(int y = 0; y < 3; ++y)
|
||||
for(int x = 0; x < 4; ++x)
|
||||
{
|
||||
int index = x + y * 4;
|
||||
_m_draw_pos(dbasis, graph, x, y, monthstr_[index], true, (chmonth_.year == chdate_.year) && (index + 1 == chdate_.month));
|
||||
_m_draw_pos(dbasis, graph, x, y, i18n(monthstr[index]), true, (chmonth_.year == chdate_.year) && (index + 1 == chdate_.month));
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,11 +658,5 @@ namespace nana
|
||||
get_drawer_trigger().week_name(index, str);
|
||||
API::refresh_window(*this);
|
||||
}
|
||||
|
||||
void date_chooser::monthstr(unsigned index, const nana::string& str)
|
||||
{
|
||||
get_drawer_trigger().month_name(index, str);
|
||||
API::refresh_window(*this);
|
||||
}
|
||||
//end class date_chooser
|
||||
}//end namespace nana
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user