गर्म ट्यूब पाठ इंटरफ़ेस। बस सरल के बारे में

समय-समय पर हब पर विषयों को देखते हुए, मैं लगातार यह सोचकर खुद को पाता हूं कि लैपटॉप में थोड़ा और अधिक और कुछ तंत्रिका इंटरफ़ेस एक वास्तविकता बन जाएगा। अपने काम में मैं लगातार इस तथ्य पर आता हूं कि आधुनिक लोग वास्तव में एक साधारण कमांड लाइन को नहीं समझते और प्यार करते हैं। और उन सभी अधिक आलस्य को मैनुअल पढ़ने के लिए।
लेकिन मेरे व्यवहार में अक्सर ऐसा होता है कि आपको एक छोटी उपयोगिता की आवश्यकता होती है जो एक या दो कार्य करती है। और जहां इसे निष्पादित किया जाएगा वह अज्ञात है। यह विंडोज हो सकता है, यह विशेष रूप से टर्मिनल लिनक्स, बूट मीडिया - कुछ भी हो सकता है। मैं एक प्रोग्रामर नहीं हूं, लेकिन कभी-कभी खुद या दूसरों के लिए जीवन को आसान बनाना आवश्यक होता है। और अधिमानतः जितना संभव हो उतना स्पष्ट रूप से। सबसे पहले मैंने सिर्फ कंसोल उपयोगिताओं को बनाने की कोशिश की। वास्तव में, यह संभवतः वह जगह है जहां हर कोई शुरू करता है। लेकिन बहुत जल्दी यह पता चला कि प्रिंटफ / स्प्रिंट / पुट और अन्य (और मैं सी में लिखता हूं) का उपयोग करके पाठ को प्रारूपित करना, कुछ जानकारी प्रदर्शित करना बहुत सुविधाजनक नहीं है। निरंतर "स्क्रॉलिंग" वाली विंडो बहुत सुंदर नहीं लगती है, और यदि बहुत अधिक जानकारी है, तो यह पूरी तरह से अपठनीय है। फिर मुझे नर्सों के बारे में याद आया।


आमतौर पर, शाप / ncurses लिनक्स के साथ जुड़ा हुआ है, हालांकि वास्तव में कई प्लेटफार्मों के लिए संगत कार्यान्वयन हैं, विशेष रूप से विंडोज के लिए। प्रारंभ में, विन के तहत अधिकांश उपयोगिताओं की आवश्यकता थी, लेकिन मैं किसी भी चित्रमय रूपरेखा को नहीं जानता था और इसे सुंदर और स्पष्ट बनाने के लिए, पाठ को ठीक से प्रारूपित करने के तरीकों की सख्त खोज की थी। जब मैं पब्लिक डोमेन कर्स में आया था। Ncurses के साथ संगत होने के लिए डिज़ाइन किया गया, यह आपको मूल शाप / ncurses की अधिकांश विशेषताओं का उपयोग करके क्रॉस-प्लेटफ़ॉर्म एप्लिकेशन लिखने की अनुमति देता है। लेकिन, दुर्भाग्य से, यह बग और प्रतिबंध के बिना नहीं कर सकता। लेकिन यह उतना डरावना नहीं है जितना पहले लगता था। मैं बताना चाहता हूं कि कंसोल-फ्रेंडली छद्म-विंडो एप्लिकेशन बनाना इतना मुश्किल नहीं है; और आउटपुट में हमें एक गर्म ट्यूब टीयूआई मिलती है। मैं चाहता हूं कि लोग उपयोगकर्ता के साथ काम करने के ऐसे तरीकों को न भूलें।
इस पोस्ट में, मैं PDcurses के साथ संगत काम का वर्णन करूंगा, इसलिए इन उदाहरणों को विंडोज और लिनक्स दोनों पर समस्याओं के बिना बनाया जाना चाहिए।
शुरुआत

चूंकि हम एक पाठ इंटरफ़ेस के साथ काम करते हैं, इसलिए हमारे पास आयाम की इकाई के लिए एक चरित्र होगा। आप नियमित ASCII और वाइड अक्षरों दोनों के साथ काम कर सकते हैं। यह याद रखना चाहिए कि शाप केवल वही प्रदर्शित कर सकता है जो टर्मिनल का समर्थन करता है। दुर्भाग्य से, व्यक्तिगत रूप से मेरे पास 80% छद्म विज्ञान पर्याप्त रूप से प्रदर्शित नहीं हैं। लिनक्स पर थोड़ा बेहतर, विंडोज पर बहुत बुरा। सौभाग्य से, साधारण रेखाएँ सामान्य रूप से खींची जाती हैं।
हम विंडो, पैनल, रंग और पाठ (स्क्रॉलिंग, कॉपीिंग आदि सहित) के साथ काम कर सकते हैं।
काम शुरू करने से पहले, हमें काम के लिए तैयार करने की आवश्यकता है, (ओं) आवश्यक विकल्पों को चालू करें।

इस तरह मेरा सामान्य काम शुरू होता है।
initscr(); //  cbreak(); //     getch() raw(); nonl(); noecho(); //    ,      curs_set(0); //  keypad(stdscr, TRUE); //    (,     ) if (has_colors() == FALSE) //    ,      . { endwin(); puts("\nYour terminal does not support color"); return (1); } start_color(); //   use_default_colors(); // stscr  "" init_pair(1, COLOR_WHITE, COLOR_BLUE); //   (background-foreground)    ,    init_pair(2, COLOR_WHITE, COLOR_RED); ...... 



पहले एक खिड़की थी

जब हम टर्मिनल के एमुलेटर / इंस्टेंस को चलाते हैं, तो हम खुद को stdscr में पाते हैं। यह हमारा आधार है, प्रारंभिक खिड़की। हम इसमें काम कर सकते हैं, या अपनी खिड़कियां बना सकते हैं।
पर्याप्त शब्द, चलो व्यापार के लिए नीचे उतरो। एक विंडो बनाएँ। मैं एक महत्वपूर्ण बारीकियों को तुरंत नोटिस करना चाहता हूं - हर जगह, सभी कार्यों में, पहले वाई आता है, फिर एक्स

 WINDOW *win = newwin(height, width, y, x); 


प्रत्येक नई विंडो के अपने रिश्तेदार निर्देशांक होते हैं, जिन्हें आप भविष्य में संचालित करेंगे। यह महत्वपूर्ण और सुविधाजनक है।


एक विंडो बनाई गई थी, लेकिन कंसोल में कुछ भी दिखाई नहीं दिया। क्योंकि खिड़की को हमारे मामले में माता-पिता के गुण विरासत में मिले।
मैं तुम्हें दिखाता हूं कि मैं यह कैसे करता हूं। एक संरचना है जो "आभासी विंडो" का वर्णन करती है, मैं बाद में पैनलों के बारे में बात करूंगा
 struct cursed_window { WINDOW *background; WINDOW *decoration; WINDOW *overlay; PANEL *panel; }; typedef struct cursed_window curw; 

मैं ऐसा करने के लिए पहले एक डिज़ाइन बनाता हूं जो बदल नहीं जाएगा और जो स्थिर है। हम केवल कार्यशील डेटा को बदलते हैं, जबकि डिज़ाइन को ओवरराइट नहीं करते हैं।
खिड़की की पृष्ठभूमि - खिड़की से पारदर्शी पृष्ठभूमि और छाया।
सजावट - फ्रेम, यह स्वचालित रूप से तैयार की जाती है
ओवरले - वास्तव में, कार्य क्षेत्र। निर्देशांक की उत्पत्ति 0.0 होगी, क्योंकि यह एक नई विंडो है, फ्रेम और छाया में सुधार करने की कोई आवश्यकता नहीं है।
पैनल के बारे में - बाद में।

हमारी वर्चुअल विंडो बनाएं
 curw *tui_new_win(int sy, int sx, int h, int w, char *label) { curw *new = malloc (sizeof *new); new->background = newwin(h, w, sy, sx);//      wattron(new->background, COLOR_PAIR(7));// ,  .    //     for (int i= w*0.1; i<w;i++) mvwaddch(new->background, h-1, i, ' '); for (int i= h*0.2; i<h;i++) mvwaddch(new->background, i, w-1, ' '); wattroff(new->background, COLOR_PAIR(7)); //   ,      .    //   new->decoration = derwin(new->background, h-2, w-2, 1, 1); wbkgd(new->decoration, COLOR_PAIR(1)); //  box(new->decoration, 0, 0); int x, y; getmaxyx(new->decoration, y, x); new->overlay = derwin(new->decoration, y-4, x-2, 3, 1);//   wbkgd(new->overlay, COLOR_PAIR(1)); new->panel = new_panel(new->background); tui_win_label(new->decoration, label, 0); //       update_panels(); doupdate(); return new; } 





वास्तव में, यदि आप इसके ऊपर दूसरी विंडो बनाते हैं, तो हमारी पृष्ठभूमि निम्न विंडो पर "ज़ूम इन" होगी। यह बदसूरत है। लेकिन डिस्पोजेबल। लेकिन यह एक और चर्चा का विषय है। आइए सादगी के लिए छाया हटा दें और कुछ खिड़कियां बनाएं

लेकिन अब हम पैनल के बारे में कह सकते हैं। एक पैनल एक स्टैक कंटेनर है जिसमें एक खिड़की और उसके सभी बच्चे खिड़कियां हैं। पैनल के साथ, आप कई दिलचस्प जोड़तोड़ कर सकते हैं।
पैनलों

अब आप अभ्यास में पैनलों की क्षमताओं का प्रदर्शन कर सकते हैं। स्टैक में सबसे ऊपरी विंडो डिफ़ॉल्ट रूप से काम के लिए उपलब्ध है। हम नीचे दिए गए स्टैक में खिड़कियों को प्रभावित किए बिना, नीचे से स्टैक में किसी भी विंडो और पैनल तक भी पहुंच सकते हैं। हम स्वयं विंडो को सॉर्ट कर सकते हैं, स्थानांतरित कर सकते हैं, उनका आकार बदल सकते हैं। आदिम कोड के लिए क्षमा करें, लेकिन इसे और अधिक स्पष्ट रूप से करने की कोशिश की।

अंत में, मुख्य लूप बनाएं
  int x, y; getmaxyx(stdscr, y, x); curw *wins[3]; //   wins[0] = tui_new_win(0, 0, y - 5, x - 5, "-=Hello Habr=-", 1); wins[1] = tui_new_win(y / 3, x / 2, 15, 30, "-=Data=-", 4); wins[2] = tui_new_win(5, 5, 10, 20, "-=Memo=-", 5); PANEL *TOP = wins[0]->panel; int panel_counter = 0; do { switch ( user_key ) { case 0x9: //TAB if(++panel_counter > 2) { panel_counter=0; } TOP = wins[panel_counter]->panel; break; case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_RIGHT: tui_move_panel(wins[panel_counter], user_key); default: if(isalpha(user_key)) waddch(wins[panel_counter]->overlay, user_key); break; } //         top_panel(TOP); touchwin(panel_window(TOP)); update_panels( ); doupdate( ); } while (( user_key = getch( )) != KEY_F(12)); 



और यहाँ खिड़की चाल दिनचर्या है
 void tui_move_panel(curw *win, int ch) { int begy, begx, maxx, maxy, x, y; getbegyx(panel_window(win->panel), begy, begx); getmaxyx(panel_window(win->panel), maxy, maxx); getmaxyx(stdscr, y, x); switch (ch) { case KEY_UP: if ((begy - 1) >= 0) begy--; break; case KEY_DOWN: if (((begy + 1) + maxy) <= y) begy++; break; case KEY_LEFT: if ((begx - 1) >= 0) begx--; break; case KEY_RIGHT: if (((begx + 1) + maxx) <= x) begx++; break; } move_panel(win->panel, begy, begx); } 



और परिणामस्वरूप



अधिक वर्णन करने के लिए सोचा, लेकिन जाहिर है, यह बहुत बड़ा और उबाऊ पोस्ट होगा, मैं सिर्फ इस "प्राचीन तकनीक" पर ध्यान आकर्षित करना चाहता था, जिसमें पर्याप्त क्षमताएं हैं। पर्दे के पीछे विशेषताओं और अधिक के साथ पाठ के साथ जोड़तोड़ थे। उदाहरण के लिए, किसी भी विंडो से पाठ की एक पंक्ति की प्रतिलिपि बनाना संभव है, इसके रंग और मोड का पता लगाएं। और भी बहुत कुछ।
आशा है कि यह बहुत उबाऊ नहीं होगा।

Source: https://habr.com/ru/post/In205222/


All Articles