Select Git revision
-
Jan Prachař authoredJan Prachař authored
Wrappers.cs 4.77 KiB
// i3csstatus - Alternative generator of i3 status bar written in c#
// (c) 2022 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
// 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
// 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 <https://www.gnu.org/licenses/>.
#nullable enable
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using Color = System.Drawing.Color;
using Process = System.Diagnostics.Process;
using Config;
namespace i3csstatus;
abstract partial class StatusBar
{
protected static Module addStandardModuleWrappers(ConfigSection section, Module module, ModuleParent parrent)
{
if(section.Contains("_default_color"))
module = new WrapperDefaultColor(module, section.Mandatory("_default_color").AsColor());
if(section.Contains("_color"))
module = new WrapperColor(module, section.Mandatory("_color").AsColor());
foreach(var opt in section)
{
MouseButton? button = null;
Modifiers modifiers = 0;
if(opt.KeyAsValue().Tokens()[0] == "_exec")
{
opt.Use();
foreach(var t in opt.KeyAsValue().Tokens()[1..])
{
void setButton(MouseButton _button)
{
if(button != null)
throw new ConfigMistake(t, "Duplicit button definition.");
button = _button;
}
if(t=="left") setButton(MouseButton.Left); else
if(t=="right") setButton(MouseButton.Right); else
if(t=="middle") setButton(MouseButton.Middle); else
if(t=="ctrl" || t=="control") modifiers |= Modifiers.Control; else
if(t=="shift") modifiers |= Modifiers.Shift; else
if(t=="alt") modifiers |= Modifiers.Alt; else
if(t=="super" || t=="win" || t=="windows") modifiers |= Modifiers.Super; else
throw new ConfigMistake(t, $"No such modifiers or mouse key \"{t.AsString()}\".");
}
module = new WrapperExec(module, opt.AsString(), button ?? MouseButton.Left, modifiers);
}
}
if(section.Contains("_cache"))
module = new WrapperCache(module, section.Mandatory("_cache").AsMs());
module.Init(parrent, section);
return module;
}
}
#nullable disable
class ModuleWrapper: Module, ModuleParent
{
protected Module child;
protected ModuleParent parent;
public ModuleWrapper(Module _child)
{
child = _child;
}
virtual public IEnumerable<Block> Get()
=> child.Get();
virtual public void Init(ModuleParent _parent, ConfigSection section)
{
parent = _parent;
child.Init(this, section);
}
virtual public T GetGlobal<T>() where T: GlobalModuleResource, new()
=> parent.GetGlobal<T>();
virtual public void Schedule(int in_ms)
=> parent.Schedule(in_ms);
}
class WrapperDefaultColor: ModuleWrapper
{
Color defaultColor;
public WrapperDefaultColor(Module _child, Color _defaultColor):base(_child)
{
defaultColor = _defaultColor;
}
override public IEnumerable<Block> Get()
=> child.Get().Select(x => x with {
Color = x.Color==null ? defaultColor : x.Color
}).ToArray();
}
class WrapperColor: ModuleWrapper
{
Color color;
public WrapperColor(Module _child, Color _color):base(_child)
{
color = _color;
}
override public IEnumerable<Block> Get()
=> child.Get().Select(x => x with {
Color = color
}).ToArray();
}
class WrapperExec: ModuleWrapper
{
string cmd;
MouseButton button;
Modifiers modifiers;
public WrapperExec(Module _child, string _cmd, MouseButton _button, Modifiers _modifiers):base(_child)
{
cmd = _cmd;
button = _button;
modifiers = _modifiers;
}
override public IEnumerable<Block> Get()
=> child.Get().Select(x => x with {
OnClick = ev =>
{
if(ev.Button == button && ev.Modifiers == modifiers)
POSIX.Bash(cmd);
else if(x.OnClick != null)
x.OnClick(ev);
}
}).ToArray();
}
class WrapperCache: ModuleWrapper
{
IEnumerable<Block> data;
long? dataTime_ms;
long maxOld_ms;
bool wantRedraw = false;
public WrapperCache(Module _child, long _maxOld_ms):base(_child)
{
maxOld_ms = _maxOld_ms;
}
override public IEnumerable<Block> Get()
{
lock(this)
if(wantRedraw)
{
data = null;
dataTime_ms = null;
}
child.Get();
if(dataTime_ms == null || dataTime_ms + maxOld_ms <= Environment.TickCount64)
{
dataTime_ms = Environment.TickCount64;
data = child.Get();
}
return data;
}
override public void Schedule(int in_ms)
{
lock(this)
wantRedraw = true;
parent.Schedule(in_ms);
}
}