/** * Yudit Unicode Editor Source File * * GNU Copyright (C) 1997-2006 Gaspar Sinai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * dated June 1991. See file COPYYING for details. * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "swidget/STextList.h" STextList::STextList (void) : label (""), selectedLabel ("") { listListener = 0; lastSelected = -1; sliderListener = 0; viewableSize=SDimension (1,1); lastSelected = -1; setSelectedBackground (SColor("blue")); setSelectedForeground (SColor("white")); setTextBackground (SColor("white")); } STextList::~STextList () { } void STextList::setText (const SStringVector& v) { lastSelected = -1; vector = v; selectedVector.clear(); for (unsigned int i=0; iredraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height, viewableSize.width, viewableSize.height); } /** * recalculate slider. */ void STextList::recalc(int current) { slidable.value.y = current; slidable.step.height = label.textView.lineHeight; slidable.page.height = viewableSize.height/2+1; slidable.max.height = vector.size() * label.textView.lineHeight; slidable.max.height = (slidable.max.height > viewableSize.height) ? slidable.max.height - viewableSize.height: 0; if ((int)slidable.max.height < slidable.value.y) { slidable.value.y = (int)slidable.max.height; window->redraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height, viewableSize.width, viewableSize.height); } if (sliderListener) { sliderListener->valueChanged (&slidable, SSliderListener::SS_VERTICAL); } } void STextList::clear () { } void STextList::makeSelectedVisible() { if (lastSelected == -1) return; int loc = locationForIndex ((unsigned int) lastSelected); SSlidable s; bool changed = false; if (loc < (int) border.getBorderSize().height) { s.value.y = slidable.value.y - ((int) border.getBorderSize().height - loc); changed = true; } else if (loc + (int) label.textView.lineHeight > (int) border.getBorderSize().height + (int)viewableSize.height) { s.value.y = slidable.value.y + loc + (int) label.textView.lineHeight - (int) border.getBorderSize().height - (int)viewableSize.height; changed = true; } if (changed) { valueChanged (&s, SSliderListener::SS_VERTICAL); sliderListener->valueChanged (&slidable, SSliderListener::SS_VERTICAL); } } void STextList::setBackground (const SColor& bg) { //SPanel::setBackground (bg); //label.setBackground (bg); } void STextList::setTextBackground (const SColor& bg) { SPanel::setBackground (bg); label.setBackground (bg); } void STextList::setSelectedBackground (const SColor& bg) { selectedLabel.setBackground (bg); } void STextList::setForeground (const SColor& fg) { label.setForeground (fg); } void STextList::setSelectedForeground (const SColor& fg) { selectedLabel.setForeground (fg); } void STextList::redraw (SWindow *canvas, int x, int y, unsigned int width, unsigned int height) { clip (false); border.redraw (canvas, x, y, width, height); clip (true); if (vector.size()==0) return; unsigned int from = indexForLocation (y); unsigned int till = indexForLocation (y+(int)height + (int) label.textView.lineHeight); for (unsigned int i=from; i<=till; i++) { redraw (canvas, i, (int) border.getBorderSize().width, viewableSize.width); } } void STextList::keyPressed (SWindow * w, SKey key, const SString& s, bool ctrl, bool shift, bool meta) { } void STextList::keyReleased (SWindow * w, SKey key, const SString& s, bool ctrl, bool shift, bool meta) { } void STextList::buttonPressed (SWindow * w, int button, int x, int y) { selectLocation (y); if (listListener) { listListener->itemHighlighted(this, lastSelected); } } void STextList::buttonReleased (SWindow * w, int button, int x, int y) { if (lastSelected < 0) return; if (listListener) { listListener->itemSelected(this, 0); } } void STextList::buttonDragged (SWindow * w, int button, int x, int y) { selectLocation (y); if (listListener) { listListener->itemHighlighted(this, lastSelected); } } void STextList::resize (const SDimension& d) { SPanel::resize (d); border.resize (d); viewableSize = getSize(); if (viewableSize.width > 2 * border.getBorderSize().width) { viewableSize.width = viewableSize.width - 2 * border.getBorderSize().width; } if (viewableSize.height > 2 * border.getBorderSize().height) { viewableSize.height = viewableSize.height - 2 * border.getBorderSize().height; } selectedLabel.resize (SDimension (viewableSize.width, selectedLabel.textView.lineHeight)); label.resize (SDimension (viewableSize.width, selectedLabel.textView.lineHeight)); recalc (slidable.value.y); } void STextList::move (const SLocation& loc) { SPanel::move (loc); } SSlidable* STextList::setSliderListener (SSliderListener* l) { sliderListener = l; return &slidable; } /* This is from SSliderListener */ void STextList::valueChanged (SSlidable* _slidable, SSlideType type) { if (type==SSliderListener::SS_HORIZONTAL) return; if (slidable.value.y == _slidable->value.y) return; int diff = slidable.value.y - _slidable->value.y; unsigned int udiff = (diff<0) ? (unsigned int) (-diff) : (unsigned int) diff; slidable.value = _slidable->value; /* redraw the whole thing */ if (udiff > viewableSize.height) { window->redraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height, viewableSize.width, viewableSize.height); } /* up */ else if (diff < 0) { window->copy ((int) border.getBorderSize().width, (int) udiff + (int) border.getBorderSize().height, (int) viewableSize.width, (int) viewableSize.height-(int) udiff, border.getBorderSize().width, border.getBorderSize().height); /* redraw down */ window->redraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height + (int) viewableSize.height - (int) udiff, viewableSize.width, udiff); } else { /* copy down */ window->copy ((int) border.getBorderSize().width, (int) border.getBorderSize().height, (int) viewableSize.width, (int) viewableSize.height-(int) udiff, border.getBorderSize().width, border.getBorderSize().height + udiff); /* redraw up */ window->redraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height, viewableSize.width, udiff); } } void STextList::clip (bool on) { if (!on) { window->removeClippingArea (); return; } window->setClippingArea ( (int) border.getBorderSize().width , (int) border.getBorderSize().height, size.width - 2 * border.getBorderSize().width, size.height - 2 * border.getBorderSize().height); } /** * redraw one line */ void STextList::redraw (SCanvas* canvas, unsigned int index, int x, unsigned int w) { bool ison = selectedVector[index]; SLocation l((int) border.getBorderSize().width, locationForIndex (index)); if (ison) { canvas->bitfill (selectedLabel.getBackground(), l.x, l.y, getSize().width, selectedLabel.textView.lineHeight); selectedLabel.move(l); selectedLabel.setText(vector[index]); selectedLabel.redraw (canvas, l.x, l.y, getSize().width, selectedLabel.textView.lineHeight); } else { label.move(l); label.setText(vector[index]); //fprintf (stderr, "draw='%*.*s'\n", SSARGS(vector[index])); label.redraw (canvas, l.x, l.y, getSize().width, selectedLabel.textView.lineHeight); } } void STextList::selectLocation (int y) { if (vector.size()==0) return; int line = indexForLocation (y, false); selectItem (line); } /** * select an item. if item is -1 deselect all * @return true if anything got selected. */ bool STextList::selectItem (int line) { if (lastSelected == line) return line>=0; /* do real calculation here */ if (lastSelected >= 0) { selectedVector.replace ((unsigned int) lastSelected, false); window->redraw (true, (int) border.getBorderSize().width , locationForIndex ((unsigned int) lastSelected), viewableSize.width, label.textView.lineHeight); } lastSelected = line; if (lastSelected >= 0) { selectedVector.replace ((unsigned int) lastSelected, true); /* do real calculation here */ window->redraw (true, (int) border.getBorderSize().width , locationForIndex ((unsigned int) lastSelected), viewableSize.width, label.textView.lineHeight); makeSelectedVisible (); return true; } return false; } /** * Select first text if found. Unselect all otehrwise. */ bool STextList::selectText (const SString& text) { int si = -1; for (unsigned int i=0; i= (int) vector.size()) { line = correct ? (int) vector.size() -1 : -1; } return line; } /** * calculate the physical location for a given index */ int STextList::locationForIndex (unsigned int index) { int ret = (int)border.getBorderSize().height + (int) index * (int) label.textView.lineHeight - slidable.value.y; return ret; } /** * Chose between fonts. * @param fnt is the font to chose. * @param size is the size of the font or zero if old size is used. */ void STextList::setFont (const SString& fnt, double size) { label.setFont (fnt, size); selectedLabel.setFont (fnt, size); window->redraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height, viewableSize.width, viewableSize.height); recalc(slidable.value.y); } /** * Set the size of the font. */ void STextList::setFontSize (double size) { label.setFontSize (size); selectedLabel.setFontSize (size); window->redraw (true, (int) border.getBorderSize().width , (int) border.getBorderSize().height, viewableSize.width, viewableSize.height); recalc(slidable.value.y); } void STextList::setListListener (SListListener* l) { listListener = l; } SListListener::SListListener(void) { } SListListener::~SListListener() { } void SListListener::itemHighlighted (void* source, int it) { } /** * return the last selected item or -1 */ int STextList::getLastSelected () { return lastSelected; } /** * return the last selected item or -1 */ SString STextList::getLastSelectedText () { if (lastSelected < 0) return SString(); return SString(vector[(unsigned int)lastSelected]); }