widget.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. use tui::{
  2. buffer::Buffer,
  3. layout::Rect,
  4. style::{Color, Modifier},
  5. widgets::Widget,
  6. };
  7. use crate::{
  8. style::{convert, RinkColor, RinkStyle},
  9. Config,
  10. };
  11. pub struct RinkBuffer<'a> {
  12. buf: &'a mut Buffer,
  13. cfg: Config,
  14. }
  15. impl<'a> RinkBuffer<'a> {
  16. fn new(buf: &'a mut Buffer, cfg: Config) -> RinkBuffer<'a> {
  17. Self { buf, cfg }
  18. }
  19. pub fn set(&mut self, x: u16, y: u16, new: &RinkCell) {
  20. let area = self.buf.area();
  21. if x < area.x || x > area.width || y < area.y || y > area.height {
  22. panic!("({x}, {y}) is not in {area:?}");
  23. }
  24. let mut cell = self.buf.get_mut(x, y);
  25. cell.bg = convert(self.cfg.rendering_mode, new.bg.blend(cell.bg));
  26. if new.symbol.is_empty() {
  27. if !cell.symbol.is_empty() {
  28. // allows text to "shine through" transparent backgrounds
  29. cell.fg = convert(self.cfg.rendering_mode, new.bg.blend(cell.fg));
  30. }
  31. } else {
  32. cell.modifier = new.modifier;
  33. cell.symbol = new.symbol.clone();
  34. cell.fg = convert(self.cfg.rendering_mode, new.fg.blend(cell.bg));
  35. }
  36. }
  37. }
  38. pub trait RinkWidget {
  39. fn render(self, area: Rect, buf: RinkBuffer);
  40. }
  41. pub struct WidgetWithContext<T: RinkWidget> {
  42. widget: T,
  43. config: Config,
  44. }
  45. impl<T: RinkWidget> WidgetWithContext<T> {
  46. pub fn new(widget: T, config: Config) -> WidgetWithContext<T> {
  47. WidgetWithContext { widget, config }
  48. }
  49. }
  50. impl<T: RinkWidget> Widget for WidgetWithContext<T> {
  51. fn render(self, area: Rect, buf: &mut Buffer) {
  52. self.widget.render(area, RinkBuffer::new(buf, self.config))
  53. }
  54. }
  55. #[derive(Clone)]
  56. pub struct RinkCell {
  57. pub symbol: String,
  58. pub bg: RinkColor,
  59. pub fg: RinkColor,
  60. pub modifier: Modifier,
  61. }
  62. impl Default for RinkCell {
  63. fn default() -> Self {
  64. Self {
  65. symbol: "".to_string(),
  66. fg: RinkColor {
  67. color: Color::Rgb(0, 0, 0),
  68. alpha: 0,
  69. },
  70. bg: RinkColor {
  71. color: Color::Rgb(0, 0, 0),
  72. alpha: 0,
  73. },
  74. modifier: Modifier::empty(),
  75. }
  76. }
  77. }
  78. impl RinkCell {
  79. pub fn set_style(&mut self, style: RinkStyle) {
  80. if let Some(c) = style.fg {
  81. self.fg = c;
  82. }
  83. if let Some(c) = style.bg {
  84. self.bg = c;
  85. }
  86. self.modifier = style.add_modifier;
  87. self.modifier.remove(style.sub_modifier);
  88. }
  89. }