123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // Flexlay - A Generic 2D Game Editor
- // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- #include <ClanLib/Core/IOData/directory_scanner.h>
- #include <ClanLib/Display/display.h>
- #include "fonts.hpp"
- #include "directory_view.hpp"
- class DirectoryViewEntry
- {
- public:
- std::string name;
- bool directory;
- bool hidden;
- };
- struct DirectoryViewSorter
- {
- bool operator()(const DirectoryViewEntry& lhs, const DirectoryViewEntry& rhs)
- {
- if (lhs.directory > rhs.directory)
- return true;
- else if (lhs.directory < rhs.directory)
- return false;
- else
- return lhs.name < rhs.name;
- }
- };
- class DirectoryViewImpl
- {
- public:
- DirectoryView* parent;
- std::vector<CL_Slot> slots;
- std::string path;
- CL_Signal_v1<std::string> sig_on_click;
- typedef std::vector<DirectoryViewEntry> Items;
- Items items;
- int current_item;
- int column_width;
- int num_columns;
- void update_items();
- void draw();
- int get_item(const CL_Point& pos);
- void on_mouse_move(const CL_InputEvent& event);
- void on_mouse_down(const CL_InputEvent& event);
- };
- DirectoryView::DirectoryView(const CL_Rect& rect, CL_Component* parent)
- : CL_Component(rect, parent),
- impl(new DirectoryViewImpl())
- {
- impl->parent = this;
- // impl->slots.push_back(sig_mouse_down().connect(impl.get(), &DirectoryViewImpl::draw));
- impl->slots.push_back(sig_paint().connect(impl.get(), &DirectoryViewImpl::draw));
- impl->slots.push_back(sig_mouse_move().connect(impl.get(), &DirectoryViewImpl::on_mouse_move));
- impl->slots.push_back(sig_mouse_down().connect(impl.get(), &DirectoryViewImpl::on_mouse_down));
- impl->current_item = -1;
- }
- DirectoryView::~DirectoryView()
- {
- }
- void
- DirectoryView::set_directory(const std::string& path_)
- {
- impl->path = path_;
- impl->update_items();
- }
- CL_Signal_v1<std::string>&
- DirectoryView::sig_on_click()
- {
- return impl->sig_on_click;
- }
- void
- DirectoryViewImpl::draw()
- {
- CL_Font font = Fonts::verdana11;
- int horizontal_spacing = 10;
- int vertical_spacing = 5;
- int x_pos = 0;
- int y_pos = 0;
- CL_Display::clear(CL_Color(255, 255, 0));
- int j = 0;
- for(Items::iterator i = items.begin(); i != items.begin()+50 && i != items.end(); ++i)
- {
- if (current_item && current_item < int(items.size()) && j == current_item)
- {
- CL_Rect rect = font.bounding_rect(x_pos * (column_width + horizontal_spacing) + 1,
- y_pos * (font.get_height() + vertical_spacing) + 1,
- i->name);
- CL_Display::fill_rect(CL_Rect(rect.left-5, rect.top-3,
- rect.left+5+column_width, rect.bottom+3),
- CL_Color(250, 200, 0));
- }
- // draw item
- if (!i->directory)
- {
- font.draw(x_pos * (column_width + horizontal_spacing),
- y_pos * (font.get_height() + vertical_spacing),
- i->name);
- }
- else
- {
- font.draw(x_pos * (column_width + horizontal_spacing),
- y_pos * (font.get_height() + vertical_spacing),
- "[" + i->name + "]");
- }
- x_pos += 1;
- if (x_pos >= num_columns)
- {
- x_pos = 0;
- y_pos += 1;
- }
- ++j;
- }
- }
- int
- DirectoryViewImpl::get_item(const CL_Point& pos)
- {
- CL_Font font = Fonts::verdana11;
- int horizontal_spacing = 10;
- int vertical_spacing = 5;
- return (pos.x / (column_width + horizontal_spacing))
- + num_columns * (pos.y / (font.get_height() + vertical_spacing));
- }
- void
- DirectoryViewImpl::on_mouse_down(const CL_InputEvent& event)
- {
- current_item = get_item(event.mouse_pos);
- if (current_item >= 0 && current_item < int(items.size()))
- {
- if (items[current_item].directory)
- parent->set_directory(path + "/" + items[current_item].name);
- }
- }
- void
- DirectoryViewImpl::on_mouse_move(const CL_InputEvent& event)
- {
- current_item = get_item(event.mouse_pos);
- }
- void
- DirectoryViewImpl::update_items()
- {
- items.clear();
- CL_DirectoryScanner scanner;
- scanner.scan(path);
- while(scanner.next())
- {
- DirectoryViewEntry entry;
- entry.name = scanner.get_name();
- entry.hidden = (scanner.get_name()[0] == '.');
- entry.directory = scanner.is_directory();
- items.push_back(entry);
- }
- std::sort(items.begin(), items.end(), DirectoryViewSorter());
- CL_Font font = Fonts::verdana11;
- column_width = 60; // min_colum_width
- for(Items::iterator i = items.begin(); i != items.end(); ++i)
- {
- CL_Rect rect = font.bounding_rect(0, 0, i->name + "[]");
- column_width = std::max(column_width, rect.get_width());
- }
- num_columns = parent->get_width()/column_width;
- }
- /* EOF */
|