diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 814a98b7..cb795e5f 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -436,6 +436,8 @@ namespace API * widget by the content extent. */ optional> content_extent(window wd, unsigned limited_px, bool limit_width); + + unsigned screen_dpi(bool x_requested); }//end namespace API }//end namespace nana diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index adbd4e14..aecf1ade 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -94,6 +94,12 @@ namespace nana */ virtual void fit_content(unsigned maximum = 0) noexcept = 0; + /// Sets an exclusive font for the column + virtual void typeface(const paint::font& column_font) = 0; + + /// Returns a font + virtual paint::font typeface() const noexcept = 0; + /// Determines the visibility state of the column /** * @return true if the column is visible, false otherwise @@ -1198,17 +1204,25 @@ namespace nana color_proxy selection_box{ static_cast(0x3399FF) }; ///< Color of selection box border. + + std::shared_ptr column_font; ///< Renderer draws column texts with the font if it is not a nullptr. + /// The max column width which is generated by fit_content is allowed. It is ignored when it is 0, or a max value is passed to fit_content. unsigned max_fit_content{ 0 }; - unsigned min_column_width{ 20 }; ///< def=20 . non counting suspension_width + unsigned min_column_width{ 20 }; ///< def=20 . non counting suspension_width - unsigned suspension_width { 8 }; ///< def= . the trigger will set this to the width if ("...") - unsigned text_margin { 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 - unsigned header_height { 25 }; ///< def=25 . header height header_size - unsigned item_height_ex { 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex + unsigned suspension_width{ 8 }; ///< def= . the trigger will set this to the width if ("...") + unsigned text_margin{ 5 }; ///< def= 5. Additional or extended with added (before) to the text width to determine the cell width. cell_w = text_w + ext_w +1 + + //deprecated + //unsigned header_height { 25 }; ///< def=25 . header height header_size + + unsigned item_height_ex{ 6 }; ///< Set !=0 !!!! def=6. item_height = text_height + item_height_ex unsigned header_splitter_area_before{ 2 }; ///< def=2. But 4 is better... IMO - unsigned header_splitter_area_after { 3 }; ///< def=3. But 4 is better... + unsigned header_splitter_area_after{ 3 }; ///< def=3. But 4 is better... + unsigned header_padding_top{ 3 }; + unsigned header_padding_bottom{ 3 }; ::nana::parameters::mouse_wheel mouse_wheel{}; ///< The number of lines/characters to scroll when vertical/horizontal mouse wheel is moved. }; diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index 9ce35704..ad0ef379 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -38,14 +38,21 @@ namespace nana font(const font&); font(const ::std::string& name, double size_pt, const font_style& fs = {}); - font(double size_pt, const path_type& truetype, const font_style& ft = {}); + font(double size_pt, const path_type& truetype, const font_style& fs = {}); ~font(); bool empty() const; void set_default() const; ::std::string name() const; - double size() const; + + /// Returns font size, in point. + /** + * @param fixed Indicates whether to return a fixed font size. If this parameter is false, the method may return zero for default system font size. If the parameter is true, the method returns a fixed size of default font size if the font size that assigned by constructor is zero. + * @return The font size, in point. + */ + double size(bool fixed = false) const; + bool bold() const; unsigned weight() const; bool italic() const; diff --git a/include/nana/stdc++.hpp b/include/nana/stdc++.hpp index fc2d6568..8730d806 100644 --- a/include/nana/stdc++.hpp +++ b/include/nana/stdc++.hpp @@ -1,7 +1,7 @@ /** * Standard Library for C++11/14/17 * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2017 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2018 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at diff --git a/source/detail/platform_abstraction.cpp b/source/detail/platform_abstraction.cpp index 6490045c..2d05a35f 100644 --- a/source/detail/platform_abstraction.cpp +++ b/source/detail/platform_abstraction.cpp @@ -255,6 +255,35 @@ namespace nana data::storage = nullptr; } + double platform_abstraction::font_default_pt() + { +#ifdef NANA_WINDOWS + //Create default font object. + NONCLIENTMETRICS metrics = {}; + metrics.cbSize = sizeof metrics; +#if(WINVER >= 0x0600) +#if defined(NANA_MINGW) + OSVERSIONINFO osvi = {}; + osvi.dwOSVersionInfoSize = sizeof(osvi); + ::GetVersionEx(&osvi); + if (osvi.dwMajorVersion < 6) + metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth); +#else + if (!IsWindowsVistaOrGreater()) + metrics.cbSize -= sizeof(metrics.iPaddedBorderWidth); +#endif +#endif + ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0); + + auto desktop = ::GetDC(nullptr); + auto pt = std::abs(metrics.lfMessageFont.lfHeight) * 72.0 / ::GetDeviceCaps(desktop, LOGPIXELSY); + ::ReleaseDC(nullptr, desktop); + return pt; +#else + return 10; +#endif + } + ::std::shared_ptr platform_abstraction::default_font(const ::std::shared_ptr& new_font) { auto & r = platform_storage(); @@ -337,7 +366,7 @@ namespace nana if(font_family.empty()) font_family = '*'; - std::string pat_str = font_family + '-' + std::to_string(size_pt ? size_pt : 10); + std::string pat_str = font_family + '-' + std::to_string(size_pt ? size_pt : platform_abstraction::font_default_pt()); auto pat = ::XftNameParse(pat_str.c_str()); XftResult res; auto match_pat = ::XftFontMatch(disp, ::XDefaultScreen(disp), pat, &res); @@ -407,6 +436,31 @@ namespace nana ::FcConfigAppFontClear(nullptr); } } +#endif + } + + unsigned platform_abstraction::screen_dpi(bool x_requested) + { +#ifdef NANA_WINDOWS + auto hdc = ::GetDC(nullptr); + auto dots = static_cast(::GetDeviceCaps(hdc, (x_requested ? LOGPIXELSX : LOGPIXELSY))); + ::ReleaseDC(nullptr, hdc); + return dots; +#else + auto & spec = ::nana::detail::platform_spec::instance(); + auto disp = spec.open_display(); + auto screen = ::XDefaultScreen(disp); + + double dots; + + if (x_requested) + dots += ((((double)DisplayWidth(disp, screen)) * 25.4) / + ((double)DisplayWidthMM(disp, screen))); + else + dots += ((((double)DisplayHeight(disp, screen)) * 25.4) / + ((double)DisplayHeightMM(disp, screen))); + + return static_cast(dots + 0.5); #endif } } diff --git a/source/detail/platform_abstraction.hpp b/source/detail/platform_abstraction.hpp index d22190c6..290e0a5c 100644 --- a/source/detail/platform_abstraction.hpp +++ b/source/detail/platform_abstraction.hpp @@ -33,10 +33,13 @@ namespace nana static void initialize(); /// Shutdown before destruction of platform_spec static void shutdown(); + static double font_default_pt(); static ::std::shared_ptr default_font(const ::std::shared_ptr&); static ::std::shared_ptr make_font(const ::std::string& font_family, double size_pt, const font::font_style& fs); static ::std::shared_ptr make_font_from_ttf(const path_type& ttf, double size_pt, const font::font_style& fs); static void font_resource(bool try_add, const path_type& ttf); + + static unsigned screen_dpi(bool x_requested); }; } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 626803d3..9ddf5842 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -20,6 +20,8 @@ #include #include +#include "../../source/detail/platform_abstraction.hpp" + namespace nana { //restrict @@ -1482,5 +1484,10 @@ namespace API return{}; } + + unsigned screen_dpi(bool x_requested) + { + return ::nana::platform_abstraction::screen_dpi(x_requested); + } }//end namespace API }//end namespace nana diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index c2d75048..d5e71b54 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -134,6 +134,7 @@ namespace nana std::function weak_ordering; + std::shared_ptr font; ///< The exclusive column font column() = default; @@ -150,11 +151,12 @@ namespace nana index = other.index; alignment = other.alignment; weak_ordering = other.weak_ordering; + font = other.font; } return *this; } - + column(column&& other): caption(std::move(other.caption)), width_px(other.width_px), @@ -163,6 +165,7 @@ namespace nana index(other.index), alignment(other.alignment), weak_ordering(std::move(other.weak_ordering)), + font(std::move(other.font)), ess_(other.ess_) { } @@ -237,6 +240,12 @@ namespace nana //Definition is provided after essence void fit_content(unsigned maximize = 100000) noexcept override; + /// Sets an exclusive font for the column + void typeface(const paint::font& column_font) override; + + /// Returns a font + paint::font typeface() const noexcept override; + bool visible() const noexcept override { return visible_state; @@ -307,7 +316,7 @@ namespace nana return cont_.back().index; } - unsigned pixels() const noexcept ///< the visible width of the whole header + unsigned width_px() const noexcept ///< the visible width of the whole header { unsigned pixels = 0; for(auto & col : cont_) @@ -716,6 +725,13 @@ namespace nana std::size_t column_pos; }; + enum class view_action + { + auto_view, + top_view, + bottom_view, + }; + class es_lister { public: @@ -971,7 +987,12 @@ namespace nana return prstatus; } - void scroll(const index_pair& abs_pos, bool to_bottom); +#if 0 + void scroll(const index_pair& abs_pos, bool to_bottom); //deprecated +#endif + + /// Scroll the selected item into the view + void scroll_into_view(const index_pair& abs_pos, view_action vw_act); /// Append a new category with a specified name and return a pointer to it. category_t* create_cat(native_string_type&& text) @@ -1672,7 +1693,7 @@ namespace nana ///origin(); - return{ r.x - origin.x, r.x - origin.x + static_cast(header.pixels()) }; + return{ r.x - origin.x, r.x - origin.x + static_cast(header.width_px()) }; } void start_mouse_selection(const arg_mouse& arg) @@ -2112,7 +2133,7 @@ namespace nana auto content_x = coordinate_cast({ columns_range().first, 0 }, true).x; if ((std::max)(mouse_selection.end_position.x, mouse_selection.begin_position.x) >= content_x && - (std::min)(mouse_selection.end_position.x, mouse_selection.begin_position.x) < content_x + static_cast(header.pixels())) + (std::min)(mouse_selection.end_position.x, mouse_selection.begin_position.x) < content_x + static_cast(header.width_px())) { auto const begin_off = (std::max)((std::min)(mouse_selection.begin_position.y, mouse_selection.end_position.y), 0) / item_height(); @@ -2225,7 +2246,7 @@ namespace nana ::nana::size calc_content_size(bool try_update = true) { size ctt_size( - this->header.pixels() + this->header.margin(), + this->header.width_px() + this->header.margin(), static_cast(this->lister.the_number_of_expanded()) * this->item_height() ); @@ -2271,12 +2292,12 @@ namespace nana { /// we are inside auto const origin = content_view->origin(); - if(header.visible() && (pos.y < static_cast(scheme_ptr->header_height) + area.y)) + if (header.visible() && (pos.y < static_cast(header_visible_px()) + area.y)) { /// we are in the header new_where.first = parts::header; new_where.second = this->column_from_pos(pos.x); } - else if (area.x <= pos.x + origin.x && pos.x + origin.x < area.x + static_cast(header.pixels())) + else if (area.x <= pos.x + origin.x && pos.x + origin.x < area.x + static_cast(header.width_px())) { // detect if cursor is in the area of header margin if (pos.x < area.x - origin.x + static_cast(header.margin())) @@ -2356,9 +2377,42 @@ namespace nana return r; } + double header_font_px() const + { + unsigned max_font_px = 0; + + paint::graphics graph{ size{ 1, 1 } }; + for (auto & col : this->header.cont()) + { + if (!col.visible()) + continue; + + graph.typeface(col.typeface()); + + unsigned as, ds, ileading; + graph.text_metrics(as, ds, ileading); + + max_font_px = (std::max)(as + ds, max_font_px); + } + + if (0 == max_font_px) + { + graph.typeface(listbox_ptr->typeface()); + unsigned as, ds, ileading; + graph.text_metrics(as, ds, ileading); + + max_font_px = (std::max)(as + ds, max_font_px); + } + + return max_font_px; + } + unsigned header_visible_px() const { - return (header.visible() ? scheme_ptr->header_height : 0); + if (!header.visible()) + return 0; + + return scheme_ptr->header_padding_top + scheme_ptr->header_padding_bottom + static_cast(header_font_px()); } bool rect_header(nana::rectangle& r) const @@ -2367,7 +2421,7 @@ namespace nana { r = this->content_area(); - r.height = scheme_ptr->header_height; + r.height = header_visible_px(); if (lister.wd_ptr()->borderless()) return !r.empty(); @@ -2777,6 +2831,29 @@ namespace nana _m_refresh(); } + + /// Sets an exclusive font for the column + void es_header::column::typeface(const paint::font& column_font) + { + this->font.reset(new paint::font{ column_font }); + + API::refresh_window(*ess_->listbox_ptr); + } + + /// Returns a font + paint::font es_header::column::typeface() const noexcept + { + //Returns the exclusive font if it is not empty + if (this->font && !this->font->empty()) + return *this->font; + + //Returns the column font if it is not empty + if (ess_->scheme_ptr->column_font && !ess_->scheme_ptr->column_font) + return *(ess_->scheme_ptr->column_font); + + //If all above fonts are invalid, returns the widget font. + return ess_->listbox_ptr->typeface(); + } //end es_header::column functions class inline_indicator @@ -2865,7 +2942,8 @@ namespace nana std::vector> panes_; }; - void es_lister::scroll(const index_pair& abs_pos, bool to_bottom) +#if 0 + void es_lister::scroll(const index_pair& abs_pos, bool to_bottom) //deprecated { auto& cat = *get(abs_pos.cat); @@ -2909,6 +2987,63 @@ namespace nana if(ess_->content_view->move_origin(origin - ess_->content_view->origin())) ess_->content_view->sync(false); } +#endif + + void es_lister::scroll_into_view(const index_pair& abs_pos, view_action vw_act) + { + auto& cat = *get(abs_pos.cat); + + if ((abs_pos.item != nana::npos) && (abs_pos.item >= cat.items.size())) + throw std::invalid_argument("listbox: invalid pos to scroll"); + + if (!cat.expand) + { + this->expand(abs_pos.cat, true); + ess_->calc_content_size(); + } + else if (!ess_->auto_draw) + { + //force a update of content size and scrollbar status when auto_draw is false to make + //sure that the scroll function works fine. + ess_->calc_content_size(); + } + + auto origin = ess_->content_view->origin(); + + auto off = this->distance(this->first(), this->index_cast(abs_pos, false)) * ess_->item_height(); + + auto screen_px = ess_->content_view->view_area().height; + + if (view_action::auto_view == vw_act) + { + if (static_cast(off) < origin.y) + vw_act = view_action::top_view; + else if (static_cast(off) >= static_cast(origin.y + ess_->content_view->view_area().height)) + vw_act = view_action::bottom_view; + else + return; + } + + origin.y = 0; + + if (view_action::bottom_view == vw_act) + { + off += ess_->item_height(); + if (off >= screen_px) + origin.y = static_cast(off - screen_px); + } + else + { + auto last_off = this->distance(this->first(), this->last()) * ess_->item_height(); + if (last_off - off >= screen_px) + origin.y = static_cast(off); + else if (last_off >= screen_px) + origin.y = static_cast(last_off - screen_px); + } + + if (ess_->content_view->move_origin(origin - ess_->content_view->origin())) + ess_->content_view->sync(false); + } void es_lister::erase(const index_pair& pos) { @@ -2928,7 +3063,7 @@ namespace nana } } - void es_lister::move_select(bool upwards, bool unselect_previous, bool /*trace_selected*/) noexcept + void es_lister::move_select(bool upwards, bool unselect_previous, bool into_view) noexcept { auto next_selected_dpl = index_cast_noexcpt(latest_selected_abs, false); //convert absolute position to display position @@ -3008,6 +3143,9 @@ namespace nana } else break; } + + if (into_view && !latest_selected_abs.empty()) + this->scroll_into_view(latest_selected_abs, view_action::auto_view); } std::string es_lister::to_string(const export_options& exp_opt) const @@ -3081,6 +3219,14 @@ namespace nana using item_state = essence::item_state; using parts = essence::parts; + struct column_rendering_parameter + { + unsigned margin; + unsigned height; + double max_font_px; + paint::font wdg_font; + }; + drawer_header_impl(essence* es) noexcept: essence_(es){} size_type splitter() const noexcept @@ -3192,25 +3338,31 @@ namespace nana 0, r.height - 1 }; + column_rendering_parameter crp; + //The first item includes the margin - unsigned margin = essence_->header.margin(); + crp.margin = essence_->header.margin(); + + crp.height = essence_->header_visible_px(); + crp.max_font_px = essence_->header_font_px(); + crp.wdg_font = graph.typeface(); for (auto & col : essence_->header.cont()) { if (col.visible_state) { - column_r.width = col.width_px + margin; + column_r.width = col.width_px + crp.margin; const auto right_pos = column_r.right(); //Make sure the column is in the display area. if (right_pos > r.x) { - _m_draw_header_item(graph, margin, column_r, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); + _m_draw_header_item(graph, crp, column_r, text_color, col, (col.index == essence_->pointer_where.second ? state : item_state::normal)); graph.line({ right_pos - 1, r.y }, { right_pos - 1, r.bottom() - 2 }, border_color); } - margin = 0; + crp.margin = 0; column_r.x = right_pos; if (right_pos > r.right()) @@ -3275,7 +3427,7 @@ namespace nana return npos; } - void _m_draw_header_item(graph_reference graph, unsigned margin, const rectangle& column_r, const ::nana::color& fgcolor, const es_header::column& column, item_state state) + void _m_draw_header_item(graph_reference graph, const column_rendering_parameter& crp, const rectangle& column_r, const ::nana::color& fgcolor, const es_header::column& column, item_state state) { ::nana::color bgcolor; @@ -3306,7 +3458,16 @@ namespace nana { graph.palette(true, fgcolor); - point text_pos{ column_r.x + static_cast(margin), (static_cast(essence_->scheme_ptr->header_height) - static_cast(essence_->text_height)) / 2 }; + //Set column font + graph.typeface(column.typeface()); + + unsigned ascent, descent, ileading; + graph.text_metrics(ascent, descent, ileading); + + point text_pos{ + column_r.x + static_cast(crp.margin), + column_r.bottom() - static_cast(crp.height + ascent + descent) / 2 + }; if (align::left == column.alignment) text_pos.x += text_margin; @@ -3314,6 +3475,9 @@ namespace nana text_margin = 0; text_aligner.draw(column.caption, text_pos, column_r.width - text_margin); + + //Restores widget font + graph.typeface(crp.wdg_font); } auto & sort = essence_->lister.sort_attrs(); @@ -3330,16 +3494,20 @@ namespace nana { const auto & col = essence_->header.at(essence_->pointer_where.second); - auto margin = 0; - - if (&essence_->header.at(0, true) == &col) - margin = essence_->header.margin(); + column_rendering_parameter crp; + crp.margin = 0; + crp.height = essence_->header_visible_px(); + crp.max_font_px = essence_->header_font_px(); + crp.wdg_font = essence_->listbox_ptr->typeface(); - paint::graphics fl_graph({ col.width_px + margin, essence_->scheme_ptr->header_height }); + if (&essence_->header.at(0, true) == &col) + crp.margin = essence_->header.margin(); + + paint::graphics fl_graph({ col.width_px + crp.margin, crp.height }); fl_graph.typeface(essence_->graph->typeface()); - _m_draw_header_item(fl_graph, margin, rectangle{ fl_graph.size()}, colors::white, col, item_state::floated); + _m_draw_header_item(fl_graph, crp, rectangle{ fl_graph.size()}, colors::white, col, item_state::floated); auto xpos = essence_->header.range(col.index).first + pos.x - grabs_.start_pos; essence_->graph->blend(rectangle{ point{ xpos - essence_->content_view->origin().x + rect.x, rect.y } , fl_graph.size() }, fl_graph, {}, 0.5); @@ -3398,7 +3566,7 @@ namespace nana essence_->graph->palette(false, bgcolor); - auto const header_w = essence_->header.pixels(); + auto const header_w = essence_->header.width_px(); auto const item_height_px = essence_->item_height(); auto const origin = essence_->content_view->origin(); @@ -3887,21 +4055,11 @@ namespace nana void _m_draw_item_border(int item_top) const { //Draw selecting inner rectangle - /* - rectangle r{ x, y, width, essence_->item_height() }; - - essence_->graph->rectangle(r, false, static_cast(0x99defd)); - - essence_->graph->palette(false, colors::white); - paint::draw(*essence_->graph).corner(r, 1); - - essence_->graph->rectangle(r.pare_off(1), false); - */ rectangle r{ essence_->content_area().x - essence_->content_view->origin().x + static_cast(essence_->header.margin()), item_top, - essence_->header.pixels(), + essence_->header.width_px(), essence_->item_height() }; @@ -3966,8 +4124,6 @@ namespace nana void trigger::typeface_changed(graph_reference graph) { - //essence_->text_height = graph.text_extent_size(L"jHWn0123456789/text_height = 0; unsigned as, ds, il; if (graph.text_metrics(as, ds, il)) @@ -4396,7 +4552,7 @@ namespace nana //Check if it scrolls in current screen window //condition: top of target item is not less than top edge of content view and //the bottom of target item is not greater than bottom edge of content view. - if ((screen_top + item_px <= logic_top) && (logic_top + item_px + item_px <= screen_bottom)) + if ((screen_top + static_cast(item_px) <= logic_top) && (logic_top + static_cast(item_px) + static_cast(item_px) <= screen_bottom)) { int offset = (static_cast(upward ? screen_top : screen_bottom - item_px) - logic_top) / static_cast(item_px); target_idx = list.advance(init_idx, offset); @@ -4488,8 +4644,11 @@ namespace nana } else item_proxy::from_display(essence_, pos).select(true); + + list.scroll_into_view(pos, view_action::auto_view); } } + } break; default: @@ -4585,7 +4744,7 @@ namespace nana ess_->lister.get(pos_.cat)->expand = false; if (!this->displayed()) - ess_->lister.scroll(pos_, !(ess_->first_display() > this->to_display())); + ess_->lister.scroll_into_view(pos_, (ess_->first_display() > this->to_display() ? view_action::top_view : view_action::bottom_view)); } ess_->update(); @@ -4623,7 +4782,7 @@ namespace nana ess_->lister.latest_selected_abs.set_both(npos); if (scroll_view && (!this->displayed())) - ess_->lister.scroll(pos_, !(ess_->first_display() > this->to_display())); + ess_->lister.scroll_into_view(pos_, (ess_->first_display() > this->to_display() ? view_action::top_view : view_action::bottom_view)); ess_->update(); return *this; @@ -5291,13 +5450,13 @@ namespace nana else pos.item = ess.lister.size_item(cat_pos) ? 0 : ::nana::npos; - ess.lister.scroll(pos, to_bottom); - ess.update(); + this->scroll(to_bottom, pos); } void listbox::scroll(bool to_bottom, const index_pair& abs_pos) { - _m_ess().lister.scroll(abs_pos, to_bottom); + using view_action = drawerbase::listbox::view_action; + _m_ess().lister.scroll_into_view(abs_pos, (to_bottom ? view_action::bottom_view : view_action::top_view)); _m_ess().update(); } @@ -5669,7 +5828,7 @@ namespace nana void listbox::move_select(bool upwards) ///real_font->family(); } - double font::size() const + double font::size(bool fixed) const { - if(empty()) return 0; + double size_pt = (empty() ? 0.0 : impl_->real_font->size()); - return impl_->real_font->size(); + if (fixed && (0.0 == size_pt)) + return platform_abstraction::font_default_pt(); + + return size_pt; } bool font::bold() const