mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Merging new panel in the trunk.
This commit is contained in:
13
ede-panel/applets/taskbar/Jamfile
Normal file
13
ede-panel/applets/taskbar/Jamfile
Normal file
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Part of Equinox Desktop Environment (EDE).
|
||||
# Copyright (c) 2009 EDE Authors.
|
||||
#
|
||||
# This program is licensed under terms of the
|
||||
# GNU General Public License version 2 or newer.
|
||||
# See COPYING for details.
|
||||
|
||||
SubDir TOP ede-panel-new applets taskbar ;
|
||||
|
||||
PanelApplet taskbar : TaskButton.cpp Taskbar.cpp ;
|
||||
155
ede-panel/applets/taskbar/TaskButton.cpp
Normal file
155
ede-panel/applets/taskbar/TaskButton.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Pixmap.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <edelib/Debug.h>
|
||||
#include <edelib/Nls.h>
|
||||
#include <edelib/MenuItem.h>
|
||||
#include <edelib/IconLoader.h>
|
||||
|
||||
#include "TaskButton.h"
|
||||
#include "Taskbar.h"
|
||||
#include "Netwm.h"
|
||||
#include "icons/window.xpm"
|
||||
|
||||
EDELIB_NS_USING(MenuItem)
|
||||
EDELIB_NS_USING(IconLoader)
|
||||
EDELIB_NS_USING(ICON_SIZE_TINY)
|
||||
|
||||
static Fl_Pixmap image_window(window_xpm);
|
||||
|
||||
static void close_cb(Fl_Widget*, void*);
|
||||
static void restore_cb(Fl_Widget*, void*);
|
||||
static void minimize_cb(Fl_Widget*, void*);
|
||||
static void maximize_cb(Fl_Widget*, void*);
|
||||
|
||||
static MenuItem menu_[] = {
|
||||
{_("Restore"), 0, restore_cb, 0},
|
||||
{_("Minimize"), 0, minimize_cb, 0},
|
||||
{_("Maximize"), 0, maximize_cb, 0, FL_MENU_DIVIDER},
|
||||
{_("Close"), 0, close_cb, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
static void redraw_whole_panel(TaskButton *b) {
|
||||
/* Taskbar specific member */
|
||||
Taskbar *tb = (Taskbar*)b->parent();
|
||||
tb->panel_redraw();
|
||||
}
|
||||
|
||||
static void close_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
netwm_close_window(bb->get_window_xid());
|
||||
/* no need to redraw whole panel since taskbar elements are recreated again */
|
||||
}
|
||||
|
||||
static void restore_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
wm_ede_restore_window(bb->get_window_xid());
|
||||
|
||||
netwm_set_active_window(bb->get_window_xid());
|
||||
redraw_whole_panel(bb);
|
||||
}
|
||||
|
||||
static void minimize_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
|
||||
if(wm_get_window_state(bb->get_window_xid()) != WM_STATE_ICONIC)
|
||||
wm_set_window_state(bb->get_window_xid(), WM_STATE_ICONIC);
|
||||
|
||||
redraw_whole_panel(bb);
|
||||
}
|
||||
|
||||
static void maximize_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
|
||||
netwm_set_active_window(bb->get_window_xid());
|
||||
netwm_maximize_window(bb->get_window_xid());
|
||||
|
||||
redraw_whole_panel(bb);
|
||||
}
|
||||
|
||||
TaskButton::TaskButton(int X, int Y, int W, int H, const char *l) : Fl_Button(X, Y, W, H, l), xid(0) {
|
||||
box(FL_UP_BOX);
|
||||
align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_CLIP);
|
||||
|
||||
/* parameters for callbacks */
|
||||
menu_[0].user_data(this);
|
||||
menu_[1].user_data(this);
|
||||
menu_[2].user_data(this);
|
||||
menu_[3].user_data(this);
|
||||
|
||||
if(IconLoader::inited()) {
|
||||
Fl_Shared_Image *img = IconLoader::get("process-stop", ICON_SIZE_TINY);
|
||||
menu_[3].image((Fl_Image*)img);
|
||||
}
|
||||
|
||||
image(image_window);
|
||||
}
|
||||
|
||||
void TaskButton::draw(void) {
|
||||
Fl_Color col = value() ? selection_color() : color();
|
||||
draw_box(value() ? (down_box() ? down_box() : fl_down(box())) : box(), col);
|
||||
|
||||
if(image()) {
|
||||
int X, Y, lw, lh;
|
||||
|
||||
X = x() + 5;
|
||||
Y = (y() + h() / 2) - (image()->h() / 2);
|
||||
image()->draw(X, Y);
|
||||
|
||||
X += image()->w() + 5;
|
||||
|
||||
if(label()) {
|
||||
fl_font(labelfont(), labelsize());
|
||||
fl_color(labelcolor());
|
||||
|
||||
lw = lh = 0;
|
||||
fl_measure(label(), lw, lh, align());
|
||||
|
||||
/* use clipping so long labels do not be drawn on the right border, which looks ugly */
|
||||
fl_push_clip(x() + Fl::box_dx(box()),
|
||||
y() + Fl::box_dy(box()),
|
||||
w() - Fl::box_dw(box()) - 5,
|
||||
h() - Fl::box_dh(box()));
|
||||
|
||||
Y = (y() + h() / 2) - (lh / 2);
|
||||
fl_draw(label(), X, Y, lw, lh, align(), 0, 0);
|
||||
|
||||
fl_pop_clip();
|
||||
}
|
||||
} else {
|
||||
draw_label();
|
||||
}
|
||||
|
||||
if(Fl::focus() == this)
|
||||
draw_focus();
|
||||
}
|
||||
|
||||
void TaskButton::display_menu(void) {
|
||||
const char *t = tooltip();
|
||||
|
||||
/* do not popup tooltip when the menu is on */
|
||||
tooltip(NULL);
|
||||
|
||||
const MenuItem *item = menu_->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
|
||||
if(item && item->callback())
|
||||
item->do_callback(this);
|
||||
|
||||
tooltip(t);
|
||||
}
|
||||
|
||||
void TaskButton::update_title_from_xid(void) {
|
||||
E_RETURN_IF_FAIL(xid >= 0);
|
||||
|
||||
char *title = netwm_get_window_title(xid);
|
||||
if(!title) {
|
||||
label("...");
|
||||
tooltip("...");
|
||||
} else {
|
||||
copy_label(title);
|
||||
tooltip(label());
|
||||
free(title);
|
||||
}
|
||||
}
|
||||
24
ede-panel/applets/taskbar/TaskButton.h
Normal file
24
ede-panel/applets/taskbar/TaskButton.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __TASKBUTTON_H__
|
||||
#define __TASKBUTTON_H__
|
||||
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/x.H>
|
||||
|
||||
class TaskButton : public Fl_Button {
|
||||
private:
|
||||
/* window ID this button handles */
|
||||
Window xid;
|
||||
|
||||
public:
|
||||
TaskButton(int X, int Y, int W, int H, const char *l = 0);
|
||||
|
||||
void draw(void);
|
||||
void display_menu(void);
|
||||
|
||||
void set_window_xid(Window win) { xid = win; }
|
||||
Window get_window_xid(void) { return xid; }
|
||||
|
||||
void update_title_from_xid(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
230
ede-panel/applets/taskbar/Taskbar.cpp
Normal file
230
ede-panel/applets/taskbar/Taskbar.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
#include "Applet.h"
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <edelib/Debug.h>
|
||||
|
||||
#include "Netwm.h"
|
||||
#include "TaskButton.h"
|
||||
#include "Taskbar.h"
|
||||
#include "Panel.h"
|
||||
|
||||
#define DEFAULT_CHILD_W 175
|
||||
#define DEFAULT_SPACING 5
|
||||
|
||||
static void button_cb(TaskButton *b, void *t) {
|
||||
Taskbar *tt = (Taskbar*)t;
|
||||
|
||||
if(Fl::event_button() == FL_RIGHT_MOUSE)
|
||||
b->display_menu();
|
||||
else
|
||||
tt->activate_window(b);
|
||||
}
|
||||
|
||||
static void net_event_cb(int action, Window xid, void *data) {
|
||||
E_RETURN_IF_FAIL(data != NULL);
|
||||
|
||||
if(action == NETWM_CHANGED_CURRENT_WORKSPACE || action == NETWM_CHANGED_WINDOW_LIST) {
|
||||
Taskbar *tt = (Taskbar*)data;
|
||||
tt->create_task_buttons();
|
||||
return;
|
||||
}
|
||||
|
||||
if(action == NETWM_CHANGED_WINDOW_NAME) {
|
||||
Taskbar *tt = (Taskbar*)data;
|
||||
tt->update_child_title(xid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is a message, so property is not changed and netwm_get_active_window() must be called */
|
||||
if(action == NETWM_CHANGED_ACTIVE_WINDOW) {
|
||||
Taskbar *tt = (Taskbar*)data;
|
||||
tt->update_active_button();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Taskbar::Taskbar() : Fl_Group(0, 0, 40, 25), curr_active(NULL), prev_active(NULL), panel(NULL) {
|
||||
end();
|
||||
|
||||
panel = EDE_PANEL_GET_PANEL_OBJECT;
|
||||
|
||||
/* assure display is openned */
|
||||
fl_open_display();
|
||||
|
||||
create_task_buttons();
|
||||
netwm_callback_add(net_event_cb, this);
|
||||
}
|
||||
|
||||
Taskbar::~Taskbar() {
|
||||
netwm_callback_remove(net_event_cb);
|
||||
}
|
||||
|
||||
void Taskbar::create_task_buttons(void) {
|
||||
/* erase all current elements */
|
||||
if(children())
|
||||
clear();
|
||||
|
||||
/* also current/prev storage */
|
||||
curr_active = prev_active = NULL;
|
||||
|
||||
/* redraw it, in case no windows exists in this workspace */
|
||||
panel_redraw();
|
||||
|
||||
Window *wins;
|
||||
int nwins = netwm_get_mapped_windows(&wins);
|
||||
|
||||
if(nwins > 0) {
|
||||
TaskButton *b;
|
||||
int curr_workspace = netwm_get_current_workspace();
|
||||
char *title;
|
||||
|
||||
for(int i = 0; i < nwins; i++) {
|
||||
if(!netwm_manageable_window(wins[i]))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* show window per workspace
|
||||
* TODO: allow showing all windows in each workspace
|
||||
*/
|
||||
if(curr_workspace == netwm_get_window_workspace(wins[i])) {
|
||||
b = new TaskButton(0, 0, DEFAULT_CHILD_W, 25);
|
||||
b->set_window_xid(wins[i]);
|
||||
b->update_title_from_xid();
|
||||
|
||||
/*
|
||||
* catch name changes
|
||||
* TODO: put this in Netwm.{h,cpp}
|
||||
*/
|
||||
XSelectInput(fl_display, wins[i], PropertyChangeMask | StructureNotifyMask);
|
||||
|
||||
b->callback((Fl_Callback*)button_cb, this);
|
||||
add(b);
|
||||
}
|
||||
}
|
||||
|
||||
XFree(wins);
|
||||
}
|
||||
|
||||
layout_children();
|
||||
update_active_button();
|
||||
}
|
||||
|
||||
void Taskbar::resize(int X, int Y, int W, int H) {
|
||||
Fl_Widget::resize(X, Y, W, H);
|
||||
layout_children();
|
||||
}
|
||||
|
||||
void Taskbar::layout_children(void) {
|
||||
if(!children())
|
||||
return;
|
||||
|
||||
Fl_Widget *o;
|
||||
int X = x() + Fl::box_dx(box());
|
||||
int Y = y() + Fl::box_dy(box());
|
||||
int W = w() - Fl::box_dw(box());
|
||||
|
||||
int child_w = DEFAULT_CHILD_W;
|
||||
int sz = children();
|
||||
int all_buttons_w = 0;
|
||||
|
||||
/* figure out the bounds */
|
||||
for(int i = 0; i < sz; i++)
|
||||
all_buttons_w += child(i)->w() + DEFAULT_SPACING;
|
||||
|
||||
if(all_buttons_w > W) {
|
||||
int reduce = (all_buttons_w - W) / sz;
|
||||
child_w -= reduce;
|
||||
}
|
||||
|
||||
/* now, position each child and resize it if needed */
|
||||
for(int i = 0; i < sz; i++) {
|
||||
o = child(i);
|
||||
|
||||
o->resize(X, Y, child_w, o->h());
|
||||
X += o->w() + DEFAULT_SPACING;
|
||||
}
|
||||
}
|
||||
|
||||
void Taskbar::update_active_button(int xid) {
|
||||
if(!children())
|
||||
return;
|
||||
|
||||
if(xid == -1) {
|
||||
xid = netwm_get_active_window();
|
||||
/* TODO: make sure panel does not get 'active', or all buttons will be FL_UP_BOX */
|
||||
}
|
||||
|
||||
TaskButton *o;
|
||||
for(int i = 0; i < children(); i++) {
|
||||
o = (TaskButton*)child(i);
|
||||
|
||||
if(o->get_window_xid() == xid)
|
||||
o->box(FL_DOWN_BOX);
|
||||
else
|
||||
o->box(FL_UP_BOX);
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Taskbar::activate_window(TaskButton *b) {
|
||||
E_RETURN_IF_FAIL(b != NULL);
|
||||
|
||||
Window xid = b->get_window_xid();
|
||||
|
||||
/* if clicked on activated button, it will be minimized, then next one will be activated */
|
||||
if(b == curr_active) {
|
||||
if(wm_get_window_state(xid) != WM_STATE_ICONIC) {
|
||||
/* minimize if not so */
|
||||
wm_set_window_state(xid, WM_STATE_ICONIC);
|
||||
|
||||
if(prev_active &&
|
||||
prev_active != b &&
|
||||
wm_get_window_state(prev_active->get_window_xid()) != WM_STATE_ICONIC)
|
||||
{
|
||||
xid = prev_active->get_window_xid();
|
||||
b = prev_active;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* active or restore minimized */
|
||||
netwm_set_active_window(xid);
|
||||
update_active_button(xid);
|
||||
|
||||
/* TODO: use stack for this (case when this can't handle: minimize three window, out of four on the workspace) */
|
||||
prev_active = curr_active;
|
||||
curr_active = b;
|
||||
}
|
||||
|
||||
void Taskbar::update_child_title(Window xid) {
|
||||
E_RETURN_IF_FAIL(xid >= 0);
|
||||
|
||||
TaskButton *o;
|
||||
for(int i = 0; i < children(); i++) {
|
||||
o = (TaskButton*)child(i);
|
||||
|
||||
if(o->get_window_xid() == xid) {
|
||||
o->update_title_from_xid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Taskbar::panel_redraw(void) {
|
||||
E_RETURN_IF_FAIL(panel != NULL);
|
||||
panel->redraw();
|
||||
}
|
||||
|
||||
|
||||
EDE_PANEL_APPLET_EXPORT (
|
||||
Taskbar,
|
||||
EDE_PANEL_APPLET_OPTION_ALIGN_LEFT | EDE_PANEL_APPLET_OPTION_RESIZABLE_H,
|
||||
"Taskbar",
|
||||
"0.1",
|
||||
"empty",
|
||||
"Sanel Zukan"
|
||||
)
|
||||
30
ede-panel/applets/taskbar/Taskbar.h
Normal file
30
ede-panel/applets/taskbar/Taskbar.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __TASKBAR_H__
|
||||
#define __TASKBAR_H__
|
||||
|
||||
#include <FL/Fl_Group.H>
|
||||
|
||||
class TaskButton;
|
||||
class Panel;
|
||||
|
||||
class Taskbar : public Fl_Group {
|
||||
public:
|
||||
TaskButton *curr_active, *prev_active;
|
||||
Panel *panel;
|
||||
|
||||
public:
|
||||
Taskbar();
|
||||
~Taskbar();
|
||||
|
||||
void create_task_buttons(void);
|
||||
|
||||
void resize(int X, int Y, int W, int H);
|
||||
void layout_children(void);
|
||||
|
||||
void update_active_button(int xid = -1);
|
||||
void activate_window(TaskButton *b);
|
||||
void update_child_title(Window xid);
|
||||
|
||||
void panel_redraw(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
BIN
ede-panel/applets/taskbar/icons/window.png
Normal file
BIN
ede-panel/applets/taskbar/icons/window.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 463 B |
76
ede-panel/applets/taskbar/icons/window.xpm
Normal file
76
ede-panel/applets/taskbar/icons/window.xpm
Normal file
@@ -0,0 +1,76 @@
|
||||
/* XPM */
|
||||
static char * window_xpm[] = {
|
||||
"16 16 57 1",
|
||||
" c None",
|
||||
". c #BABDB6",
|
||||
"+ c #FFFFFF",
|
||||
"@ c #FEFEFE",
|
||||
"# c #204A87",
|
||||
"$ c #FCFCFB",
|
||||
"% c #3465A4",
|
||||
"& c #FAFBFA",
|
||||
"* c #F9F9F9",
|
||||
"= c #F8F9F8",
|
||||
"- c #F8F8F8",
|
||||
"; c #F6F6F6",
|
||||
"> c #F5F6F6",
|
||||
", c #F6F5F6",
|
||||
"' c #F6F6F5",
|
||||
") c #F6F5F5",
|
||||
"! c #BBBDB3",
|
||||
"~ c #F7F7F7",
|
||||
"{ c #F4F3F3",
|
||||
"] c #F3F3F3",
|
||||
"^ c #F2F3F3",
|
||||
"/ c #F2F2F3",
|
||||
"( c #F3F2F3",
|
||||
"_ c #F5F5F5",
|
||||
": c #F1F0F1",
|
||||
"< c #F0F1F1",
|
||||
"[ c #F1F0F0",
|
||||
"} c #F0F0F0",
|
||||
"| c #F0F1F0",
|
||||
"1 c #F0EFF0",
|
||||
"2 c #EFF0EF",
|
||||
"3 c #F5F5F4",
|
||||
"4 c #EEEEEE",
|
||||
"5 c #EDEEED",
|
||||
"6 c #EDEDED",
|
||||
"7 c #EDEDEE",
|
||||
"8 c #EEEEED",
|
||||
"9 c #F2F2F2",
|
||||
"0 c #EBEBEB",
|
||||
"a c #EBEBEA",
|
||||
"b c #EAEAEB",
|
||||
"c c #EAEAEA",
|
||||
"d c #F1F2F1",
|
||||
"e c #EFEFF0",
|
||||
"f c #E9E8E8",
|
||||
"g c #E8E8E8",
|
||||
"h c #E8E7E8",
|
||||
"i c #E7E7E7",
|
||||
"j c #E8E7E7",
|
||||
"k c #EFEFEF",
|
||||
"l c #EEEFEE",
|
||||
"m c #E5E5E6",
|
||||
"n c #E5E5E5",
|
||||
"o c #E5E6E5",
|
||||
"p c #F3F2F2",
|
||||
"q c #F0EFEF",
|
||||
"r c #EFF0F0",
|
||||
" ",
|
||||
" ............ ",
|
||||
" .++++++++++++. ",
|
||||
" .@##########+. ",
|
||||
" .$%%%%%%%%%%+. ",
|
||||
" .&***==-====&. ",
|
||||
" .-;>,;'')'''-! ",
|
||||
" .~{]]]]^^]/(;. ",
|
||||
" ._:<[}|}}}123. ",
|
||||
" .]4567867666]. ",
|
||||
" .900aabbbcacd. ",
|
||||
" .efgggghigjhk. ",
|
||||
" .lmnonnnnnnn8. ",
|
||||
" .p2qkr1kkkqkk. ",
|
||||
" ............ ",
|
||||
" "};
|
||||
Reference in New Issue
Block a user