📄 fl_window_type.cxx
字号:
//// "$Id: Fl_Window_Type.cxx,v 1.1.1.1 2003/08/07 21:18:39 jasonk Exp $"//// Window type code for the Fast Light Tool Kit (FLTK).//// The widget describing an Fl_Window. This is also all the code// for interacting with the overlay, which allows the user to// select, move, and resize the children widgets.//// Copyright 1998-1999 by Bill Spitzak and others.//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library 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// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "fltk-bugs@easysw.com".//#include <FL/Fl.H>#include <FL/Fl_Overlay_Window.H>#include <FL/fl_message.H>#include <FL/fl_draw.H>#include <FL/Fl_Menu_Item.H>#include "Fl_Widget_Type.h"#include <math.h>#include <stdlib.h>#include "alignment_panel.h"#include <stdio.h>int gridx = 5;int gridy = 5;int snap = 3;int include_H_from_C = 1;void alignment_cb(Fl_Input *i, long v) { int n = atoi(i->value()); if (n < 0) n = 0; switch (v) { case 1: gridx = n; break; case 2: gridy = n; break; case 3: snap = n; break; }}extern const char* header_file_name;extern const char* code_file_name;void show_alignment_cb(Fl_Widget *, void *) { if(alignment_window==0) make_alignment_window(); include_H_from_C_button->value(include_H_from_C); header_file_input->value(header_file_name); code_file_input->value(code_file_name); char buf[128]; sprintf(buf,"%d",gridx); horizontal_input->value(buf); sprintf(buf,"%d",gridy); vertical_input->value(buf); sprintf(buf,"%d",snap); snap_input->value(buf); alignment_window->show();}void header_input_cb(Fl_Input* i, void*) { header_file_name = i->value();}void code_input_cb(Fl_Input* i, void*) { code_file_name = i->value();}void include_H_from_C_button_cb(Fl_Light_Button* b, void*) { include_H_from_C = b->value();}////////////////////////////////////////////////////////////////Fl_Menu_Item window_type_menu[] = { {"Single",0,0,(void*)FL_WINDOW}, {"Double",0,0,(void*)(FL_WINDOW+1)}, {0}};static int overlays_invisible;// The following Fl_Widget is used to simulate the windows. It has// an overlay for the fluid ui, and special-cases the FL_NO_BOX.class Overlay_Window : public Fl_Overlay_Window { void draw(); void draw_overlay();public: Fl_Window_Type *window; int handle(int); Overlay_Window(int w,int h) : Fl_Overlay_Window(w,h) {Fl_Group::current(0);} void resize(int,int,int,int);};void Overlay_Window::draw() { const int CHECKSIZE = 8; // see if box is clear or a frame or rounded: if ((damage()&FL_DAMAGE_ALL) && (!box() || (box()>=4&&!(box()&2)) || box()>=_FL_ROUNDED_BOX)) { // if so, draw checkerboard so user can see what areas are clear: for (int y = 0; y < h(); y += CHECKSIZE) for (int x = 0; x < w(); x += CHECKSIZE) { fl_color(((y/(2*CHECKSIZE))&1) != ((x/(2*CHECKSIZE))&1) ? FL_WHITE : FL_BLACK); fl_rectf(x,y,CHECKSIZE,CHECKSIZE); } } Fl_Overlay_Window::draw();}void Overlay_Window::draw_overlay() { window->draw_overlay();}int Overlay_Window::handle(int e) { return window->handle(e);}Fl_Type *Fl_Window_Type::make() { Fl_Type *p = Fl_Type::current; while (p && !p->is_code_block()) p = p->parent; if (!p) { fl_message("Please select a function"); return 0; } Fl_Window_Type *o = new Fl_Window_Type(); if (!this->o) {// template widget this->o = new Fl_Window(100,100); Fl_Group::current(0); } o->factory = this; o->drag = 0; o->numselected = 0; Overlay_Window *w = new Overlay_Window(100,100); w->window = o; o->o = w; o->add(p); o->modal = 0; o->non_modal = 0; return o;}void Fl_Window_Type::add_child(Fl_Type* cc, Fl_Type* before) { Fl_Widget_Type* c = (Fl_Widget_Type*)cc; Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; ((Fl_Window*)o)->insert(*(c->o), b); o->redraw();}void Fl_Window_Type::remove_child(Fl_Type* cc) { Fl_Widget_Type* c = (Fl_Widget_Type*)cc; ((Fl_Window*)o)->remove(c->o); o->redraw();}void Fl_Window_Type::move_child(Fl_Type* cc, Fl_Type* before) { Fl_Widget_Type* c = (Fl_Widget_Type*)cc; ((Fl_Window*)o)->remove(c->o); Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; ((Fl_Window*)o)->insert(*(c->o), b); o->redraw();}////////////////////////////////////////////////////////////////// Double-click on window widget shows the window, or if already shown,// it shows the control panel.void Fl_Window_Type::open() { Overlay_Window *w = (Overlay_Window *)o; if (w->shown()) { w->show(); Fl_Widget_Type::open(); } else { Fl_Widget *p = w->resizable(); if (!p) w->resizable(w); w->show(); w->resizable(p); }}// control panel items:#include "widget_panel.h"void modal_cb(Fl_Light_Button* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) {i->hide(); return;} i->show(); i->value(((Fl_Window_Type *)current_widget)->modal); } else { ((Fl_Window_Type *)current_widget)->modal = i->value(); }}void non_modal_cb(Fl_Light_Button* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) {i->hide(); return;} i->show(); i->value(((Fl_Window_Type *)current_widget)->non_modal); } else { ((Fl_Window_Type *)current_widget)->non_modal = i->value(); }}void border_cb(Fl_Light_Button* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) {i->hide(); return;} i->show(); i->value(((Fl_Window*)(current_widget->o))->border()); } else { ((Fl_Window*)(current_widget->o))->border(i->value()); }}void xclass_cb(Fl_Input* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) {i->hide(); return;} i->show(); i->value(((Fl_Widget_Type *)current_widget)->xclass); } else { for (Fl_Type *o = Fl_Type::first; o; o = o->next) if (o->selected && o->is_widget()) { Fl_Widget_Type* w = (Fl_Widget_Type*)o; if (w->is_window() || w->is_button()) storestring(i->value(),w->xclass); if (w->is_window()) ((Fl_Window*)(w->o))->xclass(w->xclass); else if (w->is_menu_item()) w->redraw(); } }}////////////////////////////////////////////////////////////////void Fl_Window_Type::setlabel(const char *n) { if (o) ((Fl_Window *)o)->label(n);}// make() is called on this widget when user picks window off New menu:Fl_Window_Type Fl_Window_type;// Resize from window manager, try to resize it back to a legal size.// This is not proper X behavior, but works on 4DWM and fvwmvoid Overlay_Window::resize(int X,int Y,int W,int H) {// if (!visible() || W==w() && H==h()) {// Fl_Overlay_Window::resize(X,Y,W,H);// return;// }// int nw = gridx&&W!=w() ? ((W+gridx/2)/gridx)*gridx : W;// int nh = gridy&&H!=h() ? ((H+gridy/2)/gridy)*gridy : H; Fl_Widget* t = resizable(); resizable(0); Fl_Overlay_Window::resize(X,Y,W,H); resizable(t);// // make sure new window size surrounds the widgets:// int b = 0;// int r = 0;// for (Fl_Type *o=window->next; o && o->level>window->level; o=o->next)// if (o->is_widget() && !o->is_menu_item()) {// Fl_Widget* w = ((Fl_Widget_Type*)o)->o;// if (w->x()+w->w() > r) r = w->x()+w->w();// if (w->y()+w->h() > b) b = w->y()+w->h();// }// if (nh < b) nh = b;// if (nw < r) nw = r;// // If changed, tell the window manager. Skip really big windows// // that might be bigger than screen:// if (nw != W && nw < Fl::w()-100 || nh != H && nh < Fl::h()-100) size(nw,nh);}// calculate actual move by moving mouse position (mx,my) to// nearest multiple of gridsize, and snap to original positionvoid Fl_Window_Type::newdx() { int dx, dy; if (Fl::event_state(FL_ALT)) { dx = mx-x1; dy = my-y1; } else { int dx0 = mx-x1; int ix = (drag&RIGHT) ? br : bx; dx = gridx ? ((ix+dx0+gridx/2)/gridx)*gridx - ix : dx0; if (dx0 > snap) { if (dx < 0) dx = 0; } else if (dx0 < -snap) { if (dx > 0) dx = 0; } else dx = 0; int dy0 = my-y1; int iy = (drag&BOTTOM) ? by : bt; dy = gridy ? ((iy+dy0+gridy/2)/gridy)*gridy - iy : dy0; if (dy0 > snap) { if (dy < 0) dy = 0; } else if (dy0 < -snap) { if (dy > 0) dy = 0; } else dy = 0; } if (this->dx != dx || this->dy != dy) { this->dx = dx; this->dy = dy; ((Overlay_Window *)(this->o))->redraw_overlay(); }}// Move a widget according to dx and dy calculated abovevoid Fl_Window_Type::newposition(Fl_Widget_Type *o,int &X,int &Y,int &R,int &T) { X = o->o->x(); Y = o->o->y(); R = X+o->o->w(); T = Y+o->o->h(); if (!drag) return; if (drag&DRAG) { X += dx; Y += dy; R += dx; T += dy; } else { if (drag&LEFT) if (X==bx) X += dx; else if (X<bx+dx) X = bx+dx; if (drag&BOTTOM) if (Y==by) Y += dy; else if (Y<by+dy) Y = by+dy; if (drag&RIGHT) if (R==br) R += dx; else if (R>br+dx) R = br+dx; if (drag&TOP) if (T==bt) T += dy; else if (T>bt+dx) T = bt+dx; } if (R<X) {int n = X; X = R; R = n;} if (T<Y) {int n = Y; Y = T; T = n;}}void Fl_Window_Type::draw_overlay() { if (recalc) { bx = o->w(); by = o->h(); br = 0; bt = 0; numselected = 0; for (Fl_Type *q=next; q && q->level>level; q=q->next) if (q->selected && q->is_widget() && !q->is_menu_item()) { numselected++; Fl_Widget_Type* o = (Fl_Widget_Type*)q; if (o->o->x() < bx) bx = o->o->x();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -